diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-04 14:17:57 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-05 10:05:06 +0000 |
commit | 39d357e3248f80abea0159765ff39554affb40db (patch) | |
tree | aba0e6bfb76de0244bba0f5fdbd64b830dd6e621 /chromium/build/android/gyp/dex.py | |
parent | 87778abf5a1f89266f37d1321b92a21851d8244d (diff) |
BASELINE: Update Chromium to 55.0.2883.105
And updates ninja to 1.7.2
Change-Id: I20d43c737f82764d857ada9a55586901b18b9243
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/build/android/gyp/dex.py')
-rwxr-xr-x | chromium/build/android/gyp/dex.py | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/chromium/build/android/gyp/dex.py b/chromium/build/android/gyp/dex.py new file mode 100755 index 00000000000..87e9b06bcd8 --- /dev/null +++ b/chromium/build/android/gyp/dex.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python +# +# Copyright 2013 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 json +import logging +import optparse +import os +import sys +import tempfile +import zipfile + +from util import build_utils + + +def _CheckFilePathEndsWithJar(parser, file_path): + if not file_path.endswith(".jar"): + # dx ignores non .jar files. + parser.error("%s does not end in .jar" % file_path) + + +def _CheckFilePathsEndWithJar(parser, file_paths): + for file_path in file_paths: + _CheckFilePathEndsWithJar(parser, file_path) + + +def _RemoveUnwantedFilesFromZip(dex_path): + iz = zipfile.ZipFile(dex_path, 'r') + tmp_dex_path = '%s.tmp.zip' % dex_path + oz = zipfile.ZipFile(tmp_dex_path, 'w', zipfile.ZIP_DEFLATED) + for i in iz.namelist(): + if i.endswith('.dex'): + oz.writestr(i, iz.read(i)) + os.remove(dex_path) + os.rename(tmp_dex_path, dex_path) + + +def _ParseArgs(args): + args = build_utils.ExpandFileArgs(args) + + parser = optparse.OptionParser() + build_utils.AddDepfileOption(parser) + + parser.add_option('--android-sdk-tools', + help='Android sdk build tools directory.') + parser.add_option('--output-directory', + default=os.getcwd(), + help='Path to the output build directory.') + parser.add_option('--dex-path', help='Dex output path.') + parser.add_option('--configuration-name', + help='The build CONFIGURATION_NAME.') + parser.add_option('--proguard-enabled', + help='"true" if proguard is enabled.') + parser.add_option('--debug-build-proguard-enabled', + help='"true" if proguard is enabled for debug build.') + parser.add_option('--proguard-enabled-input-path', + help=('Path to dex in Release mode when proguard ' + 'is enabled.')) + parser.add_option('--no-locals', default='0', + help='Exclude locals list from the dex file.') + parser.add_option('--incremental', + action='store_true', + help='Enable incremental builds when possible.') + parser.add_option('--inputs', help='A list of additional input paths.') + parser.add_option('--excluded-paths', + help='A list of paths to exclude from the dex file.') + parser.add_option('--main-dex-list-path', + help='A file containing a list of the classes to ' + 'include in the main dex.') + parser.add_option('--multidex-configuration-path', + help='A JSON file containing multidex build configuration.') + parser.add_option('--multi-dex', default=False, action='store_true', + help='Generate multiple dex files.') + + options, paths = parser.parse_args(args) + + required_options = ('android_sdk_tools',) + build_utils.CheckOptions(options, parser, required=required_options) + + if options.multidex_configuration_path: + with open(options.multidex_configuration_path) as multidex_config_file: + multidex_config = json.loads(multidex_config_file.read()) + options.multi_dex = multidex_config.get('enabled', False) + + if options.multi_dex and not options.main_dex_list_path: + logging.warning('multidex cannot be enabled without --main-dex-list-path') + options.multi_dex = False + elif options.main_dex_list_path and not options.multi_dex: + logging.warning('--main-dex-list-path is unused if multidex is not enabled') + + if options.inputs: + options.inputs = build_utils.ParseGnList(options.inputs) + _CheckFilePathsEndWithJar(parser, options.inputs) + if options.excluded_paths: + options.excluded_paths = build_utils.ParseGnList(options.excluded_paths) + + if options.proguard_enabled_input_path: + _CheckFilePathEndsWithJar(parser, options.proguard_enabled_input_path) + _CheckFilePathsEndWithJar(parser, paths) + + return options, paths + + +def _AllSubpathsAreClassFiles(paths, changes): + for path in paths: + if any(not p.endswith('.class') for p in changes.IterChangedSubpaths(path)): + return False + return True + + +def _DexWasEmpty(paths, changes): + for path in paths: + if any(p.endswith('.class') + for p in changes.old_metadata.IterSubpaths(path)): + return False + return True + + +def _IterAllClassFiles(changes): + for path in changes.IterAllPaths(): + for subpath in changes.IterAllSubpaths(path): + if subpath.endswith('.class'): + yield path + + +def _MightHitDxBug(changes): + # We've seen dx --incremental fail for small libraries. It's unlikely a + # speed-up anyways in this case. + num_classes = sum(1 for x in _IterAllClassFiles(changes)) + if num_classes < 10: + return True + + # We've also been able to consistently produce a failure by adding an empty + # line to the top of the first .java file of a library. + # https://crbug.com/617935 + first_file = next(_IterAllClassFiles(changes)) + for path in changes.IterChangedPaths(): + for subpath in changes.IterChangedSubpaths(path): + if first_file == subpath: + return True + return False + + +def _RunDx(changes, options, dex_cmd, paths): + with build_utils.TempDir() as classes_temp_dir: + # --multi-dex is incompatible with --incremental. + if options.multi_dex: + dex_cmd.append('--main-dex-list=%s' % options.main_dex_list_path) + else: + # --incremental tells dx to merge all newly dex'ed .class files with + # what that already exist in the output dex file (existing classes are + # replaced). + # Use --incremental when .class files are added or modified, but not when + # any are removed (since it won't know to remove them). + if (options.incremental + and not _MightHitDxBug(changes) + and changes.AddedOrModifiedOnly()): + changed_inputs = set(changes.IterChangedPaths()) + changed_paths = [p for p in paths if p in changed_inputs] + if not changed_paths: + return + # When merging in other dex files, there's no easy way to know if + # classes were removed from them. + if (_AllSubpathsAreClassFiles(changed_paths, changes) + and not _DexWasEmpty(changed_paths, changes)): + dex_cmd.append('--incremental') + for path in changed_paths: + changed_subpaths = set(changes.IterChangedSubpaths(path)) + # Note: |changed_subpaths| may be empty if nothing changed. + if changed_subpaths: + build_utils.ExtractAll(path, path=classes_temp_dir, + predicate=lambda p: p in changed_subpaths) + paths = [classes_temp_dir] + + dex_cmd += paths + build_utils.CheckOutput(dex_cmd, print_stderr=False) + + if options.dex_path.endswith('.zip'): + _RemoveUnwantedFilesFromZip(options.dex_path) + + +def _OnStaleMd5(changes, options, dex_cmd, paths): + _RunDx(changes, options, dex_cmd, paths) + build_utils.WriteJson( + [os.path.relpath(p, options.output_directory) for p in paths], + options.dex_path + '.inputs') + + +def main(args): + options, paths = _ParseArgs(args) + if ((options.proguard_enabled == 'true' + and options.configuration_name == 'Release') + or (options.debug_build_proguard_enabled == 'true' + and options.configuration_name == 'Debug')): + paths = [options.proguard_enabled_input_path] + + if options.inputs: + paths += options.inputs + + if options.excluded_paths: + # Excluded paths are relative to the output directory. + exclude_paths = options.excluded_paths + paths = [p for p in paths if not + os.path.relpath(p, options.output_directory) in exclude_paths] + + input_paths = list(paths) + + dx_binary = os.path.join(options.android_sdk_tools, 'dx') + # See http://crbug.com/272064 for context on --force-jumbo. + # See https://github.com/android/platform_dalvik/commit/dd140a22d for + # --num-threads. + dex_cmd = [dx_binary, '--num-threads=8', '--dex', '--force-jumbo', + '--output', options.dex_path] + if options.no_locals != '0': + dex_cmd.append('--no-locals') + + if options.multi_dex: + input_paths.append(options.main_dex_list_path) + dex_cmd += [ + '--multi-dex', + '--minimal-main-dex', + ] + + output_paths = [ + options.dex_path, + options.dex_path + '.inputs', + ] + + # An escape hatch to be able to check if incremental dexing is causing + # problems. + force = int(os.environ.get('DISABLE_INCREMENTAL_DX', 0)) + + build_utils.CallAndWriteDepfileIfStale( + lambda changes: _OnStaleMd5(changes, options, dex_cmd, paths), + options, + input_paths=input_paths, + input_strings=dex_cmd, + output_paths=output_paths, + force=force, + pass_changes=True) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) |