[Android] Add gn support for multidex.

BUG=272790

Review URL: https://codereview.chromium.org/1451483002

Cr-Original-Commit-Position: refs/heads/master@{#360943}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: e6361975d7f7f4c434dc3380a3824b9d5e323d20
This commit is contained in:
jbudorick 2015-11-20 15:19:23 -08:00 коммит произвёл Commit bot
Родитель 9e5bfd7163
Коммит 3a40e0fdd4
6 изменённых файлов: 163 добавлений и 50 удалений

Просмотреть файл

@ -155,7 +155,12 @@ def main(args):
apk.writestr('lib/%s/%s' % (options.android_abi, name), ':)',
zipfile.ZIP_STORED)
if options.dex_file:
apk.write(options.dex_file, 'classes.dex')
if options.dex_file.endswith('.zip'):
with zipfile.ZipFile(options.dex_file, 'r') as dex_zip:
for dex in (d for d in dex_zip.namelist() if d.endswith('.dex')):
apk.writestr(dex, dex_zip.read(dex))
else:
apk.write(options.dex_file, 'classes.dex')
if options.emma_device_jar:
# Add EMMA Java resources to APK.

Просмотреть файл

@ -60,13 +60,14 @@ def _ParseArgs(args):
'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)
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())

Просмотреть файл

