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

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
« no previous file with comments | « build/toolchain/mac/BUILD.gn ('k') | chrome/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
18 #
19 # The command passed to the linker_driver.py is first invoked unaltered (except
20 # for the removal of the special driver arguments, described below). Then the
21 # driver performs additional actions, based on these arguments:
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.
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 try:
Mark Mentovai 2016/05/20 15:42:42 I’d move the try up to include the call of the com
Robert Sesek 2016/05/20 19:09:55 Done.
63 for action in _LINKER_DRIVER_ACTIONS:
64 name = action[0]
65 if name in linker_driver_actions:
66 linker_driver_actions[name](args)
67 except Exception, e:
68 # If a linker driver action failed, remove the linker output to make the
69 # build step atomic.
70 try:
71 os.unlink(_FindLinkerOutput(compiler_driver_args))
72 except RuntimeError:
Mark Mentovai 2016/05/20 15:42:42 Why isn’t this just “except:”? os.unlink is most
Robert Sesek 2016/05/20 19:09:55 This was to only capture the exception from _FindL
73 # Re-raise the original exception, since it may be more interesting than
74 # failing to find the output flag.
75 raise e
76 return
77
78 # Re-report the original failure.
Mark Mentovai 2016/05/20 15:42:42 Actually, since this is what you want to do no mat
79 raise
80
81
82 def ProcessLinkerDriverArg(arg):
83 """Processes a linker driver argument and returns a tuple containing the
84 name and unary lambda to invoke for that linker driver action.
85
86 Args:
87 arg: string, The linker driver argument.
88
89 Returns:
90 A 2-tuple:
91 0: The driver action name, as in _LINKER_DRIVER_ACTIONS.
92 1: An 1-ary lambda that takes the full list of arguments passed to
93 Main(). The lambda should call the linker driver action that
94 corresponds to the argument.
95 """
96 if not arg.startswith(_LINKER_DRIVER_ARG_PREFIX):
97 raise ValueError('%s is not a linker driver argument' % (arg,))
98
99 sub_arg = arg[len(_LINKER_DRIVER_ARG_PREFIX):]
100
101 for driver_action in _LINKER_DRIVER_ACTIONS:
102 (name, action) = driver_action
103 if sub_arg.startswith(name):
104 return (name,
105 lambda full_args: action(sub_arg[len(name):], full_args))
106
107 raise ValueError('Unknown linker driver argument: %s' % (arg,))
108
109
110 def RunDsymUtil(dsym_path_prefix, full_args):
111 """Linker driver action for -Wcrl,dsym,<dsym-path-prefix>. Invokes dsymutil
112 on the linker's output and produces a dsym file at |dsym_file| path.
113
114 Args:
115 dsym_path_prefix: string, The path at which the dsymutil output should be
116 located.
117 full_args: list of string, Full argument list for the linker driver.
118 """
119 if not len(dsym_path_prefix):
120 raise ValueError('Unspecified dSYM output file')
121
122 linker_out = _FindLinkerOutput(full_args)
123 (head, tail) = os.path.split(linker_out)
124 dsym_out = os.path.join(dsym_path_prefix, tail + '.dSYM')
125 subprocess.check_call(['xcrun', 'dsymutil', '-o', dsym_out, linker_out])
126
127
128 def RunStrip(strip_args_string, full_args):
129 """Linker driver action for -Wcrl,strip,<strip_arguments>.
130
131 Args:
132 strip_args_string: string, Comma-separated arguments for `strip`.
133 full_args: list of string, Full arguments for the linker driver.
134 """
135 strip_args_list = strip_args_string.split(',')
136 strip_command = ['xcrun', 'strip'] + strip_args_list
137 strip_command.append(_FindLinkerOutput(full_args))
138 subprocess.check_call(strip_command)
139
140
141 def _FindLinkerOutput(full_args):
142 """Finds the output of the linker by looking for the output flag in its
143 argument list. As this is a required linker argument, raises an error if it
Mark Mentovai 2016/05/20 15:42:42 Not true. % echo 'int main(int argc, char* argv[]
Robert Sesek 2016/05/20 19:09:55 This comment is true for our build.
Mark Mentovai 2016/05/20 19:41:11 Robert Sesek wrote:
144 cannot be found.
145 """
146 for (i, arg) in enumerate(full_args):
147 if arg == '-o':
148 return full_args[i+1]
149 raise RuntimeError('Unable to locate linker output file')
150
151
152 """List of linker driver actions. The sort order of this list affects the
153 order in which the actions are invoked. The first item in the tuple is the
154 argument's -Wcrl,<sub_argument> and the second is the function to invoke.
155 """
156 _LINKER_DRIVER_ACTIONS = [
157 ('dsym,', RunDsymUtil),
158 ('strip,', RunStrip),
159 ]
160
161
162 if __name__ == '__main__':
163 Main(sys.argv)
164 sys.exit(0)
OLDNEW
« no previous file with comments | « build/toolchain/mac/BUILD.gn ('k') | chrome/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698