OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
Hiroshi Ichikawa
2017/05/22 23:46:39
It would be great if you put this script at more g
mef
2017/05/23 20:56:36
I agree that it should move to more general locati
Hiroshi Ichikawa
2017/05/24 05:10:23
Sounds good, thanks!
| |
2 | |
3 # Copyright 2017 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 # Create a static library which exposes only symbols which are explicitly marked | |
8 # as visible e.g., by __attribute__((visibility("default"))). | |
9 # | |
10 # See BUILD.gn in this directory for usage example. | |
11 # | |
12 # This way, we can reduce risk of symbol conflict when linking it into apps | |
13 # by exposing internal symbols, especially in third-party libraries. | |
14 | |
15 import optparse | |
16 import os | |
17 import subprocess | |
18 | |
19 | |
20 # Mapping from GN's target_cpu attribute to ld's -arch parameter. | |
21 # Taken from the definition of config("compiler") in: | |
22 # //build/config/mac/BUILD.gn | |
23 GN_CPU_TO_LD_ARCH = { | |
24 'x64': 'x86_64', | |
25 'x86': 'i386', | |
26 'armv7': 'armv7', | |
27 'arm': 'armv7', | |
28 'arm64': 'arm64', | |
29 } | |
30 | |
31 | |
32 def main(): | |
33 parser = optparse.OptionParser() | |
34 parser.add_option( | |
35 '--input_libs', | |
36 help='Comma-separated paths to input .a files which contain symbols ' | |
37 'which must be always linked.') | |
38 parser.add_option( | |
39 '--deps_lib', | |
40 help='The path to a complete static library (.a file) which contains all ' | |
41 'dependencies of --input_libs. .o files in this library are also ' | |
42 'added to the output library, but only if they are referred from ' | |
43 '--input_libs.') | |
44 parser.add_option( | |
45 '--output_obj', | |
46 help='Outputs the generated .o file here. This is an intermediate file.') | |
47 parser.add_option( | |
48 '--output_lib', | |
49 help='Outputs the generated .a file here.') | |
50 parser.add_option( | |
51 '--current_cpu', | |
52 help='The current processor architecture in the format of the target_cpu ' | |
53 'attribute in GN.') | |
54 (options, args) = parser.parse_args() | |
55 assert not args | |
56 | |
57 # ld -r concatenates multiple .o files and .a files into a single .o file, | |
58 # while "hiding" symbols not marked as visible. | |
59 command = [ | |
60 'xcrun', 'ld', | |
61 '-arch', GN_CPU_TO_LD_ARCH[options.current_cpu], | |
62 '-r', | |
63 ] | |
64 for input_lib in options.input_libs.split(','): | |
65 # By default, ld only pulls .o files out of a static library if needed to | |
66 # resolve some symbol reference. We apply -force_load option to input_lib | |
67 # (but not to deps_lib) to force pulling all .o files. | |
68 command += ['-force_load', input_lib] | |
69 command += [ | |
70 options.deps_lib, | |
71 '-o', options.output_obj | |
72 ] | |
73 try: | |
74 subprocess.check_call(command) | |
75 except subprocess.CalledProcessError: | |
76 # Work around LD failure for x86 Debug buiilds when it fails with error: | |
77 # ld: scattered reloc r_address too large for architecture i386 | |
78 if options.current_cpu == "x86": | |
79 # Copy input lib into output lib without dependencies. | |
80 # TODO(mef): Consider including dependencies without hiding them. | |
81 command = [ | |
82 'xcrun', 'lipo', | |
83 '-arch', 'i386', options.input_libs, | |
84 '-output', options.output_lib, | |
85 '-create', | |
86 ] | |
87 subprocess.check_call(command) | |
88 return | |
89 | |
90 if os.path.exists(options.output_lib): | |
91 os.remove(options.output_lib) | |
92 | |
93 # Creates a .a file which contains a single .o file. | |
94 command = [ | |
95 'xcrun', 'ar', '-r', | |
96 options.output_lib, | |
97 options.output_obj, | |
98 ] | |
99 subprocess.check_call(command) | |
100 | |
101 | |
102 if __name__ == "__main__": | |
103 main() | |
OLD | NEW |