Commit 8f7c4ee8 authored by Sam Maier's avatar Sam Maier Committed by Commit Bot

Reland "Using R8 in place of Proguard for creating main dex list"

This is a reland of eec7c07a

Original change's description:
> Using R8 in place of Proguard for creating main dex list
>
> Bug: 908988
> Change-Id: I9cfe718d3754b92022c9045f860dee36c7e049bb
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1635949
> Commit-Queue: Sam Maier <smaier@chromium.org>
> Auto-Submit: Sam Maier <smaier@chromium.org>
> Reviewed-by: Eric Stevenson <estevenson@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#665957}

Bug: 908988
Change-Id: I9d535df1e642f59a639865388b90fdd066a09802
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650373
Commit-Queue: Sam Maier <smaier@chromium.org>
Auto-Submit: Sam Maier <smaier@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#672083}
parent 13efbf05
...@@ -36,9 +36,11 @@ public abstract class BuildHooksAndroid { ...@@ -36,9 +36,11 @@ public abstract class BuildHooksAndroid {
// doesn't need to be in the main dex file. // doesn't need to be in the main dex file.
private static BuildHooksAndroid constructBuildHooksAndroidImpl() { private static BuildHooksAndroid constructBuildHooksAndroidImpl() {
try { try {
// Not final to avoid inlining. Without this proguard is able to figure out that // Not final to avoid inlining. Without this R8 is able to figure out that
// BuildHooksAndroidImpl is actually used. // BuildHooksAndroidImpl is actually used.
String implClazzName = "org.chromium.build.BuildHooksAndroidImpl"; String implClazzName = System.currentTimeMillis() > 0
? "org.chromium.build.BuildHooksAndroidImpl"
: "";
Class<?> implClazz = Class.forName(implClazzName); Class<?> implClazz = Class.forName(implClazzName);
return (BuildHooksAndroid) implClazz.newInstance(); return (BuildHooksAndroid) implClazz.newInstance();
} catch (Exception e) { } catch (Exception e) {
...@@ -104,4 +106,4 @@ public abstract class BuildHooksAndroid { ...@@ -104,4 +106,4 @@ public abstract class BuildHooksAndroid {
} }
protected abstract void maybeRecordResourceMetricsImpl(); protected abstract void maybeRecordResourceMetricsImpl();
} }
\ No newline at end of file
...@@ -32,8 +32,8 @@ def main(args): ...@@ -32,8 +32,8 @@ def main(args):
parser.add_argument('--inputs', parser.add_argument('--inputs',
help='JARs for which a main dex list should be ' help='JARs for which a main dex list should be '
'generated.') 'generated.')
parser.add_argument('--proguard-path', required=True, parser.add_argument(
help='Path to the proguard executable.') '--r8-path', required=True, help='Path to the r8 executable.')
parser.add_argument('--negative-main-dex-globs', parser.add_argument('--negative-main-dex-globs',
help='GN-list of globs of .class names (e.g. org/chromium/foo/Bar.class) ' help='GN-list of globs of .class names (e.g. org/chromium/foo/Bar.class) '
'that will fail the build if they match files in the main dex.') 'that will fail the build if they match files in the main dex.')
...@@ -55,13 +55,24 @@ def main(args): ...@@ -55,13 +55,24 @@ def main(args):
args.negative_main_dex_globs) args.negative_main_dex_globs)
proguard_cmd = [ proguard_cmd = [
'java', '-jar', args.proguard_path, 'java',
'-forceprocessing', '-jar',
'-dontwarn', '-dontoptimize', '-dontobfuscate', '-dontpreverify', args.r8_path,
'-libraryjars', args.shrinked_android_path, '--classfile',
'--lib',
args.shrinked_android_path,
] ]
for m in args.main_dex_rules_paths: for m in args.main_dex_rules_paths:
proguard_cmd.extend(['-include', m]) proguard_cmd.extend(['--pg-conf', m])
proguard_flags = [
'-forceprocessing',
'-dontwarn',
'-dontoptimize',
'-dontobfuscate',
'-dontpreverify',
]
main_dex_list_cmd = [ main_dex_list_cmd = [
'java', '-cp', args.dx_path, 'java', '-cp', args.dx_path,
...@@ -83,17 +94,24 @@ def main(args): ...@@ -83,17 +94,24 @@ def main(args):
proguard_cmd, proguard_cmd,
main_dex_list_cmd, main_dex_list_cmd,
] ]
if args.negative_main_dex_globs: if args.negative_main_dex_globs:
input_strings += args.negative_main_dex_globs input_strings += args.negative_main_dex_globs
for glob in args.negative_main_dex_globs:
# Globs come with 1 asterix, but we want 2 to match subpackages.
proguard_flags.append('-checkdiscard class ' +
glob.replace('*', '**').replace('/', '.'))
output_paths = [ output_paths = [
args.main_dex_list_path, args.main_dex_list_path,
] ]
def _LineLengthHelperForOnStaleMd5():
_OnStaleMd5(proguard_cmd, proguard_flags, main_dex_list_cmd, args.paths,
args.main_dex_list_path)
build_utils.CallAndWriteDepfileIfStale( build_utils.CallAndWriteDepfileIfStale(
lambda: _OnStaleMd5(proguard_cmd, main_dex_list_cmd, args.paths, _LineLengthHelperForOnStaleMd5,
args.main_dex_list_path,
args.negative_main_dex_globs),
args, args,
input_paths=input_paths, input_paths=input_paths,
input_strings=input_strings, input_strings=input_strings,
...@@ -104,38 +122,22 @@ def main(args): ...@@ -104,38 +122,22 @@ def main(args):
return 0 return 0
def _CheckForUnwanted(kept_classes, proguard_cmd, negative_main_dex_globs): def _OnStaleMd5(proguard_cmd, proguard_flags, main_dex_list_cmd, paths,
# Check if ProGuard kept any unwanted classes. main_dex_list_path):
found_unwanted_classes = sorted(
p for p in kept_classes
if build_utils.MatchesGlob(p, negative_main_dex_globs))
if found_unwanted_classes:
first_class = found_unwanted_classes[0].replace(
'.class', '').replace('/', '.')
proguard_cmd += ['-whyareyoukeeping', 'class', first_class, '{}']
output = build_utils.CheckOutput(
proguard_cmd, print_stderr=False,
stdout_filter=proguard_util.ProguardOutputFilter())
raise Exception(
('Found classes that should not be in the main dex:\n {}\n\n'
'Here is the -whyareyoukeeping output for {}: \n{}').format(
'\n '.join(found_unwanted_classes), first_class, output))
def _OnStaleMd5(proguard_cmd, main_dex_list_cmd, paths, main_dex_list_path,
negative_main_dex_globs):
paths_arg = ':'.join(paths)
main_dex_list = '' main_dex_list = ''
try: try:
with tempfile.NamedTemporaryFile(suffix='.jar') as temp_jar: with tempfile.NamedTemporaryFile(suffix='.jar') as temp_jar:
# Step 1: Use ProGuard to find all @MainDex code, and all code reachable # Step 1: Use ProGuard to find all @MainDex code, and all code reachable
# from @MainDex code (recursive). # from @MainDex code (recursive).
proguard_cmd += [ proguard_cmd += ['--output', temp_jar.name]
'-injars', paths_arg, with tempfile.NamedTemporaryFile() as proguard_flags_file:
'-outjars', temp_jar.name for flag in proguard_flags:
] proguard_flags_file.write(flag + '\n')
build_utils.CheckOutput(proguard_cmd, print_stderr=False) proguard_flags_file.flush()
proguard_cmd += ['--pg-conf', proguard_flags_file.name]
for injar in paths:
proguard_cmd.append(injar)
build_utils.CheckOutput(proguard_cmd, print_stderr=False)
# Record the classes kept by ProGuard. Not used by the build, but useful # Record the classes kept by ProGuard. Not used by the build, but useful
# for debugging what classes are kept by ProGuard vs. MainDexListBuilder. # for debugging what classes are kept by ProGuard vs. MainDexListBuilder.
...@@ -144,18 +146,9 @@ def _OnStaleMd5(proguard_cmd, main_dex_list_cmd, paths, main_dex_list_path, ...@@ -144,18 +146,9 @@ def _OnStaleMd5(proguard_cmd, main_dex_list_cmd, paths, main_dex_list_path,
with open(main_dex_list_path + '.partial', 'w') as f: with open(main_dex_list_path + '.partial', 'w') as f:
f.write('\n'.join(kept_classes) + '\n') f.write('\n'.join(kept_classes) + '\n')
if negative_main_dex_globs:
# Perform assertions before MainDexListBuilder because:
# a) MainDexListBuilder is not recursive, so being included by it isn't
# a huge deal.
# b) Errors are much more actionable.
_CheckForUnwanted(kept_classes, proguard_cmd, negative_main_dex_globs)
# Step 2: Expand inclusion list to all classes referenced by the .class # Step 2: Expand inclusion list to all classes referenced by the .class
# files of kept classes (non-recursive). # files of kept classes (non-recursive).
main_dex_list_cmd += [ main_dex_list_cmd += [temp_jar.name, ':'.join(paths)]
temp_jar.name, paths_arg
]
main_dex_list = build_utils.CheckOutput(main_dex_list_cmd) main_dex_list = build_utils.CheckOutput(main_dex_list_cmd)
except build_utils.CalledProcessError as e: except build_utils.CalledProcessError as e:
......
...@@ -1234,18 +1234,13 @@ if (enable_java_templates) { ...@@ -1234,18 +1234,13 @@ if (enable_java_templates) {
# http://crbug.com/725224. Fix for bots running out of memory. # http://crbug.com/725224. Fix for bots running out of memory.
pool = "//build/toolchain:link_pool($default_toolchain)" pool = "//build/toolchain:link_pool($default_toolchain)"
if (defined(invoker.proguard_jar_path)) {
_proguard_jar_path = invoker.proguard_jar_path
} else {
_proguard_jar_path = _default_proguard_jar_path
}
_shrinked_android = "$android_sdk_build_tools/lib/shrinkedAndroid.jar" _shrinked_android = "$android_sdk_build_tools/lib/shrinkedAndroid.jar"
_dx = "$android_sdk_build_tools/lib/dx.jar" _dx = "$android_sdk_build_tools/lib/dx.jar"
_r8 = "//third_party/r8/lib/r8.jar"
inputs = [ inputs = [
_main_dex_rules, _main_dex_rules,
_dx, _dx,
_proguard_jar_path, _r8,
_shrinked_android, _shrinked_android,
] ]
...@@ -1264,8 +1259,8 @@ if (enable_java_templates) { ...@@ -1264,8 +1259,8 @@ if (enable_java_templates) {
rebase_path(_main_dex_list_path, root_build_dir), rebase_path(_main_dex_list_path, root_build_dir),
"--main-dex-rules-path", "--main-dex-rules-path",
rebase_path(_main_dex_rules, root_build_dir), rebase_path(_main_dex_rules, root_build_dir),
"--proguard-path", "--r8-path",
rebase_path(_proguard_jar_path, root_build_dir), rebase_path(_r8, root_build_dir),
] ]
if (defined(invoker.extra_main_dex_proguard_config)) { if (defined(invoker.extra_main_dex_proguard_config)) {
...@@ -1290,11 +1285,11 @@ if (enable_java_templates) { ...@@ -1290,11 +1285,11 @@ if (enable_java_templates) {
if (defined(invoker.input_jar_classpath)) { if (defined(invoker.input_jar_classpath)) {
inputs += [ invoker.build_config ] inputs += [ invoker.build_config ]
args += [ "--inputs=@FileArg(${invoker.input_jar_classpath})" ] args += [ "--inputs=@FileArg(${invoker.input_jar_classpath})" ]
} } else {
inputs += _dexing_jars
inputs += _dexing_jars if (_dexing_jars != []) {
if (_dexing_jars != []) { args += rebase_path(_dexing_jars, root_build_dir)
args += rebase_path(_dexing_jars, root_build_dir) }
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment