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