1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*6777b538SAndroid Build Coastguard Worker 3*6777b538SAndroid Build Coastguard Worker# Copyright 2016 The Chromium Authors 4*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Workerimport os 8*6777b538SAndroid Build Coastguard Workerimport os.path 9*6777b538SAndroid Build Coastguard Workerimport re 10*6777b538SAndroid Build Coastguard Workerimport shutil 11*6777b538SAndroid Build Coastguard Workerimport subprocess 12*6777b538SAndroid Build Coastguard Workerimport sys 13*6777b538SAndroid Build Coastguard Workerimport tempfile 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Worker# The path to `whole_archive`. 16*6777b538SAndroid Build Coastguard Workersys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Workerimport whole_archive 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker# Prefix for all custom linker driver arguments. 21*6777b538SAndroid Build Coastguard WorkerLINKER_DRIVER_ARG_PREFIX = '-Wcrl,' 22*6777b538SAndroid Build Coastguard WorkerLINKER_DRIVER_COMPILER_ARG_PREFIX = '-Wcrl,driver,' 23*6777b538SAndroid Build Coastguard Worker# Linker action to create a directory and pass it to the linker as 24*6777b538SAndroid Build Coastguard Worker# `-object_path_lto`. Special-cased since it has to run before the link. 25*6777b538SAndroid Build Coastguard WorkerOBJECT_PATH_LTO = 'object_path_lto' 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker# The linker_driver.py is responsible for forwarding a linker invocation to 28*6777b538SAndroid Build Coastguard Worker# the compiler driver, while processing special arguments itself. 29*6777b538SAndroid Build Coastguard Worker# 30*6777b538SAndroid Build Coastguard Worker# Usage: linker_driver.py -Wcrl,driver,clang++ main.o -L. -llib -o prog \ 31*6777b538SAndroid Build Coastguard Worker# -Wcrl,dsym,out 32*6777b538SAndroid Build Coastguard Worker# 33*6777b538SAndroid Build Coastguard Worker# On Mac, the logical step of linking is handled by three discrete tools to 34*6777b538SAndroid Build Coastguard Worker# perform the image link, debug info link, and strip. The linker_driver.py 35*6777b538SAndroid Build Coastguard Worker# combines these three steps into a single tool. 36*6777b538SAndroid Build Coastguard Worker# 37*6777b538SAndroid Build Coastguard Worker# The compiler driver invocation for the linker is specified by the following 38*6777b538SAndroid Build Coastguard Worker# required argument. 39*6777b538SAndroid Build Coastguard Worker# 40*6777b538SAndroid Build Coastguard Worker# -Wcrl,driver,<path_to_compiler_driver> 41*6777b538SAndroid Build Coastguard Worker# Specifies the path to the compiler driver. 42*6777b538SAndroid Build Coastguard Worker# 43*6777b538SAndroid Build Coastguard Worker# After running the compiler driver, the script performs additional actions, 44*6777b538SAndroid Build Coastguard Worker# based on these arguments: 45*6777b538SAndroid Build Coastguard Worker# 46*6777b538SAndroid Build Coastguard Worker# -Wcrl,installnametoolpath,<install_name_tool_path> 47*6777b538SAndroid Build Coastguard Worker# Sets the path to the `install_name_tool` to run with 48*6777b538SAndroid Build Coastguard Worker# -Wcrl,installnametool, in which case `xcrun` is not used to invoke it. 49*6777b538SAndroid Build Coastguard Worker# 50*6777b538SAndroid Build Coastguard Worker# -Wcrl,installnametool,<arguments,...> 51*6777b538SAndroid Build Coastguard Worker# After invoking the linker, this will run install_name_tool on the linker's 52*6777b538SAndroid Build Coastguard Worker# output. |arguments| are comma-separated arguments to be passed to the 53*6777b538SAndroid Build Coastguard Worker# install_name_tool command. 54*6777b538SAndroid Build Coastguard Worker# 55*6777b538SAndroid Build Coastguard Worker# -Wcrl,dsym,<dsym_path_prefix> 56*6777b538SAndroid Build Coastguard Worker# After invoking the linker, this will run `dsymutil` on the linker's 57*6777b538SAndroid Build Coastguard Worker# output, producing a dSYM bundle, stored at dsym_path_prefix. As an 58*6777b538SAndroid Build Coastguard Worker# example, if the linker driver were invoked with: 59*6777b538SAndroid Build Coastguard Worker# "... -o out/gn/obj/foo/libbar.dylib ... -Wcrl,dsym,out/gn ..." 60*6777b538SAndroid Build Coastguard Worker# The resulting dSYM would be out/gn/libbar.dylib.dSYM/. 61*6777b538SAndroid Build Coastguard Worker# 62*6777b538SAndroid Build Coastguard Worker# -Wcrl,dsymutilpath,<dsymutil_path> 63*6777b538SAndroid Build Coastguard Worker# Sets the path to the dsymutil to run with -Wcrl,dsym, in which case 64*6777b538SAndroid Build Coastguard Worker# `xcrun` is not used to invoke it. 65*6777b538SAndroid Build Coastguard Worker# 66*6777b538SAndroid Build Coastguard Worker# -Wcrl,unstripped,<unstripped_path_prefix> 67*6777b538SAndroid Build Coastguard Worker# After invoking the linker, and before strip, this will save a copy of 68*6777b538SAndroid Build Coastguard Worker# the unstripped linker output in the directory unstripped_path_prefix. 69*6777b538SAndroid Build Coastguard Worker# 70*6777b538SAndroid Build Coastguard Worker# -Wcrl,strip,<strip_arguments> 71*6777b538SAndroid Build Coastguard Worker# After invoking the linker, and optionally dsymutil, this will run 72*6777b538SAndroid Build Coastguard Worker# the strip command on the linker's output. strip_arguments are 73*6777b538SAndroid Build Coastguard Worker# comma-separated arguments to be passed to the strip command. 74*6777b538SAndroid Build Coastguard Worker# 75*6777b538SAndroid Build Coastguard Worker# -Wcrl,strippath,<strip_path> 76*6777b538SAndroid Build Coastguard Worker# Sets the path to the strip to run with -Wcrl,strip, in which case 77*6777b538SAndroid Build Coastguard Worker# `xcrun` is not used to invoke it. 78*6777b538SAndroid Build Coastguard Worker# -Wcrl,object_path_lto 79*6777b538SAndroid Build Coastguard Worker# Creates temporary directory for LTO object files. 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Workerclass LinkerDriver(object): 83*6777b538SAndroid Build Coastguard Worker def __init__(self, args): 84*6777b538SAndroid Build Coastguard Worker """Creates a new linker driver. 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard Worker Args: 87*6777b538SAndroid Build Coastguard Worker args: list of string, Arguments to the script. 88*6777b538SAndroid Build Coastguard Worker """ 89*6777b538SAndroid Build Coastguard Worker self._args = args 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard Worker # List of linker driver actions. **The sort order of this list affects 92*6777b538SAndroid Build Coastguard Worker # the order in which the actions are invoked.** 93*6777b538SAndroid Build Coastguard Worker # The first item in the tuple is the argument's -Wcrl,<sub_argument> 94*6777b538SAndroid Build Coastguard Worker # and the second is the function to invoke. 95*6777b538SAndroid Build Coastguard Worker self._actions = [ 96*6777b538SAndroid Build Coastguard Worker ('installnametoolpath,', self.set_install_name_tool_path), 97*6777b538SAndroid Build Coastguard Worker ('installnametool,', self.run_install_name_tool), 98*6777b538SAndroid Build Coastguard Worker ('dsymutilpath,', self.set_dsymutil_path), 99*6777b538SAndroid Build Coastguard Worker ('dsym,', self.run_dsymutil), 100*6777b538SAndroid Build Coastguard Worker ('unstripped,', self.run_save_unstripped), 101*6777b538SAndroid Build Coastguard Worker ('strippath,', self.set_strip_path), 102*6777b538SAndroid Build Coastguard Worker ('strip,', self.run_strip), 103*6777b538SAndroid Build Coastguard Worker ] 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker # Linker driver actions can modify the these values. 106*6777b538SAndroid Build Coastguard Worker self._driver_path = None # Must be specified on the command line. 107*6777b538SAndroid Build Coastguard Worker self._install_name_tool_cmd = ['xcrun', 'install_name_tool'] 108*6777b538SAndroid Build Coastguard Worker self._dsymutil_cmd = ['xcrun', 'dsymutil'] 109*6777b538SAndroid Build Coastguard Worker self._strip_cmd = ['xcrun', 'strip'] 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker # The linker output file, lazily computed in self._get_linker_output(). 112*6777b538SAndroid Build Coastguard Worker self._linker_output = None 113*6777b538SAndroid Build Coastguard Worker # The temporary directory for intermediate LTO object files. If it 114*6777b538SAndroid Build Coastguard Worker # exists, it will clean itself up on script exit. 115*6777b538SAndroid Build Coastguard Worker self._object_path_lto = None 116*6777b538SAndroid Build Coastguard Worker 117*6777b538SAndroid Build Coastguard Worker def run(self): 118*6777b538SAndroid Build Coastguard Worker """Runs the linker driver, separating out the main compiler driver's 119*6777b538SAndroid Build Coastguard Worker arguments from the ones handled by this class. It then invokes the 120*6777b538SAndroid Build Coastguard Worker required tools, starting with the compiler driver to produce the linker 121*6777b538SAndroid Build Coastguard Worker output. 122*6777b538SAndroid Build Coastguard Worker """ 123*6777b538SAndroid Build Coastguard Worker # Collect arguments to the linker driver (this script) and remove them 124*6777b538SAndroid Build Coastguard Worker # from the arguments being passed to the compiler driver. 125*6777b538SAndroid Build Coastguard Worker linker_driver_actions = {} 126*6777b538SAndroid Build Coastguard Worker compiler_driver_args = [] 127*6777b538SAndroid Build Coastguard Worker for index, arg in enumerate(self._args[1:]): 128*6777b538SAndroid Build Coastguard Worker if arg.startswith(LINKER_DRIVER_COMPILER_ARG_PREFIX): 129*6777b538SAndroid Build Coastguard Worker assert not self._driver_path 130*6777b538SAndroid Build Coastguard Worker self._driver_path = arg[len(LINKER_DRIVER_COMPILER_ARG_PREFIX 131*6777b538SAndroid Build Coastguard Worker ):] 132*6777b538SAndroid Build Coastguard Worker elif arg.startswith(LINKER_DRIVER_ARG_PREFIX): 133*6777b538SAndroid Build Coastguard Worker # Convert driver actions into a map of name => lambda to invoke. 134*6777b538SAndroid Build Coastguard Worker driver_action = self._process_driver_arg(arg) 135*6777b538SAndroid Build Coastguard Worker assert driver_action[0] not in linker_driver_actions 136*6777b538SAndroid Build Coastguard Worker linker_driver_actions[driver_action[0]] = driver_action[1] 137*6777b538SAndroid Build Coastguard Worker else: 138*6777b538SAndroid Build Coastguard Worker # TODO(crbug.com/1446796): On Apple, the linker command line 139*6777b538SAndroid Build Coastguard Worker # produced by rustc for LTO includes these arguments, but the 140*6777b538SAndroid Build Coastguard Worker # Apple linker doesn't accept them. 141*6777b538SAndroid Build Coastguard Worker # Upstream bug: https://github.com/rust-lang/rust/issues/60059 142*6777b538SAndroid Build Coastguard Worker BAD_RUSTC_ARGS = '-Wl,-plugin-opt=O[0-9],-plugin-opt=mcpu=.*' 143*6777b538SAndroid Build Coastguard Worker if not re.match(BAD_RUSTC_ARGS, arg): 144*6777b538SAndroid Build Coastguard Worker compiler_driver_args.append(arg) 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker if not self._driver_path: 147*6777b538SAndroid Build Coastguard Worker raise RuntimeError( 148*6777b538SAndroid Build Coastguard Worker "Usage: linker_driver.py -Wcrl,driver,<compiler-driver> " 149*6777b538SAndroid Build Coastguard Worker "[linker-args]...") 150*6777b538SAndroid Build Coastguard Worker 151*6777b538SAndroid Build Coastguard Worker if self._object_path_lto is not None: 152*6777b538SAndroid Build Coastguard Worker compiler_driver_args.append('-Wl,-object_path_lto,{}'.format( 153*6777b538SAndroid Build Coastguard Worker os.path.relpath(self._object_path_lto.name))) 154*6777b538SAndroid Build Coastguard Worker if self._get_linker_output() is None: 155*6777b538SAndroid Build Coastguard Worker raise ValueError( 156*6777b538SAndroid Build Coastguard Worker 'Could not find path to linker output (-o or --output)') 157*6777b538SAndroid Build Coastguard Worker 158*6777b538SAndroid Build Coastguard Worker # We want to link rlibs as --whole-archive if they are part of a unit 159*6777b538SAndroid Build Coastguard Worker # test target. This is determined by switch 160*6777b538SAndroid Build Coastguard Worker # `-LinkWrapper,add-whole-archive`. 161*6777b538SAndroid Build Coastguard Worker compiler_driver_args = whole_archive.wrap_with_whole_archive( 162*6777b538SAndroid Build Coastguard Worker compiler_driver_args, is_apple=True) 163*6777b538SAndroid Build Coastguard Worker 164*6777b538SAndroid Build Coastguard Worker linker_driver_outputs = [self._get_linker_output()] 165*6777b538SAndroid Build Coastguard Worker 166*6777b538SAndroid Build Coastguard Worker try: 167*6777b538SAndroid Build Coastguard Worker # Zero the mtime in OSO fields for deterministic builds. 168*6777b538SAndroid Build Coastguard Worker # https://crbug.com/330262. 169*6777b538SAndroid Build Coastguard Worker env = os.environ.copy() 170*6777b538SAndroid Build Coastguard Worker env['ZERO_AR_DATE'] = '1' 171*6777b538SAndroid Build Coastguard Worker # Run the linker by invoking the compiler driver. 172*6777b538SAndroid Build Coastguard Worker subprocess.check_call([self._driver_path] + compiler_driver_args, 173*6777b538SAndroid Build Coastguard Worker env=env) 174*6777b538SAndroid Build Coastguard Worker 175*6777b538SAndroid Build Coastguard Worker # Run the linker driver actions, in the order specified by the 176*6777b538SAndroid Build Coastguard Worker # actions list. 177*6777b538SAndroid Build Coastguard Worker for action in self._actions: 178*6777b538SAndroid Build Coastguard Worker name = action[0] 179*6777b538SAndroid Build Coastguard Worker if name in linker_driver_actions: 180*6777b538SAndroid Build Coastguard Worker linker_driver_outputs += linker_driver_actions[name]() 181*6777b538SAndroid Build Coastguard Worker except: 182*6777b538SAndroid Build Coastguard Worker # If a linker driver action failed, remove all the outputs to make 183*6777b538SAndroid Build Coastguard Worker # the build step atomic. 184*6777b538SAndroid Build Coastguard Worker map(_remove_path, linker_driver_outputs) 185*6777b538SAndroid Build Coastguard Worker 186*6777b538SAndroid Build Coastguard Worker # Re-report the original failure. 187*6777b538SAndroid Build Coastguard Worker raise 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker def _get_linker_output(self): 190*6777b538SAndroid Build Coastguard Worker """Returns the value of the output argument to the linker.""" 191*6777b538SAndroid Build Coastguard Worker if not self._linker_output: 192*6777b538SAndroid Build Coastguard Worker for index, arg in enumerate(self._args): 193*6777b538SAndroid Build Coastguard Worker if arg in ('-o', '-output', '--output'): 194*6777b538SAndroid Build Coastguard Worker self._linker_output = self._args[index + 1] 195*6777b538SAndroid Build Coastguard Worker break 196*6777b538SAndroid Build Coastguard Worker return self._linker_output 197*6777b538SAndroid Build Coastguard Worker 198*6777b538SAndroid Build Coastguard Worker def _process_driver_arg(self, arg): 199*6777b538SAndroid Build Coastguard Worker """Processes a linker driver argument and returns a tuple containing the 200*6777b538SAndroid Build Coastguard Worker name and unary lambda to invoke for that linker driver action. 201*6777b538SAndroid Build Coastguard Worker 202*6777b538SAndroid Build Coastguard Worker Args: 203*6777b538SAndroid Build Coastguard Worker arg: string, The linker driver argument. 204*6777b538SAndroid Build Coastguard Worker 205*6777b538SAndroid Build Coastguard Worker Returns: 206*6777b538SAndroid Build Coastguard Worker A 2-tuple: 207*6777b538SAndroid Build Coastguard Worker 0: The driver action name, as in |self._actions|. 208*6777b538SAndroid Build Coastguard Worker 1: A lambda that calls the linker driver action with its direct 209*6777b538SAndroid Build Coastguard Worker argument and returns a list of outputs from the action. 210*6777b538SAndroid Build Coastguard Worker """ 211*6777b538SAndroid Build Coastguard Worker if not arg.startswith(LINKER_DRIVER_ARG_PREFIX): 212*6777b538SAndroid Build Coastguard Worker raise ValueError('%s is not a linker driver argument' % (arg, )) 213*6777b538SAndroid Build Coastguard Worker 214*6777b538SAndroid Build Coastguard Worker sub_arg = arg[len(LINKER_DRIVER_ARG_PREFIX):] 215*6777b538SAndroid Build Coastguard Worker # Special-cased, since it needs to run before the link. 216*6777b538SAndroid Build Coastguard Worker # TODO(lgrey): Remove if/when we start running `dsymutil` 217*6777b538SAndroid Build Coastguard Worker # through the clang driver. See https://crbug.com/1324104 218*6777b538SAndroid Build Coastguard Worker if sub_arg == OBJECT_PATH_LTO: 219*6777b538SAndroid Build Coastguard Worker self._object_path_lto = tempfile.TemporaryDirectory( 220*6777b538SAndroid Build Coastguard Worker dir=os.getcwd()) 221*6777b538SAndroid Build Coastguard Worker return (OBJECT_PATH_LTO, lambda: []) 222*6777b538SAndroid Build Coastguard Worker 223*6777b538SAndroid Build Coastguard Worker for driver_action in self._actions: 224*6777b538SAndroid Build Coastguard Worker (name, action) = driver_action 225*6777b538SAndroid Build Coastguard Worker if sub_arg.startswith(name): 226*6777b538SAndroid Build Coastguard Worker return (name, lambda: action(sub_arg[len(name):])) 227*6777b538SAndroid Build Coastguard Worker 228*6777b538SAndroid Build Coastguard Worker raise ValueError('Unknown linker driver argument: %s' % (arg, )) 229*6777b538SAndroid Build Coastguard Worker 230*6777b538SAndroid Build Coastguard Worker def set_install_name_tool_path(self, install_name_tool_path): 231*6777b538SAndroid Build Coastguard Worker """Linker driver action for -Wcrl,installnametoolpath,<path>. 232*6777b538SAndroid Build Coastguard Worker 233*6777b538SAndroid Build Coastguard Worker Sets the invocation command for install_name_tool, which allows the 234*6777b538SAndroid Build Coastguard Worker caller to specify an alternate path. This action is always 235*6777b538SAndroid Build Coastguard Worker processed before the run_install_name_tool action. 236*6777b538SAndroid Build Coastguard Worker 237*6777b538SAndroid Build Coastguard Worker Args: 238*6777b538SAndroid Build Coastguard Worker install_name_tool_path: string, The path to the install_name_tool 239*6777b538SAndroid Build Coastguard Worker binary to run 240*6777b538SAndroid Build Coastguard Worker 241*6777b538SAndroid Build Coastguard Worker Returns: 242*6777b538SAndroid Build Coastguard Worker No output - this step is run purely for its side-effect. 243*6777b538SAndroid Build Coastguard Worker """ 244*6777b538SAndroid Build Coastguard Worker self._install_name_tool_cmd = [install_name_tool_path] 245*6777b538SAndroid Build Coastguard Worker return [] 246*6777b538SAndroid Build Coastguard Worker 247*6777b538SAndroid Build Coastguard Worker def run_install_name_tool(self, args_string): 248*6777b538SAndroid Build Coastguard Worker """Linker driver action for -Wcrl,installnametool,<args>. Invokes 249*6777b538SAndroid Build Coastguard Worker install_name_tool on the linker's output. 250*6777b538SAndroid Build Coastguard Worker 251*6777b538SAndroid Build Coastguard Worker Args: 252*6777b538SAndroid Build Coastguard Worker args_string: string, Comma-separated arguments for 253*6777b538SAndroid Build Coastguard Worker `install_name_tool`. 254*6777b538SAndroid Build Coastguard Worker 255*6777b538SAndroid Build Coastguard Worker Returns: 256*6777b538SAndroid Build Coastguard Worker No output - this step is run purely for its side-effect. 257*6777b538SAndroid Build Coastguard Worker """ 258*6777b538SAndroid Build Coastguard Worker command = list(self._install_name_tool_cmd) 259*6777b538SAndroid Build Coastguard Worker command.extend(args_string.split(',')) 260*6777b538SAndroid Build Coastguard Worker command.append(self._get_linker_output()) 261*6777b538SAndroid Build Coastguard Worker subprocess.check_call(command) 262*6777b538SAndroid Build Coastguard Worker return [] 263*6777b538SAndroid Build Coastguard Worker 264*6777b538SAndroid Build Coastguard Worker def run_dsymutil(self, dsym_path_prefix): 265*6777b538SAndroid Build Coastguard Worker """Linker driver action for -Wcrl,dsym,<dsym-path-prefix>. Invokes 266*6777b538SAndroid Build Coastguard Worker dsymutil on the linker's output and produces a dsym file at |dsym_file| 267*6777b538SAndroid Build Coastguard Worker path. 268*6777b538SAndroid Build Coastguard Worker 269*6777b538SAndroid Build Coastguard Worker Args: 270*6777b538SAndroid Build Coastguard Worker dsym_path_prefix: string, The path at which the dsymutil output 271*6777b538SAndroid Build Coastguard Worker should be located. 272*6777b538SAndroid Build Coastguard Worker 273*6777b538SAndroid Build Coastguard Worker Returns: 274*6777b538SAndroid Build Coastguard Worker list of string, Build step outputs. 275*6777b538SAndroid Build Coastguard Worker """ 276*6777b538SAndroid Build Coastguard Worker if not len(dsym_path_prefix): 277*6777b538SAndroid Build Coastguard Worker raise ValueError('Unspecified dSYM output file') 278*6777b538SAndroid Build Coastguard Worker 279*6777b538SAndroid Build Coastguard Worker linker_output = self._get_linker_output() 280*6777b538SAndroid Build Coastguard Worker base = os.path.basename(linker_output) 281*6777b538SAndroid Build Coastguard Worker dsym_out = os.path.join(dsym_path_prefix, base + '.dSYM') 282*6777b538SAndroid Build Coastguard Worker 283*6777b538SAndroid Build Coastguard Worker # Remove old dSYMs before invoking dsymutil. 284*6777b538SAndroid Build Coastguard Worker _remove_path(dsym_out) 285*6777b538SAndroid Build Coastguard Worker 286*6777b538SAndroid Build Coastguard Worker tools_paths = _find_tools_paths(self._args) 287*6777b538SAndroid Build Coastguard Worker if os.environ.get('PATH'): 288*6777b538SAndroid Build Coastguard Worker tools_paths.append(os.environ['PATH']) 289*6777b538SAndroid Build Coastguard Worker dsymutil_env = os.environ.copy() 290*6777b538SAndroid Build Coastguard Worker dsymutil_env['PATH'] = ':'.join(tools_paths) 291*6777b538SAndroid Build Coastguard Worker subprocess.check_call(self._dsymutil_cmd + 292*6777b538SAndroid Build Coastguard Worker ['-o', dsym_out, linker_output], 293*6777b538SAndroid Build Coastguard Worker env=dsymutil_env) 294*6777b538SAndroid Build Coastguard Worker return [dsym_out] 295*6777b538SAndroid Build Coastguard Worker 296*6777b538SAndroid Build Coastguard Worker def set_dsymutil_path(self, dsymutil_path): 297*6777b538SAndroid Build Coastguard Worker """Linker driver action for -Wcrl,dsymutilpath,<dsymutil_path>. 298*6777b538SAndroid Build Coastguard Worker 299*6777b538SAndroid Build Coastguard Worker Sets the invocation command for dsymutil, which allows the caller to 300*6777b538SAndroid Build Coastguard Worker specify an alternate dsymutil. This action is always processed before 301*6777b538SAndroid Build Coastguard Worker the RunDsymUtil action. 302*6777b538SAndroid Build Coastguard Worker 303*6777b538SAndroid Build Coastguard Worker Args: 304*6777b538SAndroid Build Coastguard Worker dsymutil_path: string, The path to the dsymutil binary to run 305*6777b538SAndroid Build Coastguard Worker 306*6777b538SAndroid Build Coastguard Worker Returns: 307*6777b538SAndroid Build Coastguard Worker No output - this step is run purely for its side-effect. 308*6777b538SAndroid Build Coastguard Worker """ 309*6777b538SAndroid Build Coastguard Worker self._dsymutil_cmd = [dsymutil_path] 310*6777b538SAndroid Build Coastguard Worker return [] 311*6777b538SAndroid Build Coastguard Worker 312*6777b538SAndroid Build Coastguard Worker def run_save_unstripped(self, unstripped_path_prefix): 313*6777b538SAndroid Build Coastguard Worker """Linker driver action for -Wcrl,unstripped,<unstripped_path_prefix>. 314*6777b538SAndroid Build Coastguard Worker Copies the linker output to |unstripped_path_prefix| before stripping. 315*6777b538SAndroid Build Coastguard Worker 316*6777b538SAndroid Build Coastguard Worker Args: 317*6777b538SAndroid Build Coastguard Worker unstripped_path_prefix: string, The path at which the unstripped 318*6777b538SAndroid Build Coastguard Worker output should be located. 319*6777b538SAndroid Build Coastguard Worker 320*6777b538SAndroid Build Coastguard Worker Returns: 321*6777b538SAndroid Build Coastguard Worker list of string, Build step outputs. 322*6777b538SAndroid Build Coastguard Worker """ 323*6777b538SAndroid Build Coastguard Worker if not len(unstripped_path_prefix): 324*6777b538SAndroid Build Coastguard Worker raise ValueError('Unspecified unstripped output file') 325*6777b538SAndroid Build Coastguard Worker 326*6777b538SAndroid Build Coastguard Worker base = os.path.basename(self._get_linker_output()) 327*6777b538SAndroid Build Coastguard Worker unstripped_out = os.path.join(unstripped_path_prefix, 328*6777b538SAndroid Build Coastguard Worker base + '.unstripped') 329*6777b538SAndroid Build Coastguard Worker 330*6777b538SAndroid Build Coastguard Worker shutil.copyfile(self._get_linker_output(), unstripped_out) 331*6777b538SAndroid Build Coastguard Worker return [unstripped_out] 332*6777b538SAndroid Build Coastguard Worker 333*6777b538SAndroid Build Coastguard Worker def run_strip(self, strip_args_string): 334*6777b538SAndroid Build Coastguard Worker """Linker driver action for -Wcrl,strip,<strip_arguments>. 335*6777b538SAndroid Build Coastguard Worker 336*6777b538SAndroid Build Coastguard Worker Args: 337*6777b538SAndroid Build Coastguard Worker strip_args_string: string, Comma-separated arguments for `strip`. 338*6777b538SAndroid Build Coastguard Worker 339*6777b538SAndroid Build Coastguard Worker Returns: 340*6777b538SAndroid Build Coastguard Worker list of string, Build step outputs. 341*6777b538SAndroid Build Coastguard Worker """ 342*6777b538SAndroid Build Coastguard Worker strip_command = list(self._strip_cmd) 343*6777b538SAndroid Build Coastguard Worker if len(strip_args_string) > 0: 344*6777b538SAndroid Build Coastguard Worker strip_command += strip_args_string.split(',') 345*6777b538SAndroid Build Coastguard Worker strip_command.append(self._get_linker_output()) 346*6777b538SAndroid Build Coastguard Worker subprocess.check_call(strip_command) 347*6777b538SAndroid Build Coastguard Worker return [] 348*6777b538SAndroid Build Coastguard Worker 349*6777b538SAndroid Build Coastguard Worker def set_strip_path(self, strip_path): 350*6777b538SAndroid Build Coastguard Worker """Linker driver action for -Wcrl,strippath,<strip_path>. 351*6777b538SAndroid Build Coastguard Worker 352*6777b538SAndroid Build Coastguard Worker Sets the invocation command for strip, which allows the caller to 353*6777b538SAndroid Build Coastguard Worker specify an alternate strip. This action is always processed before the 354*6777b538SAndroid Build Coastguard Worker RunStrip action. 355*6777b538SAndroid Build Coastguard Worker 356*6777b538SAndroid Build Coastguard Worker Args: 357*6777b538SAndroid Build Coastguard Worker strip_path: string, The path to the strip binary to run 358*6777b538SAndroid Build Coastguard Worker 359*6777b538SAndroid Build Coastguard Worker Returns: 360*6777b538SAndroid Build Coastguard Worker No output - this step is run purely for its side-effect. 361*6777b538SAndroid Build Coastguard Worker """ 362*6777b538SAndroid Build Coastguard Worker self._strip_cmd = [strip_path] 363*6777b538SAndroid Build Coastguard Worker return [] 364*6777b538SAndroid Build Coastguard Worker 365*6777b538SAndroid Build Coastguard Worker 366*6777b538SAndroid Build Coastguard Workerdef _find_tools_paths(full_args): 367*6777b538SAndroid Build Coastguard Worker """Finds all paths where the script should look for additional tools.""" 368*6777b538SAndroid Build Coastguard Worker paths = [] 369*6777b538SAndroid Build Coastguard Worker for idx, arg in enumerate(full_args): 370*6777b538SAndroid Build Coastguard Worker if arg in ['-B', '--prefix']: 371*6777b538SAndroid Build Coastguard Worker paths.append(full_args[idx + 1]) 372*6777b538SAndroid Build Coastguard Worker elif arg.startswith('-B'): 373*6777b538SAndroid Build Coastguard Worker paths.append(arg[2:]) 374*6777b538SAndroid Build Coastguard Worker elif arg.startswith('--prefix='): 375*6777b538SAndroid Build Coastguard Worker paths.append(arg[9:]) 376*6777b538SAndroid Build Coastguard Worker return paths 377*6777b538SAndroid Build Coastguard Worker 378*6777b538SAndroid Build Coastguard Worker 379*6777b538SAndroid Build Coastguard Workerdef _remove_path(path): 380*6777b538SAndroid Build Coastguard Worker """Removes the file or directory at |path| if it exists.""" 381*6777b538SAndroid Build Coastguard Worker if os.path.exists(path): 382*6777b538SAndroid Build Coastguard Worker if os.path.isdir(path): 383*6777b538SAndroid Build Coastguard Worker shutil.rmtree(path) 384*6777b538SAndroid Build Coastguard Worker else: 385*6777b538SAndroid Build Coastguard Worker os.unlink(path) 386*6777b538SAndroid Build Coastguard Worker 387*6777b538SAndroid Build Coastguard Worker 388*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__': 389*6777b538SAndroid Build Coastguard Worker LinkerDriver(sys.argv).run() 390*6777b538SAndroid Build Coastguard Worker sys.exit(0) 391