xref: /aosp_15_r20/external/angle/build/toolchain/gcc_link_wrapper.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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