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