@ -17,8 +17,9 @@ sys.path.append(os.path.abspath(os.path.join(
from pylib import constants
def main():
def main(args):
parser = argparse.ArgumentParser()
build_utils.AddDepfileOption(parser)
parser.add_argument('--android-sdk-tools', required=True,
help='Android sdk build tools directory.')
parser.add_argument('--main-dex-rules-path', action='append', default=[],
@ -36,11 +37,14 @@ def main():
parser.add_argument('--multidex-configuration-path',
help='A JSON file containing multidex build '
'configuration.')
parser.add_argument('paths', nargs='+',
parser.add_argument('--inputs',
help='JARs for which a main dex list should be '
'generated.')
parser.add_argument('paths', nargs='*', default=[],
help='JARs for which a main dex list should be '
'generated.')
args = parser.parse_args()
args = parser.parse_args(build_utils.ExpandFileArgs(args))
if args.multidex_configuration_path:
with open(args.multidex_configuration_path) as multidex_config_file:
@ -49,52 +53,86 @@ def main():
if not multidex_config.get('enabled', False):
return 0
with open(args.main_dex_list_path, 'w') as main_dex_list_file:
if args.inputs:
args.paths.extend(build_utils.ParseGypList(args.inputs))
shrinked_android_jar = os.path.abspath(
os.path.join(args.android_sdk_tools, 'lib', 'shrinkedAndroid.jar'))
dx_jar = os.path.abspath(
os.path.join(args.android_sdk_tools, 'lib', 'dx.jar'))
paths_arg = ':'.join(args.paths)
rules_file = os.path.abspath(
os.path.join(args.android_sdk_tools, 'mainDexClasses.rules'))
shrinked_android_jar = os.path.abspath(
os.path.join(args.android_sdk_tools, 'lib', 'shrinkedAndroid.jar'))
dx_jar = os.path.abspath(
os.path.join(args.android_sdk_tools, 'lib', 'dx.jar'))
rules_file = os.path.abspath(
os.path.join(args.android_sdk_tools, 'mainDexClasses.rules'))
with tempfile.NamedTemporaryFile(suffix='.jar') as temp_jar:
proguard_cmd = [
constants.PROGUARD_SCRIPT_PATH,
'-forceprocessing',
'-dontwarn', '-dontoptimize', '-dontobfuscate', '-dontpreverify',
'-injars', paths_arg,
'-outjars', temp_jar.name,
'-libraryjars', shrinked_android_jar,
'-include', rules_file,
]
for m in args.main_dex_rules_paths:
proguard_cmd.extend(['-include', m])
proguard_cmd = [
constants.PROGUARD_SCRIPT_PATH,
'-forceprocessing',
'-dontwarn', '-dontoptimize', '-dontobfuscate', '-dontpreverify',
'-libraryjars', shrinked_android_jar,
'-include', rules_file,
]
for m in args.main_dex_rules_paths:
proguard_cmd.extend(['-include', m])
main_dex_list = ''
try:
build_utils.CheckOutput(proguard_cmd, print_stderr=False)
main_dex_list_cmd = [
'java', '-cp', dx_jar,
'com.android.multidex.MainDexListBuilder',
]
java_cmd = [
'java', '-cp', dx_jar,
'com.android.multidex.MainDexListBuilder',
temp_jar.name, paths_arg
]
main_dex_list = build_utils.CheckOutput(java_cmd)
except build_utils.CalledProcessError as e:
if 'output jar is empty' in e.output:
pass
elif "input doesn't contain any classes" in e.output:
pass
else:
raise
input_paths = list(args.paths)
input_paths += [
shrinked_android_jar,
dx_jar,
rules_file,
]
input_paths += args.main_dex_rules_paths
main_dex_list_file.write(main_dex_list)
input_strings = [
proguard_cmd,
main_dex_list_cmd,
]
output_paths = [
args.main_dex_list_path,
]
build_utils.CallAndWriteDepfileIfStale(
lambda: _OnStaleMd5(proguard_cmd, main_dex_list_cmd, args.paths,
args.main_dex_list_path),
args,
input_paths=input_paths,
input_strings=input_strings,
output_paths=output_paths)
return 0
if __name__ == '__main__':
sys.exit(main())
def _OnStaleMd5(proguard_cmd, main_dex_list_cmd, paths, main_dex_list_path):
paths_arg = ':'.join(paths)
main_dex_list = ''
try:
with tempfile.NamedTemporaryFile(suffix='.jar') as temp_jar:
proguard_cmd += [
'-injars', paths_arg,
'-outjars', temp_jar.name
]
build_utils.CheckOutput(proguard_cmd, print_stderr=False)
main_dex_list_cmd += [
temp_jar.name, paths_arg
]
main_dex_list = build_utils.CheckOutput(main_dex_list_cmd)
except build_utils.CalledProcessError as e:
if 'output jar is empty' in e.output:
pass
elif "input doesn't contain any classes" in e.output:
pass
else:
raise
with open(main_dex_list_path, 'w') as main_dex_list_file:
main_dex_list_file.write(main_dex_list)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

Просмотреть файл

@ -10,8 +10,8 @@
# 'action_name': 'some name for the action'
# 'actions': [
# 'variables': {
# 'jar_path': 'path to jar',
# 'output_path': 'output path'
# 'jar_paths': ['path to jar', ...],
# 'output_path': 'output path',
# },
# 'includes': [ 'relative/path/to/main_dex_action.gypi' ],
# ],
@ -27,7 +27,7 @@
'main_dex_rules_path': '<(DEPTH)/build/android/main_dex_classes.flags',
},
'inputs': [
'<(jar_path)',
'<@(jar_paths)',
'<(main_dex_list_script)',
'<(main_dex_rules_path)',
'<(multidex_configuration_path)',

Просмотреть файл

@ -223,6 +223,51 @@ template("java_binary_script") {
template("dex") {
set_sources_assignment_filter([])
_enable_multidex = defined(invoker.enable_multidex) && invoker.enable_multidex
if (_enable_multidex) {
_main_dex_list_path = invoker.output + ".main_dex_list"
_main_dex_list_target_name = "${target_name}__main_dex_list"
action(_main_dex_list_target_name) {
forward_variables_from(invoker,
[
"deps",
"inputs",
"sources",
"testonly",
])
script = "//build/android/gyp/main_dex_list.py"
depfile = "$target_gen_dir/$target_name.d"
main_dex_rules = "//build/android/main_dex_classes.flags"
outputs = [
depfile,
_main_dex_list_path,
]
args = [
"--depfile",
rebase_path(depfile, root_build_dir),
"--android-sdk-tools",
rebased_android_sdk_build_tools,
"--main-dex-list-path",
rebase_path(_main_dex_list_path, root_build_dir),
"--main-dex-rules-path",
rebase_path(main_dex_rules, root_build_dir),
]
if (defined(invoker.args)) {
args += invoker.args
}
if (defined(invoker.sources)) {
args += rebase_path(invoker.sources, root_build_dir)
}
}
}
assert(defined(invoker.output))
action(target_name) {
forward_variables_from(invoker,
@ -258,6 +303,16 @@ template("dex") {
args += [ "--no-locals=1" ]
}
if (_enable_multidex) {
args += [
"--multi-dex",
"--main-dex-list-path",
rebase_path(_main_dex_list_path, root_build_dir),
]
deps += [ ":${_main_dex_list_target_name}" ]
inputs += [ _main_dex_list_path ]
}
if (defined(invoker.args)) {
args += invoker.args
}

Просмотреть файл

@ -1240,7 +1240,12 @@ template("android_apk") {
_rebased_lib_dex_path = rebase_path(_lib_dex_path, root_build_dir)
_template_name = target_name
final_dex_path = "$gen_dir/classes.dex"
enable_multidex = defined(invoker.enable_multidex) && invoker.enable_multidex
if (enable_multidex) {
final_dex_path = "$gen_dir/classes.dex.zip"
} else {
final_dex_path = "$gen_dir/classes.dex"
}
final_dex_target_name = "${_template_name}__final_dex"
_final_apk_path = ""
@ -1552,18 +1557,27 @@ template("android_apk") {
_dex_sources = [ _proguard_jar_path ]
_dex_deps = [ ":$_proguard_target" ]
} else {
_dex_sources = [ _lib_dex_path ]
if (enable_multidex) {
_dex_sources = [ _jar_path ]
} else {
_dex_sources = [ _lib_dex_path ]
}
_dex_deps = [ ":$java_target" ]
}
dex("$final_dex_target_name") {
forward_variables_from(invoker, [ "enable_multidex" ])
deps = _dex_deps + [ ":$build_config_target" ]
inputs = [
_build_config,
]
sources = _dex_sources
output = final_dex_path
_dex_arg_key = "${_rebased_build_config}:final_dex:dependency_dex_files"
if (enable_multidex) {
_dex_arg_key = "${_rebased_build_config}:dist_jar:dependency_jars"
} else {
_dex_arg_key = "${_rebased_build_config}:final_dex:dependency_dex_files"
}
args = [ "--inputs=@FileArg($_dex_arg_key)" ]
if (emma_coverage && !_emma_never_instrument) {