Christoffer Jansson | 4e8a773 | 2022-02-08 08:01:12 | [diff] [blame] | 1 | #!/usr/bin/env vpython3 |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 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. |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 10 | """WebRTC iOS XCFramework build script. |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 11 | Each architecture is compiled separately before being merged together. |
| 12 | By default, the library is created in out_ios_libs/. (Change with -o.) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 13 | """ |
| 14 | |
| 15 | import argparse |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 16 | import logging |
| 17 | import os |
Junji Watanabe | 43f724d | 2025-06-25 12:54:53 | [diff] [blame] | 18 | import pathlib |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 19 | import shutil |
| 20 | import subprocess |
| 21 | import sys |
| 22 | |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 23 | os.environ['PATH'] = '/usr/libexec' + os.pathsep + os.environ['PATH'] |
| 24 | |
| 25 | SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
Henrik Kjellander | ec57e05 | 2017-10-17 19:36:01 | [diff] [blame] | 26 | SRC_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..')) |
| 27 | sys.path.append(os.path.join(SRC_DIR, 'build')) |
| 28 | import find_depot_tools |
| 29 | |
| 30 | SDK_OUTPUT_DIR = os.path.join(SRC_DIR, 'out_ios_libs') |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 31 | SDK_FRAMEWORK_NAME = 'WebRTC.framework' |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 32 | SDK_DSYM_NAME = 'WebRTC.dSYM' |
| 33 | SDK_XCFRAMEWORK_NAME = 'WebRTC.xcframework' |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 34 | |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 35 | ENABLED_ARCHS = [ |
| 36 | 'device:arm64', 'simulator:arm64', 'simulator:x64', |
Jordan Rose | 4a3296d | 2021-07-23 22:06:19 | [diff] [blame] | 37 | 'catalyst:arm64', 'catalyst:x64', |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 38 | 'arm64', 'x64' |
| 39 | ] |
| 40 | DEFAULT_ARCHS = [ |
| 41 | 'device:arm64', 'simulator:arm64', 'simulator:x64' |
| 42 | ] |
Jordan Rose | fb5a4a3 | 2023-07-31 22:31:37 | [diff] [blame] | 43 | IOS_MINIMUM_DEPLOYMENT_TARGET = { |
Jeremy Leconte | 9b81d2c | 2024-07-23 13:07:35 | [diff] [blame] | 44 | 'device': '14.0', |
| 45 | 'simulator': '14.0', |
Jordan Rose | 4a3296d | 2021-07-23 22:06:19 | [diff] [blame] | 46 | 'catalyst': '14.0' |
| 47 | } |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 48 | LIBVPX_BUILD_VP9 = False |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 49 | |
sakal | 67e414c | 2017-09-05 07:16:15 | [diff] [blame] | 50 | sys.path.append(os.path.join(SCRIPT_DIR, '..', 'libs')) |
| 51 | from generate_licenses import LicenseBuilder |
| 52 | |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 53 | |
| 54 | def _ParseArgs(): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 55 | parser = argparse.ArgumentParser(description=__doc__) |
| 56 | parser.add_argument('--build_config', |
| 57 | default='release', |
| 58 | choices=['debug', 'release'], |
| 59 | help='The build config. Can be "debug" or "release". ' |
| 60 | 'Defaults to "release".') |
| 61 | parser.add_argument( |
| 62 | '--arch', |
| 63 | nargs='+', |
| 64 | default=DEFAULT_ARCHS, |
| 65 | choices=ENABLED_ARCHS, |
| 66 | help='Architectures to build. Defaults to %(default)s.') |
| 67 | parser.add_argument( |
| 68 | '-c', |
| 69 | '--clean', |
| 70 | action='store_true', |
| 71 | default=False, |
| 72 | help='Removes the previously generated build output, if any.') |
| 73 | parser.add_argument( |
| 74 | '-p', |
| 75 | '--purify', |
| 76 | action='store_true', |
| 77 | default=False, |
| 78 | help='Purifies the previously generated build output by ' |
| 79 | 'removing the temporary results used when (re)building.') |
| 80 | parser.add_argument( |
| 81 | '-o', |
| 82 | '--output-dir', |
| 83 | type=os.path.abspath, |
| 84 | default=SDK_OUTPUT_DIR, |
| 85 | help='Specifies a directory to output the build artifacts to. ' |
| 86 | 'If specified together with -c, deletes the dir.') |
| 87 | parser.add_argument( |
| 88 | '-r', |
| 89 | '--revision', |
| 90 | type=int, |
| 91 | default=0, |
| 92 | help='Specifies a revision number to embed if building the framework.') |
| 93 | parser.add_argument('--verbose', |
| 94 | action='store_true', |
| 95 | default=False, |
| 96 | help='Debug logging.') |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 97 | parser.add_argument('--use-remoteexec', |
| 98 | action='store_true', |
| 99 | default=False, |
| 100 | help='Use RBE to build.') |
| 101 | parser.add_argument( |
| 102 | '--deployment-target', |
| 103 | default=IOS_MINIMUM_DEPLOYMENT_TARGET['device'], |
| 104 | help='Raise the minimum deployment target to build for. ' |
| 105 | 'Cannot be lowered below 12.0 for iOS/iPadOS ' |
| 106 | 'and 14.0 for Catalyst.') |
| 107 | parser.add_argument( |
| 108 | '--extra-gn-args', |
| 109 | default=[], |
| 110 | nargs='*', |
| 111 | help='Additional GN args to be used during Ninja generation.') |
mbonadei | 585209b | 2017-02-13 12:59:27 | [diff] [blame] | 112 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 113 | return parser.parse_args() |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 114 | |
| 115 | |
| 116 | def _RunCommand(cmd): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 117 | logging.debug('Running: %r', cmd) |
| 118 | subprocess.check_call(cmd, cwd=SRC_DIR) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 119 | |
| 120 | |
| 121 | def _CleanArtifacts(output_dir): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 122 | if os.path.isdir(output_dir): |
| 123 | logging.info('Deleting %s', output_dir) |
| 124 | shutil.rmtree(output_dir) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 125 | |
| 126 | |
VladimirTechMan | 7b188e8 | 2017-03-14 10:12:35 | [diff] [blame] | 127 | def _CleanTemporary(output_dir, architectures): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 128 | if os.path.isdir(output_dir): |
| 129 | logging.info('Removing temporary build files.') |
Junji Watanabe | b3ceadf | 2025-05-15 05:30:42 | [diff] [blame] | 130 | for (env, archs) in architectures.items(): |
| 131 | for arch in archs: |
| 132 | arch_lib_path = '%s_%s_libs' % (env, arch) |
| 133 | if os.path.isdir(arch_lib_path): |
| 134 | shutil.rmtree(arch_lib_path) |
VladimirTechMan | 7b188e8 | 2017-03-14 10:12:35 | [diff] [blame] | 135 | |
| 136 | |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 137 | def _ParseArchitecture(architectures): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 138 | result = dict() |
| 139 | for arch in architectures: |
| 140 | if ":" in arch: |
| 141 | target_environment, target_cpu = arch.split(":") |
| 142 | else: |
| 143 | logging.warning('The environment for build is not specified.') |
| 144 | logging.warning('It is assumed based on cpu type.') |
| 145 | logging.warning('See crbug.com/1138425 for more details.') |
| 146 | if arch == "x64": |
| 147 | target_environment = "simulator" |
| 148 | else: |
| 149 | target_environment = "device" |
| 150 | target_cpu = arch |
| 151 | archs = result.get(target_environment) |
| 152 | if archs is None: |
| 153 | result[target_environment] = {target_cpu} |
| 154 | else: |
| 155 | archs.add(target_cpu) |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 156 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 157 | return result |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 158 | |
| 159 | |
Jordan Rose | fb5a4a3 | 2023-07-31 22:31:37 | [diff] [blame] | 160 | def _VersionMax(*versions): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 161 | return max(*versions, |
| 162 | key=lambda version: |
| 163 | [int(component) for component in version.split('.')]) |
Jordan Rose | fb5a4a3 | 2023-07-31 22:31:37 | [diff] [blame] | 164 | |
| 165 | |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 166 | def BuildWebRTC(output_dir, target_environment, target_arch, flavor, |
| 167 | gn_target_name, ios_deployment_target, libvpx_build_vp9, |
Jeremy Leconte | 0b496cc | 2024-05-16 08:14:06 | [diff] [blame] | 168 | use_remoteexec, extra_gn_args): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 169 | gn_args = [ |
| 170 | 'target_os="ios"', |
| 171 | 'ios_enable_code_signing=false', |
| 172 | 'is_component_build=false', |
| 173 | 'rtc_include_tests=false', |
| 174 | ] |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 175 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 176 | # Add flavor option. |
| 177 | if flavor == 'debug': |
| 178 | gn_args.append('is_debug=true') |
| 179 | elif flavor == 'release': |
| 180 | gn_args.append('is_debug=false') |
| 181 | else: |
| 182 | raise ValueError('Unexpected flavor type: %s' % flavor) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 183 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 184 | gn_args.append('target_environment="%s"' % target_environment) |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 185 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 186 | gn_args.append('target_cpu="%s"' % target_arch) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 187 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 188 | gn_args.append('ios_deployment_target="%s"' % ios_deployment_target) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 189 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 190 | gn_args.append('rtc_libvpx_build_vp9=' + |
| 191 | ('true' if libvpx_build_vp9 else 'false')) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 192 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 193 | gn_args.append('use_lld=true') |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 194 | gn_args.append('rtc_enable_objc_symbol_export=true') |
Junji Watanabe | 5d165b1 | 2025-05-15 05:34:41 | [diff] [blame] | 195 | gn_args.append('use_siso=true') |
| 196 | if use_remoteexec: |
| 197 | gn_args.extend([ |
| 198 | 'use_remoteexec=true', |
| 199 | 'use_reclient=false', |
| 200 | ]) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 201 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 202 | args_string = ' '.join(gn_args + extra_gn_args) |
| 203 | logging.info('Building WebRTC with args: %s', args_string) |
mbonadei | 8714b8f | 2017-02-15 21:18:57 | [diff] [blame] | 204 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 205 | cmd = [ |
| 206 | sys.executable, |
| 207 | os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gn.py'), |
| 208 | 'gen', |
| 209 | output_dir, |
| 210 | '--args=' + args_string, |
| 211 | ] |
| 212 | _RunCommand(cmd) |
| 213 | logging.info('Building target: %s', gn_target_name) |
mbonadei | 8714b8f | 2017-02-15 21:18:57 | [diff] [blame] | 214 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 215 | cmd = [ |
Junji Watanabe | 5d165b1 | 2025-05-15 05:34:41 | [diff] [blame] | 216 | os.path.join(SRC_DIR, 'third_party', 'siso', 'cipd', 'siso'), |
| 217 | 'ninja', |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 218 | '-C', |
| 219 | output_dir, |
| 220 | gn_target_name, |
| 221 | ] |
Jeremy Leconte | 0b496cc | 2024-05-16 08:14:06 | [diff] [blame] | 222 | if use_remoteexec: |
Junji Watanabe | 5d165b1 | 2025-05-15 05:34:41 | [diff] [blame] | 223 | cmd.extend(['-remote_jobs', '200']) |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 224 | _RunCommand(cmd) |
Mirko Bonadei | 8cc6695 | 2020-10-30 09:13:45 | [diff] [blame] | 225 | |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 226 | |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 227 | def main(): |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 228 | args = _ParseArgs() |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 229 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 230 | logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 231 | |
Junji Watanabe | 43f724d | 2025-06-25 12:54:53 | [diff] [blame] | 232 | if not pathlib.Path(args.output_dir).is_relative_to(SRC_DIR): |
| 233 | logging.error('--output-dir must be under %s.', SRC_DIR) |
| 234 | return 1 |
| 235 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 236 | if args.clean: |
| 237 | _CleanArtifacts(args.output_dir) |
| 238 | return 0 |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 239 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 240 | # architectures is typed as Dict[str, Set[str]], |
| 241 | # where key is for the environment (device or simulator) |
| 242 | # and value is for the cpu type. |
| 243 | architectures = _ParseArchitecture(args.arch) |
| 244 | gn_args = args.extra_gn_args |
VladimirTechMan | 7b188e8 | 2017-03-14 10:12:35 | [diff] [blame] | 245 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 246 | if args.purify: |
Junji Watanabe | b3ceadf | 2025-05-15 05:30:42 | [diff] [blame] | 247 | _CleanTemporary(args.output_dir, architectures) |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 248 | return 0 |
VladimirTechMan | 7b188e8 | 2017-03-14 10:12:35 | [diff] [blame] | 249 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 250 | gn_target_name = 'framework_objc' |
| 251 | gn_args.append('enable_dsyms=true') |
| 252 | gn_args.append('enable_stripping=true') |
Kári Tristan Helgason | 1edbda0 | 2017-06-13 08:45:42 | [diff] [blame] | 253 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 254 | # Build all architectures. |
| 255 | framework_paths = [] |
| 256 | all_lib_paths = [] |
| 257 | for (environment, archs) in list(architectures.items()): |
| 258 | ios_deployment_target = _VersionMax( |
| 259 | args.deployment_target, IOS_MINIMUM_DEPLOYMENT_TARGET[environment]) |
| 260 | framework_path = os.path.join(args.output_dir, environment) |
| 261 | framework_paths.append(framework_path) |
| 262 | lib_paths = [] |
| 263 | for arch in archs: |
Junji Watanabe | b3ceadf | 2025-05-15 05:30:42 | [diff] [blame] | 264 | lib_path = '%s_%s_libs' % (framework_path, arch) |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 265 | lib_paths.append(lib_path) |
| 266 | BuildWebRTC(lib_path, environment, arch, args.build_config, |
| 267 | gn_target_name, ios_deployment_target, |
Jeremy Leconte | 0b496cc | 2024-05-16 08:14:06 | [diff] [blame] | 268 | LIBVPX_BUILD_VP9, args.use_remoteexec, gn_args) |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 269 | all_lib_paths.extend(lib_paths) |
Kári Tristan Helgason | 1edbda0 | 2017-06-13 08:45:42 | [diff] [blame] | 270 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 271 | # Combine the slices. |
| 272 | dylib_path = os.path.join(SDK_FRAMEWORK_NAME, 'WebRTC') |
| 273 | # Dylibs will be combined, all other files are the same across archs. |
| 274 | shutil.rmtree(os.path.join(framework_path, SDK_FRAMEWORK_NAME), |
| 275 | ignore_errors=True) |
| 276 | shutil.copytree(os.path.join(lib_paths[0], SDK_FRAMEWORK_NAME), |
| 277 | os.path.join(framework_path, SDK_FRAMEWORK_NAME), |
| 278 | symlinks=True) |
| 279 | logging.info('Merging framework slices for %s.', environment) |
| 280 | dylib_paths = [os.path.join(path, dylib_path) for path in lib_paths] |
| 281 | out_dylib_path = os.path.join(framework_path, dylib_path) |
| 282 | if os.path.islink(out_dylib_path): |
| 283 | out_dylib_path = os.path.join(os.path.dirname(out_dylib_path), |
| 284 | os.readlink(out_dylib_path)) |
| 285 | try: |
| 286 | os.remove(out_dylib_path) |
| 287 | except OSError: |
| 288 | pass |
| 289 | cmd = ['lipo'] + dylib_paths + ['-create', '-output', out_dylib_path] |
| 290 | _RunCommand(cmd) |
| 291 | |
| 292 | # Merge the dSYM slices. |
| 293 | lib_dsym_dir_path = os.path.join(lib_paths[0], SDK_DSYM_NAME) |
| 294 | if os.path.isdir(lib_dsym_dir_path): |
| 295 | shutil.rmtree(os.path.join(framework_path, SDK_DSYM_NAME), |
| 296 | ignore_errors=True) |
| 297 | shutil.copytree(lib_dsym_dir_path, |
| 298 | os.path.join(framework_path, SDK_DSYM_NAME)) |
| 299 | logging.info('Merging dSYM slices.') |
| 300 | dsym_path = os.path.join(SDK_DSYM_NAME, 'Contents', 'Resources', |
| 301 | 'DWARF', 'WebRTC') |
| 302 | lib_dsym_paths = [ |
| 303 | os.path.join(path, dsym_path) for path in lib_paths |
| 304 | ] |
| 305 | out_dsym_path = os.path.join(framework_path, dsym_path) |
| 306 | try: |
| 307 | os.remove(out_dsym_path) |
| 308 | except OSError: |
| 309 | pass |
| 310 | cmd = ['lipo' |
| 311 | ] + lib_dsym_paths + ['-create', '-output', out_dsym_path] |
| 312 | _RunCommand(cmd) |
| 313 | |
| 314 | # Check for Mac-style WebRTC.framework/Resources/ (for Catalyst)... |
| 315 | resources_dir = os.path.join(framework_path, SDK_FRAMEWORK_NAME, |
| 316 | 'Resources') |
| 317 | if not os.path.exists(resources_dir): |
| 318 | # ...then fall back to iOS-style WebRTC.framework/ |
| 319 | resources_dir = os.path.dirname(resources_dir) |
| 320 | |
| 321 | # Modify the version number. |
| 322 | # Format should be <Branch cut MXX>.<Hotfix #>.<Rev #>. |
| 323 | # e.g. 55.0.14986 means |
| 324 | # branch cut 55, no hotfixes, and revision 14986. |
| 325 | infoplist_path = os.path.join(resources_dir, 'Info.plist') |
| 326 | cmd = [ |
| 327 | 'PlistBuddy', '-c', 'Print :CFBundleShortVersionString', |
| 328 | infoplist_path |
| 329 | ] |
| 330 | major_minor = subprocess.check_output(cmd).decode('utf-8').strip() |
| 331 | version_number = '%s.%s' % (major_minor, args.revision) |
| 332 | logging.info('Substituting revision number: %s', version_number) |
| 333 | cmd = [ |
| 334 | 'PlistBuddy', '-c', 'Set :CFBundleVersion ' + version_number, |
| 335 | infoplist_path |
| 336 | ] |
| 337 | _RunCommand(cmd) |
| 338 | _RunCommand(['plutil', '-convert', 'binary1', infoplist_path]) |
| 339 | |
| 340 | xcframework_dir = os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME) |
| 341 | if os.path.isdir(xcframework_dir): |
| 342 | shutil.rmtree(xcframework_dir) |
| 343 | |
| 344 | logging.info('Creating xcframework.') |
| 345 | cmd = ['xcodebuild', '-create-xcframework', '-output', xcframework_dir] |
| 346 | |
| 347 | # Apparently, xcodebuild needs absolute paths for input arguments |
| 348 | for framework_path in framework_paths: |
| 349 | cmd += [ |
| 350 | '-framework', |
| 351 | os.path.abspath(os.path.join(framework_path, SDK_FRAMEWORK_NAME)), |
| 352 | ] |
| 353 | dsym_full_path = os.path.join(framework_path, SDK_DSYM_NAME) |
| 354 | if os.path.exists(dsym_full_path): |
| 355 | cmd += ['-debug-symbols', os.path.abspath(dsym_full_path)] |
| 356 | |
Byoungchan Lee | c41093b | 2021-07-06 09:52:21 | [diff] [blame] | 357 | _RunCommand(cmd) |
| 358 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 359 | # Generate the license file. |
| 360 | logging.info('Generate license file.') |
| 361 | gn_target_full_name = '//sdk:' + gn_target_name |
| 362 | builder = LicenseBuilder(all_lib_paths, [gn_target_full_name]) |
| 363 | builder.generate_license_text( |
| 364 | os.path.join(args.output_dir, SDK_XCFRAMEWORK_NAME)) |
Mirko Bonadei | 8cc6695 | 2020-10-30 09:13:45 | [diff] [blame] | 365 | |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 366 | logging.info('Done.') |
| 367 | return 0 |
oprypin | 7a2d8ca | 2017-02-06 15:53:41 | [diff] [blame] | 368 | |
| 369 | |
| 370 | if __name__ == '__main__': |
Christoffer Dewerin | 81a9117 | 2024-04-08 07:26:41 | [diff] [blame] | 371 | sys.exit(main()) |