1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""A wrapper to run yasm.
6
7Its main job is to provide a Python wrapper for GN integration, and to write
8the makefile-style output yasm generates in stdout to a .d file for dependency
9management of .inc files.
10
11Run with:
12  python run_yasm.py <yasm_binary_path> <all other yasm args>
13
14Note that <all other yasm args> must include an explicit output file (-o). This
15script will append a ".d" to this and write the dependencies there. This script
16will add "-M" to cause yasm to write the deps to stdout, so you don't need to
17specify that.
18"""
19
20import argparse
21import os
22import sys
23import subprocess
24
25# Extract the output file name from the yasm command line so we can generate a
26# .d file with the same base name.
27parser = argparse.ArgumentParser()
28parser.add_argument("-o", dest="objfile")
29options, _ = parser.parse_known_args()
30
31objfile = options.objfile
32depfile = objfile + '.d'
33
34# Set up environment for yasm.
35# Setting YASM_TEST_SUITE makes yasm output deterministic:
36# - the PE/COFF timestamp field is always 0 (this breaks link.exe /incremental,
37#   but we no longer user link.exe)
38# - in debug info, yasm identifies itself as "yasm HEAD" instead of e.g.
39#   "yasm 1.3.0" (we don't care much about this effect)
40# - in debug info, file paths are no longer absolute but relative to '.'
41os.environ['YASM_TEST_SUITE'] = '1'
42
43# Assemble.
44result_code = subprocess.call(sys.argv[1:])
45if result_code != 0:
46  sys.exit(result_code)
47
48# Now generate the .d file listing the dependencies. The -M option makes yasm
49# write the Makefile-style dependencies to stdout, but it seems that inhibits
50# generating any compiled output so we need to do this in a separate pass.
51# However, outputting deps seems faster than actually assembling, and yasm is
52# so fast anyway this is not a big deal.
53#
54# This guarantees proper dependency management for assembly files. Otherwise,
55# we would have to require people to manually specify the .inc files they
56# depend on in the build file, which will surely be wrong or out-of-date in
57# some cases.
58deps = subprocess.check_output(sys.argv[1:] + ['-M'])
59with open(depfile, "wb") as f:
60  f.write(deps)
61
62