Home | History | Annotate | Download | only in toolchain
      1 #!/usr/bin/env python
      2 # Copyright 2015 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 """Runs a linking command and optionally a strip command.
      7 
      8 This script exists to avoid using complex shell commands in
      9 gcc_toolchain.gni's tool("link"), in case the host running the compiler
     10 does not have a POSIX-like shell (e.g. Windows).
     11 """
     12 
     13 import argparse
     14 import subprocess
     15 import sys
     16 
     17 
     18 # When running on a Windows host and using a toolchain whose tools are
     19 # actually wrapper scripts (i.e. .bat files on Windows) rather than binary
     20 # executables, the "command" to run has to be prefixed with this magic.
     21 # The GN toolchain definitions take care of that for when GN/Ninja is
     22 # running the tool directly.  When that command is passed in to this
     23 # script, it appears as a unitary string but needs to be split up so that
     24 # just 'cmd' is the actual command given to Python's subprocess module.
     25 BAT_PREFIX = 'cmd /c call '
     26 
     27 def CommandToRun(command):
     28   if command[0].startswith(BAT_PREFIX):
     29     command = command[0].split(None, 3) + command[1:]
     30   return command
     31 
     32 
     33 def main():
     34   parser = argparse.ArgumentParser(description=__doc__)
     35   parser.add_argument('--strip',
     36                       help='The strip binary to run',
     37                       metavar='PATH')
     38   parser.add_argument('--unstripped-file',
     39                       required=True,
     40                       help='Executable file produced by linking command',
     41                       metavar='FILE')
     42   parser.add_argument('--output',
     43                       required=True,
     44                       help='Final output executable file',
     45                       metavar='FILE')
     46   parser.add_argument('command', nargs='+',
     47                       help='Linking command')
     48   args = parser.parse_args()
     49 
     50   # First, run the actual link.
     51   result = subprocess.call(CommandToRun(args.command))
     52   if result != 0:
     53     return result
     54 
     55   # Finally, strip the linked executable (if desired).
     56   if args.strip:
     57     result = subprocess.call(CommandToRun([
     58         args.strip, '--strip-unneeded', '-o', args.output, args.unstripped_file
     59         ]))
     60 
     61   return result
     62 
     63 
     64 if __name__ == "__main__":
     65   sys.exit(main())
     66