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

Side by Side Diff: tools-webrtc/ios/build_ios_libs.py

Issue 2662513004: Rewrite iOS FAT libraries build script in Python (Closed)
Patch Set: Catch error when deleting a file (was it a mistake in the Bash script?) Created 3 years, 10 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 | « no previous file | tools-webrtc/ios/build_ios_libs.sh » ('j') | tools-webrtc/ios/build_ios_libs.sh » ('J')
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 (c) 2017 The WebRTC project authors. All Rights Reserved.
4 #
5 # Use of this source code is governed by a BSD-style license
6 # that can be found in the LICENSE file in the root of the source
7 # tree. An additional intellectual property rights grant can be found
8 # in the file PATENTS. All contributing project authors may
9 # be found in the AUTHORS file in the root of the source tree.
10
11 """WebRTC iOS FAT libraries build script.
12 Each architecture is compiled separately before being merged together.
13 By default, the library is created in out_ios_libs/. (Change with -o.)
14 The headers will be copied to out_ios_libs/include.
15 """
16
17 import argparse
18 import distutils.dir_util
19 import logging
20 import os
21 import shutil
22 import subprocess
23 import sys
24
25
26 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
27 WEBRTC_BASE_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..'))
28 SDK_OUTPUT_DIR = os.path.join(WEBRTC_BASE_DIR, 'out_ios_libs')
29 SDK_LIB_NAME = 'librtc_sdk_objc.a'
30 SDK_FRAMEWORK_NAME = 'WebRTC.framework'
31
32 BUILD_FLAVOR = 'release'
33 ENABLED_ARCHITECTURES = ['arm', 'arm64', 'x64']
34 IOS_DEPLOYMENT_TARGET = '8.0'
35 LIBVPX_BUILD_VP9 = False
36 CUSTOM_GN_OPTS = [] # example: ['some_option=foo bar', 'other_option=true']
37
38
39 def _ParseArgs():
40 parser = argparse.ArgumentParser(description=__doc__)
41 parser.add_argument('-b', '--build_type', default='framework',
42 choices=['framework', 'static_only'],
43 help='The build type. Can be "framework" or "static_only". '
44 'Defaults to "framework".')
45 parser.add_argument('-c', '--clean', action='store_true', default=False,
46 help='Removes the previously generated build output, if any.')
47 parser.add_argument('-o', '--output-dir', default=SDK_OUTPUT_DIR,
48 help='Specifies a directory to output the build artifacts to. '
49 'If specified together with -c, deletes the dir.')
50 parser.add_argument('-r', '--revision', type=int, default=0,
51 help='Specifies a revision number to embed if building the framework.')
52 parser.add_argument('-e', '--bitcode', action='store_true', default=False,
53 help='Compile with bitcode.')
54 return parser.parse_args()
55
56
57 def _CleanArtifacts(output_dir):
58 if os.path.isdir(output_dir):
59 logging.info('Deleting %s', output_dir)
60 shutil.rmtree(output_dir, True)
kjellander_webrtc 2017/01/31 21:39:54 I'm not sure we want to ignore errors here. Since
oprypin_webrtc 2017/02/06 08:39:14 Done.
61
62
63 def BuildWebRTC(output_dir, target_arch, flavor, build_type,
64 ios_deployment_target, libvpx_build_vp9, use_bitcode,
65 custom_gn_options=[]):
kjellander_webrtc 2017/01/31 21:39:53 empty lists as a default parameters in Python are
oprypin_webrtc 2017/02/06 08:39:14 Done.
66 output_dir = os.path.join(output_dir, target_arch + '_libs')
67 gn_args = ['target_os="ios"', 'ios_enable_code_signing=false',
68 'use_xcode_clang=true', 'is_component_build=false']
69
70 # Add flavor option.
kjellander_webrtc 2017/01/31 21:39:54 I know you're just preserving the behavior of the
oprypin_webrtc 2017/02/06 08:39:14 I made the change to use a flag but I feel like th
kjellander_webrtc 2017/02/06 08:58:24 Fair enough.
71 if flavor == 'debug':
72 gn_args.append('is_debug=true')
73 elif flavor == 'release':
74 gn_args.append('is_debug=false')
75 else:
76 raise ValueError('Unexpected flavor type: %s' % flavor)
77
78 # Add the specified architecture.
kjellander_webrtc 2017/01/31 21:39:53 I know these comments were there in the bash scrip
oprypin_webrtc 2017/02/06 08:39:14 Done.
79 gn_args.append('target_cpu="%s"' % target_arch)
80
81 # Add deployment target.
82 gn_args.append('ios_deployment_target="%s"' % ios_deployment_target)
83
84 # Add vp9 option.
85 gn_args.append('rtc_libvpx_build_vp9=' +
86 ('true' if libvpx_build_vp9 else 'false'))
87
88 # Add bitcode option.
89 gn_args.append('enable_ios_bitcode=' +
90 ('true' if use_bitcode else 'false'))
91
92 # Add custom options.
93 gn_args.extend(custom_gn_options)
94
95 # Generate static or dynamic.
96 if build_type == 'static_only':
97 gn_target_name = 'rtc_sdk_objc'
98 elif build_type == 'framework':
99 gn_target_name = 'rtc_sdk_framework_objc'
100 gn_args.append('enable_dsyms=true')
101 gn_args.append('enable_stripping=true')
102 else:
103 raise ValueError('Build type "%s" is not supported.' % build_type)
104
105 logging.info('Building WebRTC with args: %s', ' '.join(gn_args))
106 cmd = ['gn', 'gen', output_dir,
107 '--args=' + ' '.join(gn_args)]
108 subprocess.check_call(cmd)
kjellander_webrtc 2017/01/31 21:39:54 For debugging purposes, I find it useful to wrap s
oprypin_webrtc 2017/02/06 08:39:14 Done.
109 logging.info('Building target: %s', gn_target_name)
110 cmd = ['ninja', '-C', output_dir, gn_target_name]
111 subprocess.check_call(cmd)
112
113 # Strip debug symbols to reduce size.
114 if build_type == 'static_only':
115 gn_target_path = os.path.join(output_dir, 'obj', 'webrtc', 'sdk',
116 'lib%s.a' % gn_target_name)
117 cmd = ['strip', '-S', gn_target_path, '-o',
118 os.path.join(output_dir, 'lib%s.a' % gn_target_name)]
119 subprocess.check_call(cmd)
120
121
122 def main():
123 args = _ParseArgs()
124
125 logging.basicConfig(level=logging.INFO)
126
127 if args.clean:
128 _CleanArtifacts(args.output_dir)
129 return 0
130
131 # Build all architectures.
132 for arch in ENABLED_ARCHITECTURES:
133 BuildWebRTC(args.output_dir, arch, BUILD_FLAVOR, args.build_type,
134 IOS_DEPLOYMENT_TARGET, LIBVPX_BUILD_VP9, args.bitcode,
135 CUSTOM_GN_OPTS)
136
137 # Ignoring x86 except for static libraries for now because of a GN build issue
138 # where the generated dynamic framework has the wrong architectures.
139
140 # Create FAT archive.
141 if args.build_type == 'static_only':
142 BuildWebRTC(args.output_dir, 'x86', BUILD_FLAVOR, args.build_type,
143 IOS_DEPLOYMENT_TARGET, LIBVPX_BUILD_VP9, args.bitcode,
144 CUSTOM_GN_OPTS)
145
146 arm_lib_path = os.path.join(args.output_dir, 'arm_libs', SDK_LIB_NAME)
147 arm64_lib_path = os.path.join(args.output_dir, 'arm64_libs', SDK_LIB_NAME)
148 x64_lib_path = os.path.join(args.output_dir, 'x64_libs', SDK_LIB_NAME)
149 x86_lib_path = os.path.join(args.output_dir, 'x86_libs', SDK_LIB_NAME)
150
151 # Combine the slices.
152 cmd = ['lipo', arm_lib_path, arm64_lib_path, x64_lib_path, x86_lib_path,
153 '-create', '-output', os.path.join(args.output_dir, SDK_LIB_NAME)]
154 subprocess.check_call(cmd)
155
156 elif args.build_type == 'framework':
157 arm_lib_path = os.path.join(args.output_dir, 'arm_libs')
158 arm64_lib_path = os.path.join(args.output_dir, 'arm64_libs')
159 x64_lib_path = os.path.join(args.output_dir, 'x64_libs')
160
161 # Combine the slices.
162 dylib_path = os.path.join(SDK_FRAMEWORK_NAME, 'WebRTC')
163 # Use distutils instead of shutil to support merging folders.
164 distutils.dir_util.copy_tree(
165 os.path.join(arm64_lib_path, SDK_FRAMEWORK_NAME), args.output_dir)
166 try:
167 os.remove(os.path.join(args.output_dir, dylib_path))
kjellander_webrtc 2017/01/31 21:39:54 Use shutil.rmtree instead and check with os.path.i
oprypin_webrtc 2017/02/06 08:39:14 Not sure what you mean here. Seems like we are del
kjellander_webrtc 2017/02/06 08:58:24 Ah, I thought it was a dir. Still nicer to check i
oprypin_webrtc 2017/02/06 09:19:50 Just applying the EAFP principle. Aside from how i
kjellander_webrtc 2017/02/06 11:33:02 You're right. This is fine.
168 except OSError:
169 pass
170 logging.info('Merging framework slices.')
171 cmd = ['lipo', os.path.join(arm_lib_path, dylib_path),
172 os.path.join(arm64_lib_path, dylib_path),
173 os.path.join(x64_lib_path, dylib_path),
174 '-create', '-output', os.path.join(args.output_dir, dylib_path)]
175 subprocess.check_call(cmd)
176
177 # Remove stray mobileprovision if it exists until chromium roll lands.
178 # See https://codereview.chromium.org/2397433002.
kjellander_webrtc 2017/01/31 21:39:54 This was rolled in long time ago. Can you make a s
oprypin_webrtc 2017/02/06 08:39:14 https://codereview.webrtc.org/2676233002/
kjellander_webrtc 2017/02/06 08:58:24 Acknowledged.
179 provision_file = os.path.join(args.output_dir, SDK_FRAMEWORK_NAME,
180 'embedded.mobileprovision')
181 try:
182 os.remove(provision_file)
183 except OSError:
184 pass
185
186 # Merge the dSYM slices.
187 dsym_path = 'WebRTC.dSYM/Contents/Resources/DWARF/WebRTC'
kjellander_webrtc 2017/01/31 21:39:53 since we use os.path.join everywhere else, we shou
oprypin_webrtc 2017/02/06 08:39:14 Done.
188 distutils.dir_util.copy_tree(os.path.join(arm64_lib_path, 'WebRTC.dSYM'),
189 args.output_dir)
190 os.remove(os.path.join(args.output_dir, dsym_path))
191 logging.info('Merging dSYM slices.')
192 cmd = ['lipo', os.path.join(arm_lib_path, dsym_path),
193 os.path.join(arm64_lib_path, dsym_path),
194 os.path.join(x64_lib_path, dsym_path),
195 '-create', '-output', os.path.join(args.output_dir, dsym_path)]
196 subprocess.check_call(cmd)
197
198 # Modify the version number.
199 # Format should be <Branch cut MXX>.<Hotfix #>.<Rev #>.
200 # e.g. 55.0.14986 means branch cut 55, no hotfixes, and revision 14986.
201 infoplist_path = os.path.join(args.output_dir, SDK_FRAMEWORK_NAME,
202 'Info.plist')
203 cmd = ['PlistBuddy', '-c',
204 'Print :CFBundleShortVersionString', infoplist_path]
205 major_minor = subprocess.check_output(cmd).strip()
206 version_number = '%s.%s' % (major_minor, args.revision)
207 logging.info('Substituting revision number: %s', version_number)
208 cmd = ['PlistBuddy', '-c',
209 'Set :CFBundleVersion ' + version_number, infoplist_path]
210 subprocess.check_call(cmd)
211 subprocess.check_call(['plutil', '-convert', 'binary1', infoplist_path])
212
213 logging.info('Done.')
214 return 0
215
216
217 if __name__ == '__main__':
218 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | tools-webrtc/ios/build_ios_libs.sh » ('j') | tools-webrtc/ios/build_ios_libs.sh » ('J')

Powered by Google App Engine
This is Rietveld 408576698