diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java index 062fd4afdbee65..4bc8b0cbab272c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java @@ -397,7 +397,7 @@ public static class Options extends FragmentOptions { @Option( name = "experimental_incremental_dexing_after_proguard", - defaultValue = "1", + defaultValue = "50", documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, effectTags = { OptionEffectTag.LOADING_AND_ANALYSIS, @@ -411,7 +411,7 @@ public static class Options extends FragmentOptions { /** Whether to use a separate tool to shard classes before merging them into final dex files. */ @Option( name = "experimental_use_dex_splitter_for_incremental_dexing", - defaultValue = "false", + defaultValue = "true", metadataTags = {OptionMetadataTag.EXPERIMENTAL}, documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS}, @@ -420,7 +420,7 @@ public static class Options extends FragmentOptions { @Option( name = "experimental_incremental_dexing_after_proguard_by_default", - defaultValue = "false", + defaultValue = "true", metadataTags = {OptionMetadataTag.EXPERIMENTAL}, documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS}, diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMultidexTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMultidexTest.java index bef41ab63dc3b1..32500b96045aee 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMultidexTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMultidexTest.java @@ -43,6 +43,10 @@ protected boolean platformBasedToolchains() { @Before public void setup() throws Exception { getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a"); + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); } /** diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java index a30c8004afdc1d..39084a871f0272 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidBinaryTest.java @@ -1066,6 +1066,10 @@ public void testNativeLibrary_providesLinkerScriptToLinkAction() throws Exceptio /** Regression test for http://b/33173461. */ @Test public void testIncrementalDexingUsesDexArchives_binaryDependingOnAliasTarget() throws Exception { + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/com/google/android/BUILD", "android_library(", @@ -1150,6 +1154,10 @@ public void testIncrementalDexingDisabledWithBlacklistedDexopts() throws Excepti @Test public void testIncrementalDexingDisabledWithProguard() throws Exception { + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/com/google/android/BUILD", "android_binary(", @@ -1172,7 +1180,10 @@ public void testIncrementalDexingDisabledWithProguard() throws Exception { @Test public void testIncrementalDexing_incompatibleWithProguardWhenDisabled() throws Exception { - useConfiguration("--experimental_incremental_dexing_after_proguard=0"); // disable with Proguard + useConfiguration( + "--experimental_incremental_dexing_after_proguard=0", // disable with Proguard + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false"); checkError( "java/com/google/android", "top", @@ -2551,7 +2562,11 @@ public void testDexShardingNativeStructure() throws Exception { @Test public void testDexShardingLegacyAndProguardStructure_withNoDesugaring() throws Exception { - useConfiguration("--noexperimental_desugar_for_android"); + useConfiguration( + "--noexperimental_desugar_for_android", + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/a/BUILD", "android_binary(", @@ -2567,6 +2582,10 @@ public void testDexShardingLegacyAndProguardStructure_withNoDesugaring() throws @Test public void testDexShardingLegacyAndProguardStructure() throws Exception { + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/a/BUILD", "android_binary(", @@ -2582,6 +2601,10 @@ public void testDexShardingLegacyAndProguardStructure() throws Exception { @Test public void testDexShardingNativeAndProguardStructure() throws Exception { + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/a/BUILD", "android_binary(", @@ -4098,6 +4121,10 @@ public void testAapt2ResourceCycleShinkingWithoutResourceShrinking() throws Exce @Test public void testOnlyProguardSpecs() throws Exception { + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/com/google/android/hello/BUILD", "android_library(name = 'l2',", @@ -4255,6 +4282,10 @@ public void testNoDuplicatesInProguardCommand() throws Exception { @Test public void testProguardMapping() throws Exception { + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/com/google/android/hello/BUILD", "android_binary(name = 'b',", @@ -4312,7 +4343,11 @@ public void testProguardMappingProvider() throws Exception { @Test public void testLegacyOptimizationModeUsesExtraProguardSpecs() throws Exception { - useConfiguration("--extra_proguard_specs=java/com/google/android/hello:extra.pro"); + useConfiguration( + "--extra_proguard_specs=java/com/google/android/hello:extra.pro", + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/com/google/android/hello/BUILD", "exports_files(['extra.pro'])", @@ -4345,7 +4380,11 @@ public void testLegacyOptimizationModeUsesExtraProguardSpecs() throws Exception @Test public void testExtraProguardSpecsDontDuplicateProguardInputFiles() throws Exception { - useConfiguration("--extra_proguard_specs=java/com/google/android/hello:proguard-spec.pro"); + useConfiguration( + "--extra_proguard_specs=java/com/google/android/hello:proguard-spec.pro", + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "java/com/google/android/hello/BUILD", "android_binary(name = 'b',", @@ -4653,6 +4692,10 @@ public void testFilterActionWithInstrumentedBinary() throws Exception { */ @Test public void testConfigurableProguardSpecs() throws Exception { + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); scratch.file( "conditions/BUILD", "config_setting(", diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestTest.java index 5a8e36ed939bfe..0c0951e8658a5b 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidInstrumentationTestTest.java @@ -110,6 +110,10 @@ public void setup() throws Exception { " ],", ")"); setupTargetDevice(); + useConfiguration( + "--experimental_use_dex_splitter_for_incremental_dexing=false", + "--experimental_incremental_dexing_after_proguard_by_default=false", + "--experimental_incremental_dexing_after_proguard=1"); setBuildLanguageOptions("--experimental_google_legacy_api"); } diff --git a/src/test/shell/bazel/android/android_integration_test.sh b/src/test/shell/bazel/android/android_integration_test.sh index d1ea0523c95759..c05d6d83bd2207 100755 --- a/src/test/shell/bazel/android/android_integration_test.sh +++ b/src/test/shell/bazel/android/android_integration_test.sh @@ -179,4 +179,130 @@ built_with_bazel_version 4.5.6" assert_equals "$expected" "$actual" } +function write_large_java_file() { + f="$1" + class="$(basename $f .java)" + package="$(dirname $f | sed 's|java/||' | sed 's|/|.|g')" + echo package = $package + echo "package $package;" > "$f" + echo "public class $class {" >> "$f" + for i in $(seq 33000); do + echo "public int foo_$i() { return $i ; }" >> "$f" + done + echo "}" >> "$f" +} + +function assert_multiple_dex_files() { + apk="bazel-bin/java/com/example/hello/hello.apk" + count=$(unzip -l ${apk} | grep classes | wc -l) + [ "${count}" -gt 1 ] || \ + fail "Expected multiple dex files in apk, found ${count}" +} + +function test_native_multidex() { + write_hello_android_files + setup_android_sdk_support + cat > java/com/example/hello/BUILD <<'EOF' +android_binary( + name = "hello", + manifest = "AndroidManifest.xml", + srcs = glob(["*.java"]), + resource_files = glob(["res/**"]), + multidex = "native", +) +EOF + + write_large_java_file java/com/example/hello/Lib1.java + write_large_java_file java/com/example/hello/Lib2.java + + bazel build java/com/example/hello:hello || fail "build failed" + assert_multiple_dex_files +} + +function test_native_multidex_proguard() { + write_hello_android_files + setup_android_sdk_support + cat > java/com/example/hello/BUILD <<'EOF' +android_binary( + name = "hello", + manifest = "AndroidManifest.xml", + srcs = glob(["*.java"]), + resource_files = glob(["res/**"]), + multidex = "native", + proguard_specs = ["proguard.cfg"], +) +EOF + + cat > java/com/example/hello/proguard.cfg <<'EOF' +-keep class com.example.hello.** +-keep class com.example.hello.Lib1 { + public int foo*(); +} +-keep class com.example.hello.Lib2 { + public int foo*(); +} +EOF + + write_large_java_file java/com/example/hello/Lib1.java + write_large_java_file java/com/example/hello/Lib2.java + + bazel build java/com/example/hello:hello || fail "build failed" + # Ensures that we didn't accidentally optimize away all the unused methods. + assert_multiple_dex_files +} + +function test_native_multidex_dex_shards() { + write_hello_android_files + setup_android_sdk_support + cat > java/com/example/hello/BUILD <<'EOF' +android_binary( + name = "hello", + manifest = "AndroidManifest.xml", + srcs = glob(["*.java"]), + resource_files = glob(["res/**"]), + multidex = "native", + dex_shards = 10, +) +EOF + + write_large_java_file java/com/example/hello/Lib1.java + write_large_java_file java/com/example/hello/Lib2.java + + bazel build java/com/example/hello:hello || fail "build failed" + assert_multiple_dex_files +} + +function test_native_multidex_dex_shards_proguard() { + write_hello_android_files + setup_android_sdk_support + cat > java/com/example/hello/BUILD <<'EOF' +android_binary( + name = "hello", + manifest = "AndroidManifest.xml", + srcs = glob(["*.java"]), + resource_files = glob(["res/**"]), + multidex = "native", + proguard_specs = ["proguard.cfg"], + dex_shards = 10, +) +EOF + + cat > java/com/example/hello/proguard.cfg <<'EOF' +-keep class com.example.hello.** +-keep class com.example.hello.Lib1 { + public int foo*(); +} +-keep class com.example.hello.Lib2 { + public int foo*(); +} +EOF + + write_large_java_file java/com/example/hello/Lib1.java + write_large_java_file java/com/example/hello/Lib2.java + + bazel build java/com/example/hello:hello || fail "build failed" + # Ensures that we didn't accidentally optimize away all the unused methods. + assert_multiple_dex_files +} + run_suite "Android integration tests" diff --git a/tools/android/BUILD.tools b/tools/android/BUILD.tools index 49af2996fbadd0..f2add84420231a 100644 --- a/tools/android/BUILD.tools +++ b/tools/android/BUILD.tools @@ -72,9 +72,19 @@ alias( }), ) +# Matches dx_standalone_dexer in android_sdk_repository_template.bzl. Not using +# the one there to avoid a dependency on the android sdk. +config_setting( + name = "dx_standalone_dexer", + values = {"define": "android_standalone_dexing_tool=dx_compat_dx"}, +) + alias( name = "dexbuilder_after_proguard", - actual = "//src/tools/android/java/com/google/devtools/build/android/dexer:DexBuilder", + actual = select({ + ":dx_standalone_dexer": "//src/tools/android/java/com/google/devtools/build/android/dexer:DexBuilder", + "//conditions:default": ":d8_dexbuilder", + }), ) # Defines d8_dexmerger using @//:d8_jar_import generated by android_sdk_repository rule