1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*6777b538SAndroid Build Coastguard Worker# Copyright 2015 The Chromium Authors 3*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 5*6777b538SAndroid Build Coastguard Worker 6*6777b538SAndroid Build Coastguard Worker"""Runs a linking command and optionally a strip command. 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard WorkerThis script exists to avoid using complex shell commands in 9*6777b538SAndroid Build Coastguard Workergcc_toolchain.gni's tool("link"), in case the host running the compiler 10*6777b538SAndroid Build Coastguard Workerdoes not have a POSIX-like shell (e.g. Windows). 11*6777b538SAndroid Build Coastguard Worker""" 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Workerimport argparse 14*6777b538SAndroid Build Coastguard Workerimport os 15*6777b538SAndroid Build Coastguard Workerimport subprocess 16*6777b538SAndroid Build Coastguard Workerimport sys 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Workerimport wrapper_utils 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker# When running on a Windows host and using a toolchain whose tools are 22*6777b538SAndroid Build Coastguard Worker# actually wrapper scripts (i.e. .bat files on Windows) rather than binary 23*6777b538SAndroid Build Coastguard Worker# executables, the "command" to run has to be prefixed with this magic. 24*6777b538SAndroid Build Coastguard Worker# The GN toolchain definitions take care of that for when GN/Ninja is 25*6777b538SAndroid Build Coastguard Worker# running the tool directly. When that command is passed in to this 26*6777b538SAndroid Build Coastguard Worker# script, it appears as a unitary string but needs to be split up so that 27*6777b538SAndroid Build Coastguard Worker# just 'cmd' is the actual command given to Python's subprocess module. 28*6777b538SAndroid Build Coastguard WorkerBAT_PREFIX = 'cmd /c call ' 29*6777b538SAndroid Build Coastguard Worker 30*6777b538SAndroid Build Coastguard Workerdef CommandToRun(command): 31*6777b538SAndroid Build Coastguard Worker if command[0].startswith(BAT_PREFIX): 32*6777b538SAndroid Build Coastguard Worker command = command[0].split(None, 3) + command[1:] 33*6777b538SAndroid Build Coastguard Worker return command 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard Workerdef main(): 37*6777b538SAndroid Build Coastguard Worker parser = argparse.ArgumentParser(description=__doc__) 38*6777b538SAndroid Build Coastguard Worker parser.add_argument('--strip', 39*6777b538SAndroid Build Coastguard Worker help='The strip binary to run', 40*6777b538SAndroid Build Coastguard Worker metavar='PATH') 41*6777b538SAndroid Build Coastguard Worker parser.add_argument('--unstripped-file', 42*6777b538SAndroid Build Coastguard Worker help='Executable file produced by linking command', 43*6777b538SAndroid Build Coastguard Worker metavar='FILE') 44*6777b538SAndroid Build Coastguard Worker parser.add_argument('--map-file', 45*6777b538SAndroid Build Coastguard Worker help=('Use --Wl,-Map to generate a map file. Will be ' 46*6777b538SAndroid Build Coastguard Worker 'gzipped if extension ends with .gz'), 47*6777b538SAndroid Build Coastguard Worker metavar='FILE') 48*6777b538SAndroid Build Coastguard Worker parser.add_argument('--dwp', help=('The dwp binary to run'), metavar='FILE') 49*6777b538SAndroid Build Coastguard Worker parser.add_argument('--output', 50*6777b538SAndroid Build Coastguard Worker required=True, 51*6777b538SAndroid Build Coastguard Worker help='Final output executable file', 52*6777b538SAndroid Build Coastguard Worker metavar='FILE') 53*6777b538SAndroid Build Coastguard Worker parser.add_argument('command', nargs='+', 54*6777b538SAndroid Build Coastguard Worker help='Linking command') 55*6777b538SAndroid Build Coastguard Worker args = parser.parse_args() 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker # Work-around for gold being slow-by-default. http://crbug.com/632230 58*6777b538SAndroid Build Coastguard Worker fast_env = dict(os.environ) 59*6777b538SAndroid Build Coastguard Worker fast_env['LC_ALL'] = 'C' 60*6777b538SAndroid Build Coastguard Worker result = wrapper_utils.RunLinkWithOptionalMapFile(args.command, env=fast_env, 61*6777b538SAndroid Build Coastguard Worker map_file=args.map_file) 62*6777b538SAndroid Build Coastguard Worker if result != 0: 63*6777b538SAndroid Build Coastguard Worker return result 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker # If dwp is set, then package debug info for this exe. 66*6777b538SAndroid Build Coastguard Worker dwp_proc = None 67*6777b538SAndroid Build Coastguard Worker if args.dwp: 68*6777b538SAndroid Build Coastguard Worker exe_file = args.output 69*6777b538SAndroid Build Coastguard Worker if args.unstripped_file: 70*6777b538SAndroid Build Coastguard Worker exe_file = args.unstripped_file 71*6777b538SAndroid Build Coastguard Worker # Suppress warnings about duplicate CU entries (https://crbug.com/1264130) 72*6777b538SAndroid Build Coastguard Worker dwp_proc = subprocess.Popen(wrapper_utils.CommandToRun( 73*6777b538SAndroid Build Coastguard Worker [args.dwp, '-e', exe_file, '-o', exe_file + '.dwp']), 74*6777b538SAndroid Build Coastguard Worker stderr=subprocess.DEVNULL) 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker # Finally, strip the linked executable (if desired). 77*6777b538SAndroid Build Coastguard Worker if args.strip: 78*6777b538SAndroid Build Coastguard Worker result = subprocess.call( 79*6777b538SAndroid Build Coastguard Worker CommandToRun([args.strip, '-o', args.output, args.unstripped_file])) 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker if dwp_proc: 82*6777b538SAndroid Build Coastguard Worker dwp_result = dwp_proc.wait() 83*6777b538SAndroid Build Coastguard Worker if dwp_result != 0: 84*6777b538SAndroid Build Coastguard Worker sys.stderr.write('dwp failed with error code {}\n'.format(dwp_result)) 85*6777b538SAndroid Build Coastguard Worker return dwp_result 86*6777b538SAndroid Build Coastguard Worker 87*6777b538SAndroid Build Coastguard Worker return result 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Workerif __name__ == "__main__": 91*6777b538SAndroid Build Coastguard Worker sys.exit(main()) 92