| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 | 2 |
| 3 # Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 import os | 7 import os |
| 8 import os.path | 8 import os.path |
| 9 import shutil | 9 import shutil |
| 10 import subprocess | 10 import subprocess |
| 11 import sys | 11 import sys |
| 12 | 12 |
| 13 # The linker_driver.py is responsible for forwarding a linker invocation to | 13 # The linker_driver.py is responsible for forwarding a linker invocation to |
| 14 # the compiler driver, while processing special arguments itself. | 14 # the compiler driver, while processing special arguments itself. |
| 15 # | 15 # |
| 16 # Usage: linker_driver.py clang++ main.o -L. -llib -o prog -Wcrl,dsym,out | 16 # Usage: linker_driver.py clang++ main.o -L. -llib -o prog -Wcrl,dsym,out |
| 17 # | 17 # |
| 18 # On Mac, the logical step of linking is handled by three discrete tools to | 18 # On Mac, the logical step of linking is handled by three discrete tools to |
| 19 # perform the image link, debug info link, and strip. The linker_driver.py | 19 # perform the image link, debug info link, and strip. The linker_driver.py |
| 20 # combines these three steps into a single tool. | 20 # combines these three steps into a single tool. |
| 21 # | 21 # |
| 22 # The command passed to the linker_driver.py should be the compiler driver | 22 # The command passed to the linker_driver.py should be the compiler driver |
| 23 # invocation for the linker. It is first invoked unaltered (except for the | 23 # invocation for the linker. It is first invoked unaltered (except for the |
| 24 # removal of the special driver arguments, described below). Then the driver | 24 # removal of the special driver arguments, described below). Then the driver |
| 25 # performs additional actions, based on these arguments: | 25 # performs additional actions, based on these arguments: |
| 26 # | 26 # |
| 27 # -Wcrl,dsym,<dsym_path_prefix> | 27 # -Wcrl,dsym,<dsym_path_prefix>,<dsym_file_name> |
| 28 # After invoking the linker, this will run `dsymutil` on the linker's | 28 # After invoking the linker, this will run `dsymutil` on the linker's |
| 29 # output, producing a dSYM bundle, stored at dsym_path_prefix. As an | 29 # output, producing a dSYM bundle, stored at dsym_path_prefix. As an |
| 30 # example, if the linker driver were invoked with: | 30 # example, if the linker driver were invoked with: |
| 31 # "... -o out/gn/obj/foo/libbar.dylib ... -Wcrl,dsym,out/gn ..." | 31 # "... -o out/gn/obj/foo/libbar.dylib ... -Wcrl,dsym,out/gn, |
| 32 # The resulting dSYM would be out/gn/libbar.dylib.dSYM/. | 32 # libbar.framework.dSYM ..." |
| 33 # The resulting dSYM would be out/gn/libbar.framework.dSYM/. |
| 33 # | 34 # |
| 34 # -Wcrl,unstripped,<unstripped_path_prefix> | 35 # -Wcrl,unstripped,<unstripped_path_prefix> |
| 35 # After invoking the linker, and before strip, this will save a copy of | 36 # After invoking the linker, and before strip, this will save a copy of |
| 36 # the unstripped linker output in the directory unstripped_path_prefix. | 37 # the unstripped linker output in the directory unstripped_path_prefix. |
| 37 # | 38 # |
| 38 # -Wcrl,strip,<strip_arguments> | 39 # -Wcrl,strip,<strip_arguments> |
| 39 # After invoking the linker, and optionally dsymutil, this will run | 40 # After invoking the linker, and optionally dsymutil, this will run |
| 40 # the strip command on the linker's output. strip_arguments are | 41 # the strip command on the linker's output. strip_arguments are |
| 41 # comma-separated arguments to be passed to the strip command. | 42 # comma-separated arguments to be passed to the strip command. |
| 42 | 43 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 115 |
| 115 for driver_action in _LINKER_DRIVER_ACTIONS: | 116 for driver_action in _LINKER_DRIVER_ACTIONS: |
| 116 (name, action) = driver_action | 117 (name, action) = driver_action |
| 117 if sub_arg.startswith(name): | 118 if sub_arg.startswith(name): |
| 118 return (name, | 119 return (name, |
| 119 lambda full_args: action(sub_arg[len(name):], full_args)) | 120 lambda full_args: action(sub_arg[len(name):], full_args)) |
| 120 | 121 |
| 121 raise ValueError('Unknown linker driver argument: %s' % (arg,)) | 122 raise ValueError('Unknown linker driver argument: %s' % (arg,)) |
| 122 | 123 |
| 123 | 124 |
| 124 def RunDsymUtil(dsym_path_prefix, full_args): | 125 def RunDsymUtil(dsym_args_string, full_args): |
| 125 """Linker driver action for -Wcrl,dsym,<dsym-path-prefix>. Invokes dsymutil | 126 """Linker driver action for -Wcrl,dsym,<dsym-path-prefix>,<dsym-file-name>. |
| 126 on the linker's output and produces a dsym file at |dsym_file| path. | 127 Invokes dsymutil on the linker's output and produces a dsym file at |
| 128 |dsym_path_prefix| path with |dsym_file_name| name. |
| 127 | 129 |
| 128 Args: | 130 Args: |
| 131 dsym_args_string: string, consists of comma-separated dsym_path_prefix and |
| 132 dsym_file_name. |
| 133 full_args: list of string, Full argument list for the linker driver. |
| 134 |
| 129 dsym_path_prefix: string, The path at which the dsymutil output should be | 135 dsym_path_prefix: string, The path at which the dsymutil output should be |
| 130 located. | 136 located. |
| 131 full_args: list of string, Full argument list for the linker driver. | 137 dsym_file_name: string, The resulting file name of the .dSYM bundle. |
| 132 | 138 |
| 133 Returns: | 139 Returns: |
| 134 list of string, Build step outputs. | 140 list of string, Build step outputs. |
| 135 """ | 141 """ |
| 142 (dsym_path_prefix, dsym_file_name) = dsym_args_string.split(',') |
| 136 if not len(dsym_path_prefix): | 143 if not len(dsym_path_prefix): |
| 137 raise ValueError('Unspecified dSYM output file') | 144 raise ValueError('Unspecified dSYM output file') |
| 138 | 145 |
| 139 linker_out = _FindLinkerOutput(full_args) | 146 linker_out = _FindLinkerOutput(full_args) |
| 140 base = os.path.basename(linker_out) | 147 dsym_out = os.path.join(dsym_path_prefix, dsym_file_name) |
| 141 dsym_out = os.path.join(dsym_path_prefix, base + '.dSYM') | |
| 142 | 148 |
| 143 # Remove old dSYMs before invoking dsymutil. | 149 # Remove old dSYMs before invoking dsymutil. |
| 144 _RemovePath(dsym_out) | 150 _RemovePath(dsym_out) |
| 145 subprocess.check_call(['xcrun', 'dsymutil', '-o', dsym_out, linker_out]) | 151 subprocess.check_call(['xcrun', 'dsymutil', '-o', dsym_out, linker_out]) |
| 146 return [dsym_out] | 152 return [dsym_out] |
| 147 | 153 |
| 148 | 154 |
| 149 def RunSaveUnstripped(unstripped_path_prefix, full_args): | 155 def RunSaveUnstripped(unstripped_path_prefix, full_args): |
| 150 """Linker driver action for -Wcrl,unstripped,<unstripped_path_prefix>. Copies | 156 """Linker driver action for -Wcrl,unstripped,<unstripped_path_prefix>. Copies |
| 151 the linker output to |unstripped_path_prefix| before stripping. | 157 the linker output to |unstripped_path_prefix| before stripping. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 _LINKER_DRIVER_ACTIONS = [ | 227 _LINKER_DRIVER_ACTIONS = [ |
| 222 ('dsym,', RunDsymUtil), | 228 ('dsym,', RunDsymUtil), |
| 223 ('unstripped,', RunSaveUnstripped), | 229 ('unstripped,', RunSaveUnstripped), |
| 224 ('strip,', RunStrip), | 230 ('strip,', RunStrip), |
| 225 ] | 231 ] |
| 226 | 232 |
| 227 | 233 |
| 228 if __name__ == '__main__': | 234 if __name__ == '__main__': |
| 229 Main(sys.argv) | 235 Main(sys.argv) |
| 230 sys.exit(0) | 236 sys.exit(0) |
| OLD | NEW |