diff options
author | jbudorick <jbudorick@chromium.org> | 2015-11-12 16:44:58 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-13 00:45:41 +0000 |
commit | f667d3b3a1b953800bb5325c7b8d62775a1c5aeb (patch) | |
tree | 2e5615b25b452bc7ec6aa7e39076f8648ec305df /build | |
parent | f7e988ff06ac6ca527bc907410e1f6292534de89 (diff) | |
download | chromium_src-f667d3b3a1b953800bb5325c7b8d62775a1c5aeb.zip chromium_src-f667d3b3a1b953800bb5325c7b8d62775a1c5aeb.tar.gz chromium_src-f667d3b3a1b953800bb5325c7b8d62775a1c5aeb.tar.bz2 |
[Android] Enable multidex for debug builds of ChromePublic.
This is a non-incremental implementation. It adds @MainDex to classes used by
the renderer to keep them in the main dex, as it can't load secondary dexes
when using the multidex support library (i.e., on K and below).
BUG=272790
TBR=newt@chromium.org,sky@chromium.org
Review URL: https://codereview.chromium.org/1408163009
Cr-Commit-Position: refs/heads/master@{#359453}
Diffstat (limited to 'build')
-rwxr-xr-x | build/android/gyp/apk_obfuscate.py | 46 | ||||
-rwxr-xr-x | build/android/gyp/configure_multidex.py | 55 | ||||
-rwxr-xr-x | build/android/gyp/dex.py | 42 | ||||
-rwxr-xr-x | build/android/gyp/main_dex_list.py | 18 | ||||
-rw-r--r-- | build/android/java_cpp_template.gypi | 2 | ||||
-rw-r--r-- | build/android/main_dex_action.gypi | 6 | ||||
-rw-r--r-- | build/android/main_dex_classes.flags | 4 | ||||
-rw-r--r-- | build/android/push_libraries.gypi | 2 | ||||
-rw-r--r-- | build/java.gypi | 10 | ||||
-rw-r--r-- | build/java_apk.gypi | 73 |
10 files changed, 200 insertions, 58 deletions
diff --git a/build/android/gyp/apk_obfuscate.py b/build/android/gyp/apk_obfuscate.py index a227945..4a13cb1 100755 --- a/build/android/gyp/apk_obfuscate.py +++ b/build/android/gyp/apk_obfuscate.py @@ -10,14 +10,22 @@ If proguard is not enabled or 'Release' is not in the configuration name, obfuscation will be a no-op. """ +import json import optparse import os import sys +import tempfile from util import build_utils from util import proguard_util +_PROGUARD_KEEP_CLASS = '''-keep class %s { + *; +} +''' + + def ParseArgs(argv): parser = optparse.OptionParser() parser.add_option('--android-sdk', help='path to the Android SDK folder') @@ -56,6 +64,12 @@ def ParseArgs(argv): parser.add_option('--stamp', help='File to touch on success') + parser.add_option('--main-dex-list-path', + help='The list of classes to retain in the main dex. ' + 'These will not be obfuscated.') + parser.add_option('--multidex-configuration-path', + help='A JSON file containing multidex build configuration.') + (options, args) = parser.parse_args(argv) if args: @@ -98,11 +112,41 @@ def DoProguard(options): proguard.libraryjars([options.android_sdk_jar]) proguard_injars = [p for p in input_jars if p not in exclude_paths] proguard.injars(proguard_injars) - proguard.configs(configs) + multidex_config = _PossibleMultidexConfig(options) + if multidex_config: + configs.append(multidex_config) + + proguard.configs(configs) proguard.CheckOutput() +def _PossibleMultidexConfig(options): + if not options.multidex_configuration_path: + return None + + with open(options.multidex_configuration_path) as multidex_config_file: + multidex_config = json.loads(multidex_config_file.read()) + + if not (multidex_config.get('enabled') and options.main_dex_list_path): + return None + + main_dex_list_config = '' + with open(options.main_dex_list_path) as main_dex_list: + for clazz in (l.strip() for l in main_dex_list): + if clazz.endswith('.class'): + clazz = clazz[:-len('.class')] + clazz = clazz.replace('/', '.') + main_dex_list_config += (_PROGUARD_KEEP_CLASS % clazz) + with tempfile.NamedTemporaryFile( + delete=False, + dir=os.path.dirname(options.main_dex_list_path), + prefix='main_dex_list_proguard', + suffix='.flags') as main_dex_config_file: + main_dex_config_file.write(main_dex_list_config) + return main_dex_config_file.name + + def main(argv): options, _ = ParseArgs(argv) diff --git a/build/android/gyp/configure_multidex.py b/build/android/gyp/configure_multidex.py new file mode 100755 index 0000000..aa85d2f --- /dev/null +++ b/build/android/gyp/configure_multidex.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# Copyright 2015 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 json +import sys + +from util import build_utils + + +def ParseArgs(): + parser = argparse.ArgumentParser() + parser.add_argument('--configuration-name', required=True, + help='The build CONFIGURATION_NAME.') + parser.add_argument('--enabled-configurations', default=[], + help='The configuration(s) for which multidex should be ' + 'enabled. If not specified and --enable-multidex is ' + 'passed, multidex will be enabled for all ' + 'configurations.') + parser.add_argument('--multidex-configuration-path', required=True, + help='The path to which the multidex configuration JSON ' + 'should be saved.') + + args = parser.parse_args() + + if args.enabled_configurations: + args.enabled_configurations = build_utils.ParseGypList( + args.enabled_configurations) + + return args + + +def main(): + args = ParseArgs() + + multidex_enabled = ( + (not args.enabled_configurations + or args.configuration_name in args.enabled_configurations)) + + config = { + 'enabled': multidex_enabled, + } + + with open(args.multidex_configuration_path, 'w') as f: + f.write(json.dumps(config)) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) + diff --git a/build/android/gyp/dex.py b/build/android/gyp/dex.py index 67f43e9..2fef369 100755 --- a/build/android/gyp/dex.py +++ b/build/android/gyp/dex.py @@ -4,6 +4,7 @@ # 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 @@ -14,14 +15,6 @@ import zipfile from util import build_utils -def _CreateCombinedMainDexList(main_dex_list_paths): - main_dex_list = [] - for m in main_dex_list_paths: - with open(m) as main_dex_list_file: - main_dex_list.extend(l for l in main_dex_list_file if l) - return '\n'.join(main_dex_list) - - def _RemoveUnwantedFilesFromZip(dex_path): iz = zipfile.ZipFile(dex_path, 'r') tmp_dex_path = '%s.tmp.zip' % dex_path @@ -56,32 +49,35 @@ def _ParseArgs(args): 'is enabled.')) parser.add_option('--no-locals', help='Exclude locals list from the dex file.') - parser.add_option('--multi-dex', default=False, action='store_true', - help='Create multiple dex files.') 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-paths', - help='A list of paths containing a list of the classes to ' + 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.') options, paths = parser.parse_args(args) required_options = ('android_sdk_tools',) build_utils.CheckOptions(options, parser, required=required_options) - if options.multi_dex and not options.main_dex_list_paths: - logging.warning('--multi-dex is unused without --main-dex-list-paths') + options.multi_dex = False + 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_paths and not options.multi_dex: - logging.warning('--main-dex-list-paths is unused without --multi-dex') + 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.main_dex_list_paths: - options.main_dex_list_paths = build_utils.ParseGypList( - options.main_dex_list_paths) if options.inputs: options.inputs = build_utils.ParseGypList(options.inputs) if options.excluded_paths: @@ -101,11 +97,7 @@ 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: - combined_main_dex_list = tempfile.NamedTemporaryFile(suffix='.txt') - combined_main_dex_list.write( - _CreateCombinedMainDexList(options.main_dex_list_paths)) - combined_main_dex_list.flush() - dex_cmd.append('--main-dex-list=%s' % combined_main_dex_list.name) + dex_cmd.append('--main-dex-list=%s' % options.main_dex_list_path) else: # Use --incremental when .class files are added or modified (never when # removed). @@ -173,7 +165,7 @@ def main(args): dex_cmd.append('--no-locals') if options.multi_dex: - input_paths.extend(options.main_dex_list_paths) + input_paths.append(options.main_dex_list_path) dex_cmd += [ '--multi-dex', '--minimal-main-dex', diff --git a/build/android/gyp/main_dex_list.py b/build/android/gyp/main_dex_list.py index 6442001..7f29bfb 100755 --- a/build/android/gyp/main_dex_list.py +++ b/build/android/gyp/main_dex_list.py @@ -5,6 +5,7 @@ # found in the LICENSE file. import argparse +import json import os import sys import tempfile @@ -27,12 +28,27 @@ def main(): 'main dex.') parser.add_argument('--main-dex-list-path', required=True, help='The main dex list file to generate.') + parser.add_argument('--enabled-configurations', + help='The build configurations for which a main dex list' + ' should be generated.') + parser.add_argument('--configuration-name', + help='The current build configuration.') + parser.add_argument('--multidex-configuration-path', + help='A JSON file containing multidex build ' + 'configuration.') parser.add_argument('paths', nargs='+', help='JARs for which a main dex list should be ' 'generated.') args = parser.parse_args() + if args.multidex_configuration_path: + with open(args.multidex_configuration_path) as multidex_config_file: + multidex_config = json.loads(multidex_config_file.read()) + + if not multidex_config.get('enabled', False): + return 0 + with open(args.main_dex_list_path, 'w') as main_dex_list_file: shrinked_android_jar = os.path.abspath( @@ -58,7 +74,7 @@ def main(): main_dex_list = '' try: - build_utils.CheckOutput(proguard_cmd) + build_utils.CheckOutput(proguard_cmd, print_stderr=False) java_cmd = [ 'java', '-cp', dx_jar, diff --git a/build/android/java_cpp_template.gypi b/build/android/java_cpp_template.gypi index 3296659..f4ea0a9 100644 --- a/build/android/java_cpp_template.gypi +++ b/build/android/java_cpp_template.gypi @@ -34,6 +34,7 @@ { # Location where all generated Java sources will be placed. 'variables': { + 'additional_gcc_preprocess_options': [], 'include_path%': '<(DEPTH)', 'output_dir': '<(SHARED_INTERMEDIATE_DIR)/templates/<(_target_name)/<(package_name)', }, @@ -74,6 +75,7 @@ '--include-path=<(include_path)', '--output=<(output_path)', '--template=<(RULE_INPUT_PATH)', + '<@(additional_gcc_preprocess_options)', ], 'message': 'Generating Java from cpp template <(RULE_INPUT_PATH)', } diff --git a/build/android/main_dex_action.gypi b/build/android/main_dex_action.gypi index 06717dd..7316ae2 100644 --- a/build/android/main_dex_action.gypi +++ b/build/android/main_dex_action.gypi @@ -21,7 +21,7 @@ { 'message': 'Generating main dex classes list for <(jar_path)', 'variables': { - 'jar_path%': '', + 'jar_paths%': [], 'output_path%': '', 'main_dex_list_script': '<(DEPTH)/build/android/gyp/main_dex_list.py', 'main_dex_rules_path': '<(DEPTH)/build/android/main_dex_classes.flags', @@ -30,6 +30,7 @@ '<(jar_path)', '<(main_dex_list_script)', '<(main_dex_rules_path)', + '<(multidex_configuration_path)', ], 'outputs': [ '<(output_path)', @@ -39,6 +40,7 @@ '--main-dex-list-path', '<(output_path)', '--android-sdk-tools', '<(android_sdk_tools)', '--main-dex-rules-path', '<(main_dex_rules_path)', - '<(jar_path)', + '--multidex-configuration-path', '<(multidex_configuration_path)', + '<@(jar_paths)', ] } diff --git a/build/android/main_dex_classes.flags b/build/android/main_dex_classes.flags index d9689b2..a8d969a 100644 --- a/build/android/main_dex_classes.flags +++ b/build/android/main_dex_classes.flags @@ -1,3 +1,7 @@ -keep @**.MainDex class * { *; } + +-keepclasseswithmembers class * { + public static ** asInterface(android.os.IBinder); +} diff --git a/build/android/push_libraries.gypi b/build/android/push_libraries.gypi index 773c44f..a4a6fcd 100644 --- a/build/android/push_libraries.gypi +++ b/build/android/push_libraries.gypi @@ -44,6 +44,6 @@ '--device-dir=<(device_library_dir)', '--libraries=@FileArg(<(ordered_libraries_file):libraries)', '--stamp=<(push_stamp)', - '--configuration-name=<(configuration_name)', + '--configuration-name=<(CONFIGURATION_NAME)', ], } diff --git a/build/java.gypi b/build/java.gypi index 6f55c1b..9bc1f4b 100644 --- a/build/java.gypi +++ b/build/java.gypi @@ -65,7 +65,6 @@ 'additional_input_paths': [], 'additional_locale_input_paths': [], 'dex_path': '<(PRODUCT_DIR)/lib.java/<(_target_name).dex.jar', - 'main_dex_list_path': '<(intermediate_dir)/main_dex_list.txt', 'generated_src_dirs': ['>@(generated_R_dirs)'], 'generated_R_dirs': [], 'has_java_resources%': 0, @@ -120,7 +119,6 @@ 'variables': { 'input_jars_paths': ['<(jar_final_path)'], 'library_dexed_jars_paths': ['<(dex_path)'], - 'main_dex_list_paths': ['<(main_dex_list_path)'], }, }, }], @@ -327,14 +325,6 @@ ] }, { - 'action_name': 'main_dex_list_for_<(_target_name)', - 'variables': { - 'jar_path': '<(javac_jar_path)', - 'output_path': '<(main_dex_list_path)', - }, - 'includes': [ 'android/main_dex_action.gypi' ], - }, - { 'action_name': 'emma_instr_jar_<(_target_name)', 'message': 'Instrumenting <(_target_name) jar', 'variables': { diff --git a/build/java_apk.gypi b/build/java_apk.gypi index 174ec4d..6b0023e 100644 --- a/build/java_apk.gypi +++ b/build/java_apk.gypi @@ -84,8 +84,6 @@ 'library_jars_paths': [], 'input_jars_paths': [], 'library_dexed_jars_paths': [], - 'main_dex_list_path': '<(intermediate_dir)/main_dex_list.txt', - 'main_dex_list_paths': ['<(main_dex_list_path)'], 'additional_src_dirs': [], 'generated_src_dirs': [], 'app_manifest_version_name%': '<(android_app_version_name)', @@ -146,6 +144,9 @@ 'obfuscated_jar_path': '<(intermediate_dir)/obfuscated.jar', 'test_jar_path': '<(PRODUCT_DIR)/test.lib.java/<(apk_name).jar', 'enable_multidex%': 0, + 'enable_multidex_configurations%': [], + 'multidex_configuration_path': '<(intermediate_dir)/multidex_config.json', + 'main_dex_list_path': '<(intermediate_dir)/main_dex_list.txt', 'emma_device_jar': '<(android_sdk_root)/tools/lib/emma_device.jar', 'android_manifest_path%': '<(java_in_dir)/AndroidManifest.xml', 'split_android_manifest_path': '<(intermediate_dir)/split-manifests/<(android_app_abi)/AndroidManifest.xml', @@ -509,7 +510,6 @@ 'libraries_top_dir': '<(intermediate_dir)/lib.stripped', 'libraries_source_dir': '<(libraries_top_dir)/lib/<(android_app_abi)', 'device_library_dir': '<(device_intermediate_dir)/lib.stripped', - 'configuration_name': '<(CONFIGURATION_NAME)', }, 'dependencies': [ '<(DEPTH)/build/android/setup.gyp:get_build_device_configurations', @@ -747,7 +747,7 @@ 'dependencies': [ '<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands', '<(DEPTH)/tools/android/android_tools.gyp:android_tools', - ] + ], }], ['run_findbugs == 1', { 'actions': [ @@ -786,6 +786,38 @@ }, ], }], + ['enable_multidex == 1', { + 'actions': [ + { + 'action_name': 'main_dex_list_for_<(_target_name)', + 'variables': { + 'jar_paths': ['>@(input_jars_paths)', '<(javac_jar_path)'], + 'output_path': '<(main_dex_list_path)', + }, + 'includes': [ 'android/main_dex_action.gypi' ], + }, + { + 'action_name': 'configure_multidex_for_<(_target_name)', + 'inputs': [ + '<(DEPTH)/build/android/gyp/configure_multidex.py', + ], + 'outputs': [ + '<(multidex_configuration_path)', + ], + 'variables': { + 'additional_multidex_config_options': [], + 'enabled_configurations': ['>@(enable_multidex_configurations)'], + }, + 'action': [ + 'python', '<(DEPTH)/build/android/gyp/configure_multidex.py', + '--configuration-name', '<(CONFIGURATION_NAME)', + '--enabled-configurations', '<(enabled_configurations)', + '--multidex-configuration-path', '<(multidex_configuration_path)', + '>@(additional_multidex_config_options)', + ], + }, + ], + }], ], 'dependencies': [ '<(DEPTH)/tools/android/md5sum/md5sum.gyp:md5sum', @@ -935,14 +967,6 @@ ], }, { - 'action_name': 'main_dex_list_for_<(_target_name)', - 'variables': { - 'jar_path': '<(javac_jar_path)', - 'output_path': '<(main_dex_list_path)', - }, - 'includes': [ 'android/main_dex_action.gypi' ], - }, - { 'action_name': 'emma_instr_jar_<(_target_name)', 'message': 'Instrumenting <(_target_name) jar', 'variables': { @@ -1023,6 +1047,18 @@ '<(test_jar_path)', ], }], + ['enable_multidex == 1', { + 'inputs': [ + '<(main_dex_list_path)', + '<(multidex_configuration_path)', + ], + 'variables': { + 'additional_obfuscate_options': [ + '--main-dex-list-path', '<(main_dex_list_path)', + '--multidex-configuration-path', '<(multidex_configuration_path)', + ], + }, + }], ], 'inputs': [ '<(DEPTH)/build/android/gyp/apk_obfuscate.py', @@ -1077,16 +1113,17 @@ }, 'conditions': [ ['enable_multidex == 1', { + 'inputs': [ + '<(main_dex_list_path)', + '<(multidex_configuration_path)', + ], 'variables': { 'dex_additional_options': [ - '--multi-dex', - '--main-dex-list-paths', '>@(main_dex_list_paths)', + '--main-dex-list-path', '<(main_dex_list_path)' + '--multidex-configuration-path', '<(multidex_configuration_path)', ], }, - 'inputs': [ - '>@(main_dex_list_paths)', - ], - }] + }], ], 'target_conditions': [ ['enable_multidex == 1 or tested_apk_is_multidex == 1', { |