| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2015 The Chromium Authors. All rights reserved. | 3 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 import argparse | 7 import argparse |
| 8 import json | 8 import json |
| 9 import os | 9 import os |
| 10 import sys | 10 import sys |
| 11 import tempfile | 11 import tempfile |
| 12 | 12 |
| 13 from util import build_utils | 13 from util import build_utils |
| 14 | 14 |
| 15 sys.path.append(os.path.abspath(os.path.join( | 15 sys.path.append(os.path.abspath(os.path.join( |
| 16 os.path.dirname(__file__), os.pardir))) | 16 os.path.dirname(__file__), os.pardir))) |
| 17 from pylib import constants | 17 from pylib import constants |
| 18 | 18 |
| 19 | 19 |
| 20 def main(): | 20 def main(args): |
| 21 parser = argparse.ArgumentParser() | 21 parser = argparse.ArgumentParser() |
| 22 build_utils.AddDepfileOption(parser) |
| 22 parser.add_argument('--android-sdk-tools', required=True, | 23 parser.add_argument('--android-sdk-tools', required=True, |
| 23 help='Android sdk build tools directory.') | 24 help='Android sdk build tools directory.') |
| 24 parser.add_argument('--main-dex-rules-path', action='append', default=[], | 25 parser.add_argument('--main-dex-rules-path', action='append', default=[], |
| 25 dest='main_dex_rules_paths', | 26 dest='main_dex_rules_paths', |
| 26 help='A file containing a list of proguard rules to use ' | 27 help='A file containing a list of proguard rules to use ' |
| 27 'in determining the class to include in the ' | 28 'in determining the class to include in the ' |
| 28 'main dex.') | 29 'main dex.') |
| 29 parser.add_argument('--main-dex-list-path', required=True, | 30 parser.add_argument('--main-dex-list-path', required=True, |
| 30 help='The main dex list file to generate.') | 31 help='The main dex list file to generate.') |
| 31 parser.add_argument('--enabled-configurations', | 32 parser.add_argument('--enabled-configurations', |
| 32 help='The build configurations for which a main dex list' | 33 help='The build configurations for which a main dex list' |
| 33 ' should be generated.') | 34 ' should be generated.') |
| 34 parser.add_argument('--configuration-name', | 35 parser.add_argument('--configuration-name', |
| 35 help='The current build configuration.') | 36 help='The current build configuration.') |
| 36 parser.add_argument('--multidex-configuration-path', | 37 parser.add_argument('--multidex-configuration-path', |
| 37 help='A JSON file containing multidex build ' | 38 help='A JSON file containing multidex build ' |
| 38 'configuration.') | 39 'configuration.') |
| 39 parser.add_argument('paths', nargs='+', | 40 parser.add_argument('--inputs', |
| 41 help='JARs for which a main dex list should be ' |
| 42 'generated.') |
| 43 parser.add_argument('paths', nargs='*', default=[], |
| 40 help='JARs for which a main dex list should be ' | 44 help='JARs for which a main dex list should be ' |
| 41 'generated.') | 45 'generated.') |
| 42 | 46 |
| 43 args = parser.parse_args() | 47 args = parser.parse_args(build_utils.ExpandFileArgs(args)) |
| 44 | 48 |
| 45 if args.multidex_configuration_path: | 49 if args.multidex_configuration_path: |
| 46 with open(args.multidex_configuration_path) as multidex_config_file: | 50 with open(args.multidex_configuration_path) as multidex_config_file: |
| 47 multidex_config = json.loads(multidex_config_file.read()) | 51 multidex_config = json.loads(multidex_config_file.read()) |
| 48 | 52 |
| 49 if not multidex_config.get('enabled', False): | 53 if not multidex_config.get('enabled', False): |
| 50 return 0 | 54 return 0 |
| 51 | 55 |
| 52 with open(args.main_dex_list_path, 'w') as main_dex_list_file: | 56 if args.inputs: |
| 57 args.paths.extend(build_utils.ParseGypList(args.inputs)) |
| 53 | 58 |
| 54 shrinked_android_jar = os.path.abspath( | 59 shrinked_android_jar = os.path.abspath( |
| 55 os.path.join(args.android_sdk_tools, 'lib', 'shrinkedAndroid.jar')) | 60 os.path.join(args.android_sdk_tools, 'lib', 'shrinkedAndroid.jar')) |
| 56 dx_jar = os.path.abspath( | 61 dx_jar = os.path.abspath( |
| 57 os.path.join(args.android_sdk_tools, 'lib', 'dx.jar')) | 62 os.path.join(args.android_sdk_tools, 'lib', 'dx.jar')) |
| 58 paths_arg = ':'.join(args.paths) | 63 rules_file = os.path.abspath( |
| 59 rules_file = os.path.abspath( | 64 os.path.join(args.android_sdk_tools, 'mainDexClasses.rules')) |
| 60 os.path.join(args.android_sdk_tools, 'mainDexClasses.rules')) | |
| 61 | 65 |
| 62 with tempfile.NamedTemporaryFile(suffix='.jar') as temp_jar: | 66 proguard_cmd = [ |
| 63 proguard_cmd = [ | 67 constants.PROGUARD_SCRIPT_PATH, |
| 64 constants.PROGUARD_SCRIPT_PATH, | 68 '-forceprocessing', |
| 65 '-forceprocessing', | 69 '-dontwarn', '-dontoptimize', '-dontobfuscate', '-dontpreverify', |
| 66 '-dontwarn', '-dontoptimize', '-dontobfuscate', '-dontpreverify', | 70 '-libraryjars', shrinked_android_jar, |
| 67 '-injars', paths_arg, | 71 '-include', rules_file, |
| 68 '-outjars', temp_jar.name, | 72 ] |
| 69 '-libraryjars', shrinked_android_jar, | 73 for m in args.main_dex_rules_paths: |
| 70 '-include', rules_file, | 74 proguard_cmd.extend(['-include', m]) |
| 71 ] | |
| 72 for m in args.main_dex_rules_paths: | |
| 73 proguard_cmd.extend(['-include', m]) | |
| 74 | 75 |
| 75 main_dex_list = '' | 76 main_dex_list_cmd = [ |
| 76 try: | 77 'java', '-cp', dx_jar, |
| 77 build_utils.CheckOutput(proguard_cmd, print_stderr=False) | 78 'com.android.multidex.MainDexListBuilder', |
| 79 ] |
| 78 | 80 |
| 79 java_cmd = [ | 81 input_paths = list(args.paths) |
| 80 'java', '-cp', dx_jar, | 82 input_paths += [ |
| 81 'com.android.multidex.MainDexListBuilder', | 83 shrinked_android_jar, |
| 82 temp_jar.name, paths_arg | 84 dx_jar, |
| 83 ] | 85 rules_file, |
| 84 main_dex_list = build_utils.CheckOutput(java_cmd) | 86 ] |
| 85 except build_utils.CalledProcessError as e: | 87 input_paths += args.main_dex_rules_paths |
| 86 if 'output jar is empty' in e.output: | |
| 87 pass | |
| 88 elif "input doesn't contain any classes" in e.output: | |
| 89 pass | |
| 90 else: | |
| 91 raise | |
| 92 | 88 |
| 93 main_dex_list_file.write(main_dex_list) | 89 input_strings = [ |
| 90 proguard_cmd, |
| 91 main_dex_list_cmd, |
| 92 ] |
| 93 |
| 94 output_paths = [ |
| 95 args.main_dex_list_path, |
| 96 ] |
| 97 |
| 98 build_utils.CallAndWriteDepfileIfStale( |
| 99 lambda: _OnStaleMd5(proguard_cmd, main_dex_list_cmd, args.paths, |
| 100 args.main_dex_list_path), |
| 101 args, |
| 102 input_paths=input_paths, |
| 103 input_strings=input_strings, |
| 104 output_paths=output_paths) |
| 94 | 105 |
| 95 return 0 | 106 return 0 |
| 96 | 107 |
| 97 | 108 |
| 109 def _OnStaleMd5(proguard_cmd, main_dex_list_cmd, paths, main_dex_list_path): |
| 110 paths_arg = ':'.join(paths) |
| 111 main_dex_list = '' |
| 112 try: |
| 113 with tempfile.NamedTemporaryFile(suffix='.jar') as temp_jar: |
| 114 proguard_cmd += [ |
| 115 '-injars', paths_arg, |
| 116 '-outjars', temp_jar.name |
| 117 ] |
| 118 build_utils.CheckOutput(proguard_cmd, print_stderr=False) |
| 119 |
| 120 main_dex_list_cmd += [ |
| 121 temp_jar.name, paths_arg |
| 122 ] |
| 123 main_dex_list = build_utils.CheckOutput(main_dex_list_cmd) |
| 124 except build_utils.CalledProcessError as e: |
| 125 if 'output jar is empty' in e.output: |
| 126 pass |
| 127 elif "input doesn't contain any classes" in e.output: |
| 128 pass |
| 129 else: |
| 130 raise |
| 131 |
| 132 with open(main_dex_list_path, 'w') as main_dex_list_file: |
| 133 main_dex_list_file.write(main_dex_list) |
| 134 |
| 135 |
| 98 if __name__ == '__main__': | 136 if __name__ == '__main__': |
| 99 sys.exit(main()) | 137 sys.exit(main(sys.argv[1:])) |
| 100 | 138 |
| OLD | NEW |