summaryrefslogtreecommitdiff
path: root/deps/v8/build/toolchain/mac/compile_xcassets.py
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/build/toolchain/mac/compile_xcassets.py')
-rw-r--r--deps/v8/build/toolchain/mac/compile_xcassets.py251
1 files changed, 251 insertions, 0 deletions
diff --git a/deps/v8/build/toolchain/mac/compile_xcassets.py b/deps/v8/build/toolchain/mac/compile_xcassets.py
new file mode 100644
index 0000000000..c1f4680b7c
--- /dev/null
+++ b/deps/v8/build/toolchain/mac/compile_xcassets.py
@@ -0,0 +1,251 @@
+# 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.
+
+import argparse
+import os
+import re
+import subprocess
+import sys
+import tempfile
+
+"""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.
+"""
+
+# 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'
+
+# Regular expressions matching spurious messages from actool that should be
+# ignored (as they are bogus). Generally a bug should be filed with Apple
+# when adding a pattern here.
+SPURIOUS_PATTERNS = map(re.compile, [
+ # crbug.com/770634, likely a bug in Xcode 9.1 beta, remove once build
+ # requires a version of Xcode with a fix.
+ r'\[\]\[ipad\]\[76x76\]\[\]\[\]\[1x\]\[\]\[\]: notice: \(null\)',
+
+ # crbug.com/770634, likely a bug in Xcode 9.2 beta, remove once build
+ # requires a version of Xcode with a fix.
+ r'\[\]\[ipad\]\[76x76\]\[\]\[\]\[1x\]\[\]\[\]: notice: 76x76@1x app icons'
+ ' only apply to iPad apps targeting releases of iOS prior to 10.0.',
+])
+
+# 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 IsSpuriousMessage(line):
+ """Returns whether line contains a spurious message that should be ignored."""
+ for pattern in SPURIOUS_PATTERNS:
+ match = pattern.search(line)
+ if match is not None:
+ return True
+ return False
+
+
+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 IsSpuriousMessage(line):
+ continue
+ absolute_path = line.split(':')[0]
+ relative_path = relative_paths.get(absolute_path, absolute_path)
+ if absolute_path != relative_path:
+ line = relative_path + line[len(absolute_path):]
+ if not data_in_section:
+ data_in_section = True
+ filtered_output.append('/* %s */\n' % current_section)
+ filtered_output.append(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 not 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()
+
+ # Filter the output to remove all garbarge and to fix the paths.
+ stdout = FilterCompilerOutput(stdout, relative_paths)
+
+ if process.returncode or 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)
+
+ 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())