diff options
Diffstat (limited to 'third_party/libwebrtc/build/toolchain/ios')
-rw-r--r-- | third_party/libwebrtc/build/toolchain/ios/BUILD.gn | 113 | ||||
-rw-r--r-- | third_party/libwebrtc/build/toolchain/ios/OWNERS | 1 | ||||
-rw-r--r-- | third_party/libwebrtc/build/toolchain/ios/compile_xcassets.py | 258 | ||||
-rw-r--r-- | third_party/libwebrtc/build/toolchain/ios/swiftc.py | 174 |
4 files changed, 546 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/toolchain/ios/BUILD.gn b/third_party/libwebrtc/build/toolchain/ios/BUILD.gn new file mode 100644 index 0000000000..4c9cc586d2 --- /dev/null +++ b/third_party/libwebrtc/build/toolchain/ios/BUILD.gn @@ -0,0 +1,113 @@ +# Copyright 2021 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("//build/config/ios/ios_sdk.gni") +import("//build/toolchain/apple/toolchain.gni") + +# Specialisation of the apple_toolchain template to declare the toolchain +# and its tools to build target for iOS platform. +template("ios_toolchain") { + assert(defined(invoker.toolchain_args), + "Toolchains must declare toolchain_args") + + apple_toolchain(target_name) { + forward_variables_from(invoker, "*", [ "toolchain_args" ]) + + sdk_developer_dir = ios_sdk_developer_dir + deployment_target = ios_deployment_target + sdk_name = ios_sdk_name + bin_path = ios_bin_path + strip_with_lipo = true + + toolchain_args = { + forward_variables_from(invoker.toolchain_args, "*") + current_os = "ios" + } + } +} + +ios_toolchain("ios_clang_arm64") { + toolchain_args = { + target_cpu = "arm64" + } +} + +ios_toolchain("ios_clang_arm64_13_0") { + toolchain_args = { + target_cpu = "arm64" + ios_deployment_target = "13.0" + } +} + +ios_toolchain("ios_clang_arm64_14_0") { + toolchain_args = { + target_cpu = "arm64" + ios_deployment_target = "14.0" + } +} + +ios_toolchain("ios_clang_arm64_fat_arm") { + toolchain_args = { + target_cpu = "arm" + is_fat_secondary_toolchain = true + primary_fat_toolchain_name = "//build/toolchain/ios:ios_clang_arm64" + } +} + +ios_toolchain("ios_clang_arm") { + toolchain_args = { + target_cpu = "arm" + } +} + +ios_toolchain("ios_clang_x64") { + toolchain_args = { + target_cpu = "x64" + } +} + +ios_toolchain("ios_clang_x64_fat_arm64") { + toolchain_args = { + target_cpu = "arm64" + is_fat_secondary_toolchain = true + primary_fat_toolchain_name = "//build/toolchain/ios:ios_clang_x64" + } +} + +ios_toolchain("ios_clang_x64_13_0") { + toolchain_args = { + target_cpu = "x64" + ios_deployment_target = "13.0" + } +} + +ios_toolchain("ios_clang_x64_14_0") { + toolchain_args = { + target_cpu = "x64" + ios_deployment_target = "14.0" + } +} + +ios_toolchain("ios_clang_x64_14_0_fat_arm64") { + toolchain_args = { + target_cpu = "arm64" + ios_deployment_target = "14.0" + is_fat_secondary_toolchain = true + primary_fat_toolchain_name = "//build/toolchain/ios:ios_clang_x64_14_0" + } +} + +ios_toolchain("ios_clang_x64_fat_x86") { + toolchain_args = { + target_cpu = "x86" + is_fat_secondary_toolchain = true + primary_fat_toolchain_name = "//build/toolchain/ios:ios_clang_x64" + } +} + +ios_toolchain("ios_clang_x86") { + toolchain_args = { + target_cpu = "x86" + } +} diff --git a/third_party/libwebrtc/build/toolchain/ios/OWNERS b/third_party/libwebrtc/build/toolchain/ios/OWNERS new file mode 100644 index 0000000000..6f3324f07c --- /dev/null +++ b/third_party/libwebrtc/build/toolchain/ios/OWNERS @@ -0,0 +1 @@ +file://build/apple/OWNERS diff --git a/third_party/libwebrtc/build/toolchain/ios/compile_xcassets.py b/third_party/libwebrtc/build/toolchain/ios/compile_xcassets.py new file mode 100644 index 0000000000..8b86713d14 --- /dev/null +++ b/third_party/libwebrtc/build/toolchain/ios/compile_xcassets.py @@ -0,0 +1,258 @@ +# 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. + +"""Wrapper around actool to compile assets catalog. + +The script compile_xcassets.py is a wrapper around actool to compile +assets catalog to Assets.car that turns warning into errors. It also +fixes some quirks of actool to make it work from ninja (mostly that +actool seems to require absolute path but gn generates command-line +with relative paths). + +The wrapper filter out any message that is not a section header and +not a warning or error message, and fails if filtered output is not +empty. This should to treat all warnings as error until actool has +an option to fail with non-zero error code when there are warnings. +""" + +import argparse +import os +import re +import shutil +import subprocess +import sys +import tempfile + +# Pattern matching a section header in the output of actool. +SECTION_HEADER = re.compile('^/\\* ([^ ]*) \\*/$') + +# Name of the section containing informational messages that can be ignored. +NOTICE_SECTION = 'com.apple.actool.compilation-results' + +# Map special type of asset catalog to the corresponding command-line +# parameter that need to be passed to actool. +ACTOOL_FLAG_FOR_ASSET_TYPE = { + '.appiconset': '--app-icon', + '.launchimage': '--launch-image', +} + +def FixAbsolutePathInLine(line, relative_paths): + """Fix absolute paths present in |line| to relative paths.""" + absolute_path = line.split(':')[0] + relative_path = relative_paths.get(absolute_path, absolute_path) + if absolute_path == relative_path: + return line + return relative_path + line[len(absolute_path):] + + +def FilterCompilerOutput(compiler_output, relative_paths): + """Filers actool compilation output. + + The compiler output is composed of multiple sections for each different + level of output (error, warning, notices, ...). Each section starts with + the section name on a single line, followed by all the messages from the + section. + + The function filter any lines that are not in com.apple.actool.errors or + com.apple.actool.document.warnings sections (as spurious messages comes + before any section of the output). + + See crbug.com/730054, crbug.com/739163 and crbug.com/770634 for some example + messages that pollute the output of actool and cause flaky builds. + + Args: + compiler_output: string containing the output generated by the + compiler (contains both stdout and stderr) + relative_paths: mapping from absolute to relative paths used to + convert paths in the warning and error messages (unknown paths + will be left unaltered) + + Returns: + The filtered output of the compiler. If the compilation was a + success, then the output will be empty, otherwise it will use + relative path and omit any irrelevant output. + """ + + filtered_output = [] + current_section = None + data_in_section = False + for line in compiler_output.splitlines(): + match = SECTION_HEADER.search(line) + if match is not None: + data_in_section = False + current_section = match.group(1) + continue + if current_section and current_section != NOTICE_SECTION: + if not data_in_section: + data_in_section = True + filtered_output.append('/* %s */\n' % current_section) + + fixed_line = FixAbsolutePathInLine(line, relative_paths) + filtered_output.append(fixed_line + '\n') + + return ''.join(filtered_output) + + +def CompileAssetCatalog(output, platform, product_type, min_deployment_target, + inputs, compress_pngs, partial_info_plist): + """Compile the .xcassets bundles to an asset catalog using actool. + + Args: + output: absolute path to the containing bundle + platform: the targeted platform + product_type: the bundle type + min_deployment_target: minimum deployment target + inputs: list of absolute paths to .xcassets bundles + compress_pngs: whether to enable compression of pngs + partial_info_plist: path to partial Info.plist to generate + """ + command = [ + 'xcrun', + 'actool', + '--output-format=human-readable-text', + '--notices', + '--warnings', + '--errors', + '--platform', + platform, + '--minimum-deployment-target', + min_deployment_target, + ] + + if compress_pngs: + command.extend(['--compress-pngs']) + + if product_type != '': + command.extend(['--product-type', product_type]) + + if platform == 'macosx': + command.extend(['--target-device', 'mac']) + else: + command.extend(['--target-device', 'iphone', '--target-device', 'ipad']) + + # Scan the input directories for the presence of asset catalog types that + # require special treatment, and if so, add them to the actool command-line. + for relative_path in inputs: + + if not os.path.isdir(relative_path): + continue + + for file_or_dir_name in os.listdir(relative_path): + if not os.path.isdir(os.path.join(relative_path, file_or_dir_name)): + continue + + asset_name, asset_type = os.path.splitext(file_or_dir_name) + if asset_type not in ACTOOL_FLAG_FOR_ASSET_TYPE: + continue + + command.extend([ACTOOL_FLAG_FOR_ASSET_TYPE[asset_type], asset_name]) + + # Always ask actool to generate a partial Info.plist file. If no path + # has been given by the caller, use a temporary file name. + temporary_file = None + if not partial_info_plist: + temporary_file = tempfile.NamedTemporaryFile(suffix='.plist') + partial_info_plist = temporary_file.name + + command.extend(['--output-partial-info-plist', partial_info_plist]) + + # Dictionary used to convert absolute paths back to their relative form + # in the output of actool. + relative_paths = {} + + # actool crashes if paths are relative, so convert input and output paths + # to absolute paths, and record the relative paths to fix them back when + # filtering the output. + absolute_output = os.path.abspath(output) + relative_paths[output] = absolute_output + relative_paths[os.path.dirname(output)] = os.path.dirname(absolute_output) + command.extend(['--compile', os.path.dirname(os.path.abspath(output))]) + + for relative_path in inputs: + absolute_path = os.path.abspath(relative_path) + relative_paths[absolute_path] = relative_path + command.append(absolute_path) + + try: + # Run actool and redirect stdout and stderr to the same pipe (as actool + # is confused about what should go to stderr/stdout). + process = subprocess.Popen(command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout = process.communicate()[0].decode('utf-8') + + # If the invocation of `actool` failed, copy all the compiler output to + # the standard error stream and exit. See https://crbug.com/1205775 for + # example of compilation that failed with no error message due to filter. + if process.returncode: + for line in stdout.splitlines(): + fixed_line = FixAbsolutePathInLine(line, relative_paths) + sys.stderr.write(fixed_line + '\n') + sys.exit(1) + + # Filter the output to remove all garbage and to fix the paths. If the + # output is not empty after filtering, then report the compilation as a + # failure (as some version of `actool` report error to stdout, yet exit + # with an return code of zero). + stdout = FilterCompilerOutput(stdout, relative_paths) + if stdout: + sys.stderr.write(stdout) + sys.exit(1) + + finally: + if temporary_file: + temporary_file.close() + + +def Main(): + parser = argparse.ArgumentParser( + description='compile assets catalog for a bundle') + parser.add_argument('--platform', + '-p', + required=True, + choices=('macosx', 'iphoneos', 'iphonesimulator'), + help='target platform for the compiled assets catalog') + parser.add_argument( + '--minimum-deployment-target', + '-t', + required=True, + help='minimum deployment target for the compiled assets catalog') + parser.add_argument('--output', + '-o', + required=True, + help='path to the compiled assets catalog') + parser.add_argument('--compress-pngs', + '-c', + action='store_true', + default=False, + help='recompress PNGs while compiling assets catalog') + parser.add_argument('--product-type', + '-T', + help='type of the containing bundle') + parser.add_argument('--partial-info-plist', + '-P', + help='path to partial info plist to create') + parser.add_argument('inputs', + nargs='+', + help='path to input assets catalog sources') + args = parser.parse_args() + + if os.path.basename(args.output) != 'Assets.car': + sys.stderr.write('output should be path to compiled asset catalog, not ' + 'to the containing bundle: %s\n' % (args.output, )) + sys.exit(1) + + if os.path.exists(args.output): + if os.path.isfile(args.output): + os.unlink(args.output) + else: + shutil.rmtree(args.output) + + CompileAssetCatalog(args.output, args.platform, args.product_type, + args.minimum_deployment_target, args.inputs, + args.compress_pngs, args.partial_info_plist) + + +if __name__ == '__main__': + sys.exit(Main()) diff --git a/third_party/libwebrtc/build/toolchain/ios/swiftc.py b/third_party/libwebrtc/build/toolchain/ios/swiftc.py new file mode 100644 index 0000000000..a08dc8d129 --- /dev/null +++ b/third_party/libwebrtc/build/toolchain/ios/swiftc.py @@ -0,0 +1,174 @@ +# Copyright 2020 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 argparse +import collections +import json +import os +import subprocess +import sys +import tempfile + + +class OrderedSet(collections.OrderedDict): + def add(self, value): + self[value] = True + + +def compile_module(module, sources, settings, extras, tmpdir): + output_file_map = {} + if settings.whole_module_optimization: + output_file_map[''] = { + 'object': os.path.join(settings.object_dir, module + '.o'), + 'dependencies': os.path.join(tmpdir, module + '.d'), + } + else: + for source in sources: + name, _ = os.path.splitext(os.path.basename(source)) + output_file_map[source] = { + 'object': os.path.join(settings.object_dir, name + '.o'), + 'dependencies': os.path.join(tmpdir, name + '.d'), + } + + for key in ('module_path', 'header_path', 'depfile'): + path = getattr(settings, key) + if os.path.exists(path): + os.unlink(path) + if key == 'module_path': + for ext in '.swiftdoc', '.swiftsourceinfo': + path = os.path.splitext(getattr(settings, key))[0] + ext + if os.path.exists(path): + os.unlink(path) + directory = os.path.dirname(path) + if not os.path.exists(directory): + os.makedirs(directory) + + if not os.path.exists(settings.object_dir): + os.makedirs(settings.object_dir) + + for key in output_file_map: + path = output_file_map[key]['object'] + if os.path.exists(path): + os.unlink(path) + + output_file_map_path = os.path.join(tmpdir, module + '.json') + with open(output_file_map_path, 'w') as output_file_map_file: + output_file_map_file.write(json.dumps(output_file_map)) + output_file_map_file.flush() + + extra_args = [] + if settings.bridge_header: + extra_args.extend([ + '-import-objc-header', + os.path.abspath(settings.bridge_header), + ]) + + if settings.whole_module_optimization: + extra_args.append('-whole-module-optimization') + + if settings.target: + extra_args.extend([ + '-target', + settings.target, + ]) + + if settings.sdk: + extra_args.extend([ + '-sdk', + os.path.abspath(settings.sdk), + ]) + + if settings.swift_version: + extra_args.extend([ + '-swift-version', + settings.swift_version, + ]) + + if settings.include_dirs: + for include_dir in settings.include_dirs: + extra_args.append('-I' + include_dir) + + process = subprocess.Popen([ + 'swiftc', + '-parse-as-library', + '-module-name', + module, + '-emit-object', + '-emit-dependencies', + '-emit-module', + '-emit-module-path', + settings.module_path, + '-emit-objc-header', + '-emit-objc-header-path', + settings.header_path, + '-output-file-map', + output_file_map_path, + ] + extra_args + extras + sources, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + + stdout, stderr = process.communicate() + if process.returncode: + sys.stdout.write(stdout) + sys.stderr.write(stderr) + sys.exit(process.returncode) + + depfile_content = collections.OrderedDict() + for key in output_file_map: + for line in open(output_file_map[key]['dependencies']): + output, inputs = line.split(' : ', 2) + _, ext = os.path.splitext(output) + if ext == '.o': + key = output + else: + key = os.path.splitext(settings.module_path)[0] + ext + if key not in depfile_content: + depfile_content[key] = OrderedSet() + for path in inputs.split(): + depfile_content[key].add(path) + + with open(settings.depfile, 'w') as depfile: + for key in depfile_content: + if not settings.depfile_filter or key in settings.depfile_filter: + inputs = depfile_content[key] + depfile.write('%s : %s\n' % (key, ' '.join(inputs))) + + +def main(args): + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('-module-name', help='name of the Swift module') + parser.add_argument('-include', + '-I', + action='append', + dest='include_dirs', + help='add directory to header search path') + parser.add_argument('sources', nargs='+', help='Swift source file to compile') + parser.add_argument('-whole-module-optimization', + action='store_true', + help='enable whole module optimization') + parser.add_argument('-object-dir', + help='path to the generated object files directory') + parser.add_argument('-module-path', help='path to the generated module file') + parser.add_argument('-header-path', help='path to the generated header file') + parser.add_argument('-bridge-header', + help='path to the Objective-C bridge header') + parser.add_argument('-depfile', help='path to the generated depfile') + parser.add_argument('-swift-version', + help='version of Swift language to support') + parser.add_argument('-depfile-filter', + action='append', + help='limit depfile to those files') + parser.add_argument('-target', + action='store', + help='generate code for the given target <triple>') + parser.add_argument('-sdk', action='store', help='compile against sdk') + + parsed, extras = parser.parse_known_args(args) + with tempfile.TemporaryDirectory() as tmpdir: + compile_module(parsed.module_name, parsed.sources, parsed, extras, tmpdir) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) |