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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: build/toolchain/mac/linker_driver.py
diff --git a/build/toolchain/mac/linker_driver.py b/build/toolchain/mac/linker_driver.py
new file mode 100755
index 0000000000000000000000000000000000000000..2cbb395d266d6747b7de365b2dce8669be465ab5
--- /dev/null
+++ b/build/toolchain/mac/linker_driver.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import os.path
+import subprocess
+import sys
+
+# The linker_driver.py is responsible for forwarding a linker invocation to
+# the compiler driver, while processing special arguments itself.
+#
+# On Mac, the logical step of linking is handled by three discrete tools to
+# perform the image link, debug info link, and strip. The linker_driver.py
+# 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
+#
+# The invocation of the linker_driver.py is first passed unaltered, except for
+# the removal of the special driver arguments, described below. The driver
+# arguments control what other steps occur after the image link.
+#
+# -Wcrl,dsym,<dsym_path_prefix>
+# After invoking the linker, this will run `dsymutil` on the linker's
+# 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.
+#
+# -Wcrl,strip,<strip_arguments>
+# After invoking the linker, and optionally dsymutil, this will run
+# the strip command on the linker's output. strip_arguments are
+# comma-separated arguments to be passed to the strip command.
+
+_LINKER_DRIVER_ARG_PREFIX = '-Wcrl,'
+
+def Main(args):
+ """Main function for the linker driver. Separates out the arguments for
+ the main compiler driver and the linker driver, then invokes all the
+ required tools.
+
+ Args:
+ args: list of string, Arguments to the script.
+ """
+
+ if len(args) < 2:
+ raise RuntimeError("Usage: linker_driver.py [linker-invocation]")
+
+ # Collect arguments to the linker driver (this script) and remove them from
+ # the arguments being passed to the compiler driver.
+ linker_driver_actions = {}
+ compiler_driver_args = []
+ for arg in args[1:]:
+ if arg.startswith(_LINKER_DRIVER_ARG_PREFIX):
+ # Convert driver actions into a map of name => lambda to invoke.
+ driver_action = ProcessLinkerDriverArg(arg)
+ linker_driver_actions[driver_action[0]] = driver_action[1]
+ else:
+ compiler_driver_args.append(arg)
+
+ # Run the linker by invoking the compiler driver.
+ subprocess.check_call(compiler_driver_args)
+
+ # Run the linker driver actions, in the order specified by the actions list.
+ 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.
+ name = action[0]
+ if name in linker_driver_actions:
+ linker_driver_actions[name](args)
+
+
+def ProcessLinkerDriverArg(arg):
+ """Processes a linker driver argument and returns a tuple containing the
+ name and unary lambda to invoke for that linker driver action.
+
+ Args:
+ arg: string, The linker driver argument.
+
+ Returns:
+ A 2-tuple:
+ 0: The driver action name, as in _LINKER_DRIVER_ACTIONS.
+ 1: An 1-ary lambda that takes the full list of arguments passed to
+ Main(). The lambda should call the linker driver action that
+ corresponds to the argument.
+ """
+ if not arg.startswith(_LINKER_DRIVER_ARG_PREFIX):
+ raise ValueError('%s is not a linker driver argument' % (arg,))
+
+ sub_arg = arg[len(_LINKER_DRIVER_ARG_PREFIX):]
+
+ for driver_action in _LINKER_DRIVER_ACTIONS:
+ (name, action) = driver_action
+ if sub_arg.startswith(name):
+ return (name,
+ lambda full_args: action(sub_arg[len(name):], full_args))
+
+ raise ValueError('Unknown linker driver argument: %s' % (arg,))
+
+
+def RunDsymUtil(dsym_path_prefix, full_args):
+ """Linker driver action for -Wcrl,dsym,<dsym-path-prefix>. Invokes dsymutil
+ on the linker's output and produces a dsym file at |dsym_file| path.
+
+ Args:
+ dsym_path_prefix: string, The path at which the dsymutil output should be
+ located.
+ full_args: list of string, Full argument list for the linker driver.
+ """
+ if not len(dsym_path_prefix):
+ raise ValueError('Unspecified dSYM output file')
+
+ linker_out = _FindLinkerOutput(full_args)
+ (head, tail) = os.path.split(linker_out)
+ 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
+ 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
+
+
+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.
+ """Linker driver action for -Wcrl,strip,<strip_arguments>.
+
+ Args:
+ strip_args_string: string, Comma-separated arguments for `strip`.
+ full_args: list of string, Full arguments for the linker driver.
+ """
+ strip_args_list = strip_args_string.split(',')
+ strip_command = ['xcrun', 'strip'] + strip_args_list
+ strip_command.append(_FindLinkerOutput(full_args))
+ subprocess.check_call(strip_command)
+
+
+def _FindLinkerOutput(full_args):
+ """Finds the output of the linker by looking for the output flag in its
+ argument list. As this is a required linker argument, raises an error if it
+ cannot be found.
+ """
+ for (i, arg) in enumerate(full_args):
+ if arg == '-o':
+ return full_args[i+1]
+ raise RuntimeError('Unable to locate linker output file')
+
+
+"""List of linker driver actions. The sort order of this list affects the
+order in which the actions are invoked. The first item in the tuple is the
+argument's -Wcrl,<sub_argument> and the second is the function to invoke.
+"""
+_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
+ ('dsym,', RunDsymUtil),
+ ('strip,', RunStrip),
+]
+
+
+if __name__ == '__main__':
+ Main(sys.argv)
+ sys.exit(0)

Powered by Google App Engine
This is Rietveld 408576698