Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: build/toolchain/mac/linker_driver.py

Issue 1999513002: [Mac/GN] Implement dSYM generation and stripping. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2
3 # Copyright 2016 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 import os
8 import os.path
9 import subprocess
10 import sys
11
12 # The linker_driver.py is responsible for forwarding a linker invocation to
13 # the compiler driver, while processing special arguments itself.
14 #
15 # On Mac, the logical step of linking is handled by three discrete tools to
16 # perform the image link, debug info link, and strip. The linker_driver.py
17 # combines these three steps into a single tool.
Mark Mentovai 2016/05/20 15:42:41 Ask Nico whether there’s any chance of adding thes
Robert Sesek 2016/05/20 19:09:55 Acknowledged. Per offline chat, clang, when drivin
18 #
19 # The invocation of the linker_driver.py is first passed unaltered, except for
20 # the removal of the special driver arguments, described below. The driver
21 # arguments control what other steps occur after the image link.
22 #
23 # -Wcrl,dsym,<dsym_path_prefix>
24 # After invoking the linker, this will run `dsymutil` on the linker's
25 # output, producing a dSYM bundle, stored at dsym_path_prefix.
Mark Mentovai 2016/05/20 15:42:41 dsym_path_prefix is a directory, and the name + .d
Robert Sesek 2016/05/20 19:09:55 Done.
26 #
27 # -Wcrl,strip,<strip_arguments>
28 # After invoking the linker, and optionally dsymutil, this will run
29 # the strip command on the linker's output. strip_arguments are
30 # comma-separated arguments to be passed to the strip command.
31
32 _LINKER_DRIVER_ARG_PREFIX = '-Wcrl,'
33
34 def Main(args):
35 """Main function for the linker driver. Separates out the arguments for
36 the main compiler driver and the linker driver, then invokes all the
37 required tools.
38
39 Args:
40 args: list of string, Arguments to the script.
41 """
42
43 if len(args) < 2:
44 raise RuntimeError("Usage: linker_driver.py [linker-invocation]")
45
46 # Collect arguments to the linker driver (this script) and remove them from
47 # the arguments being passed to the compiler driver.
48 linker_driver_actions = {}
49 compiler_driver_args = []
50 for arg in args[1:]:
51 if arg.startswith(_LINKER_DRIVER_ARG_PREFIX):
52 # Convert driver actions into a map of name => lambda to invoke.
53 driver_action = ProcessLinkerDriverArg(arg)
54 linker_driver_actions[driver_action[0]] = driver_action[1]
55 else:
56 compiler_driver_args.append(arg)
57
58 # Run the linker by invoking the compiler driver.
59 subprocess.check_call(compiler_driver_args)
60
61 # Run the linker driver actions, in the order specified by the actions list.
62 for action in _LINKER_DRIVER_ACTIONS:
Dirk Pranke 2016/05/20 01:47:19 this should probably be wrapped in a try: ... fina
Robert Sesek 2016/05/20 15:15:36 Done.
63 name = action[0]
64 if name in linker_driver_actions:
65 linker_driver_actions[name](args)
66
67
68 def ProcessLinkerDriverArg(arg):
69 """Processes a linker driver argument and returns a tuple containing the
70 name and unary lambda to invoke for that linker driver action.
71
72 Args:
73 arg: string, The linker driver argument.
74
75 Returns:
76 A 2-tuple:
77 0: The driver action name, as in _LINKER_DRIVER_ACTIONS.
78 1: An 1-ary lambda that takes the full list of arguments passed to
79 Main(). The lambda should call the linker driver action that
80 corresponds to the argument.
81 """
82 if not arg.startswith(_LINKER_DRIVER_ARG_PREFIX):
83 raise ValueError('%s is not a linker driver argument' % (arg,))
84
85 sub_arg = arg[len(_LINKER_DRIVER_ARG_PREFIX):]
86
87 for driver_action in _LINKER_DRIVER_ACTIONS:
88 (name, action) = driver_action
89 if sub_arg.startswith(name):
90 return (name,
91 lambda full_args: action(sub_arg[len(name):], full_args))
92
93 raise ValueError('Unknown linker driver argument: %s' % (arg,))
94
95
96 def RunDsymUtil(dsym_path_prefix, full_args):
97 """Linker driver action for -Wcrl,dsym,<dsym-path-prefix>. Invokes dsymutil
98 on the linker's output and produces a dsym file at |dsym_file| path.
99
100 Args:
101 dsym_path_prefix: string, The path at which the dsymutil output should be
102 located.
103 full_args: list of string, Full argument list for the linker driver.
104 """
105 if not len(dsym_path_prefix):
106 raise ValueError('Unspecified dSYM output file')
107
108 linker_out = _FindLinkerOutput(full_args)
109 (head, tail) = os.path.split(linker_out)
110 dsym_out = os.path.join(dsym_path_prefix, tail + '.dSYM')
Mark Mentovai 2016/05/20 15:42:41 Does dsymutil trash the .dSYM before writing a new
Robert Sesek 2016/05/20 19:09:55 It "kind of" does. If you put extra things in the
111 subprocess.check_call(['xcrun', 'dsymutil', '-o', dsym_out, linker_out])
Mark Mentovai 2016/05/20 15:42:42 If (this or) a later step fails, the .dSYM that yo
Robert Sesek 2016/05/20 19:09:55 Yeah, this was on my mind when writing it. At the
112
113
114 def RunStrip(strip_args_string, full_args):
Mark Mentovai 2016/05/20 15:42:41 We may at some point want an option to save the or
Robert Sesek 2016/05/20 19:09:55 Acknowledged.
115 """Linker driver action for -Wcrl,strip,<strip_arguments>.
116
117 Args:
118 strip_args_string: string, Comma-separated arguments for `strip`.
119 full_args: list of string, Full arguments for the linker driver.
120 """
121 strip_args_list = strip_args_string.split(',')
122 strip_command = ['xcrun', 'strip'] + strip_args_list
123 strip_command.append(_FindLinkerOutput(full_args))
124 subprocess.check_call(strip_command)
125
126
127 def _FindLinkerOutput(full_args):
128 """Finds the output of the linker by looking for the output flag in its
129 argument list. As this is a required linker argument, raises an error if it
130 cannot be found.
131 """
132 for (i, arg) in enumerate(full_args):
133 if arg == '-o':
134 return full_args[i+1]
135 raise RuntimeError('Unable to locate linker output file')
136
137
138 """List of linker driver actions. The sort order of this list affects the
139 order in which the actions are invoked. The first item in the tuple is the
140 argument's -Wcrl,<sub_argument> and the second is the function to invoke.
141 """
142 _LINKER_DRIVER_ACTIONS = [
Mark Mentovai 2016/05/20 15:42:41 Can you move this up so that it’s after _LINKER_DR
Robert Sesek 2016/05/20 19:09:55 No because they reference functions declared later
143 ('dsym,', RunDsymUtil),
144 ('strip,', RunStrip),
145 ]
146
147
148 if __name__ == '__main__':
149 Main(sys.argv)
150 sys.exit(0)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698