From df8d70f694e1ed3f02004064a9de18ef4b82804c Mon Sep 17 00:00:00 2001 From: corysmith Date: Mon, 11 Sep 2017 23:33:09 +0200 Subject: Enable resource shrinking for aapt2. First commit in series, the second will make the necessary changes to the action. RELNOTES: None PiperOrigin-RevId: 168286654 --- .../build/lib/rules/android/AndroidBinary.java | 47 +++++++------- .../android/ResourceShrinkerActionBuilder.java | 41 +++++++----- .../build/lib/rules/android/AndroidBinaryTest.java | 72 ++++++++++++++++++++++ 3 files changed, 118 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java index ec5f03a7ae..550597a7a1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java @@ -827,13 +827,6 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { /** Returns {@code true} if resource shrinking should be performed. */ private static boolean shouldShrinkResources(RuleContext ruleContext) throws RuleErrorException { - - if (AndroidAaptVersion.chooseTargetAaptVersion(ruleContext) == AndroidAaptVersion.AAPT2) { - ruleContext.attributeWarning( - "shrink_resources", "aapt2 enabled builds do not yet support resource shrinking."); - return false; - } - TriState state = ruleContext.attributes().get("shrink_resources", BuildType.TRISTATE); if (state == TriState.AUTO) { boolean globalShrinkResources = @@ -854,24 +847,28 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { if (LocalResourceContainer.definesAndroidResources(ruleContext.attributes()) && !proguardSpecs.isEmpty()) { - Artifact apk = new ResourceShrinkerActionBuilder(ruleContext) - .setResourceApkOut(ruleContext.getImplicitOutputArtifact( - AndroidRuleClasses.ANDROID_RESOURCES_SHRUNK_APK)) - .setShrunkResourcesOut(ruleContext.getImplicitOutputArtifact( - AndroidRuleClasses.ANDROID_RESOURCES_SHRUNK_ZIP)) - .setLogOut(ruleContext.getImplicitOutputArtifact( - AndroidRuleClasses.ANDROID_RESOURCE_SHRINKER_LOG)) - .withResourceFiles(ruleContext.getImplicitOutputArtifact( - AndroidRuleClasses.ANDROID_RESOURCES_ZIP)) - .withShrunkJar(proguardOutput.getOutputJar()) - .withProguardMapping(proguardOutput.getMapping()) - .withPrimary(resourceApk.getPrimaryResource()) - .withDependencies(resourceApk.getResourceDependencies()) - .setResourceFilter(ResourceFilter.fromRuleContext(ruleContext)) - - .setUncompressedExtensions( - ruleContext.getTokenizedStringListAttr("nocompress_extensions")) - .build(); + Artifact apk = + new ResourceShrinkerActionBuilder(ruleContext) + .setResourceApkOut( + ruleContext.getImplicitOutputArtifact( + AndroidRuleClasses.ANDROID_RESOURCES_SHRUNK_APK)) + .setShrunkResourcesOut( + ruleContext.getImplicitOutputArtifact( + AndroidRuleClasses.ANDROID_RESOURCES_SHRUNK_ZIP)) + .setLogOut( + ruleContext.getImplicitOutputArtifact( + AndroidRuleClasses.ANDROID_RESOURCE_SHRINKER_LOG)) + .withResourceFiles( + ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP)) + .withShrunkJar(proguardOutput.getOutputJar()) + .withProguardMapping(proguardOutput.getMapping()) + .withPrimary(resourceApk.getPrimaryResource()) + .withDependencies(resourceApk.getResourceDependencies()) + .setTargetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)) + .setResourceFilter(ResourceFilter.fromRuleContext(ruleContext)) + .setUncompressedExtensions( + ruleContext.getTokenizedStringListAttr("nocompress_extensions")) + .build(); filesBuilder.add(ruleContext.getImplicitOutputArtifact( AndroidRuleClasses.ANDROID_RESOURCE_SHRINKER_LOG)); return new ResourceApk(apk, diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java index b38898a8dd..4bae0bc02c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceShrinkerActionBuilder.java @@ -17,6 +17,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; @@ -32,6 +33,7 @@ import java.util.List; * Builder for creating resource shrinker actions. */ public class ResourceShrinkerActionBuilder { + private AndroidAaptVersion targetAaptVersion; private Artifact resourceFilesZip; private Artifact shrunkJar; private Artifact proguardMapping; @@ -49,10 +51,8 @@ public class ResourceShrinkerActionBuilder { private List assetsToIgnore = Collections.emptyList(); private ResourceFilter resourceFilter; - /** - * @param ruleContext The RuleContext of the owning rule. - */ - public ResourceShrinkerActionBuilder(RuleContext ruleContext) { + /** @param ruleContext The RuleContext of the owning rule. */ + public ResourceShrinkerActionBuilder(RuleContext ruleContext) throws RuleErrorException { this.ruleContext = ruleContext; this.spawnActionBuilder = new SpawnAction.Builder(); this.sdk = AndroidSdkProvider.fromRuleContext(ruleContext); @@ -143,26 +143,33 @@ public class ResourceShrinkerActionBuilder { this.logOut = logOut; return this; } + + /** + * @param androidAaptVersion The aapt version to target with this action. + */ + public ResourceShrinkerActionBuilder setTargetAaptVersion(AndroidAaptVersion androidAaptVersion) { + this.targetAaptVersion = androidAaptVersion; + return this; + } public Artifact build() throws RuleErrorException { - if (AndroidAaptVersion.chooseTargetAaptVersion(ruleContext) == AndroidAaptVersion.AAPT2) { - ruleContext.throwWithRuleError("aapt2 enabled builds do not yet support resource shrinking."); - } ImmutableList.Builder inputs = ImmutableList.builder(); ImmutableList.Builder outputs = ImmutableList.builder(); CustomCommandLine.Builder commandLine = new CustomCommandLine.Builder(); // Set the busybox tool. - commandLine.add("--tool").add("SHRINK").add("--"); - - inputs.addAll( - ruleContext - .getExecutablePrerequisite("$android_resources_busybox", Mode.HOST) - .getRunfilesSupport() - .getRunfilesArtifactsWithoutMiddlemen()); - - commandLine.addExecPath("--aapt", sdk.getAapt().getExecutable()); + FilesToRunProvider aapt; + + if (targetAaptVersion == AndroidAaptVersion.AAPT2) { + aapt = sdk.getAapt2(); + commandLine.add("--tool").add("SHRINK_AAPT2").add("--"); + commandLine.addExecPath("--aapt2", aapt.getExecutable()); + } else { + aapt = sdk.getAapt(); + commandLine.add("--tool").add("SHRINK").add("--"); + commandLine.addExecPath("--aapt", aapt.getExecutable()); + } commandLine.addExecPath("--annotationJar", sdk.getAnnotationsJar()); inputs.add(sdk.getAnnotationsJar()); @@ -229,7 +236,7 @@ public class ResourceShrinkerActionBuilder { ruleContext.registerAction( spawnActionBuilder .useDefaultShellEnvironment() - .addTool(sdk.getAapt()) + .addTool(aapt) .addInputs(inputs.build()) .addOutputs(outputs.build()) .setCommandLine(commandLine.build()) 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 a0d1ed3c8a..64c0993328 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 @@ -3190,4 +3190,76 @@ public class AndroidBinaryTest extends AndroidBuildViewTestCase { .containsAllOf( rTxt, getImplicitOutputArtifact(b, AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_R_TXT)); } + + @Test + public void testAapt2ResourceShrinkingAction() throws Exception { + scratch.file( + "sdk/BUILD", + "android_sdk(", + " name = 'sdk',", + " aapt = 'aapt',", + " aapt2 = 'aapt2',", + " adb = 'adb',", + " aidl = 'aidl',", + " android_jar = 'android.jar',", + " annotations_jar = 'annotations_jar',", + " apksigner = 'apksigner',", + " dx = 'dx',", + " framework_aidl = 'framework_aidl',", + " main_dex_classes = 'main_dex_classes',", + " main_dex_list_creator = 'main_dex_list_creator',", + " proguard = 'proguard',", + " shrinked_android_jar = 'shrinked_android_jar',", + " zipalign = 'zipalign')"); + + scratch.file( + "java/com/google/android/hello/BUILD", + "android_binary(name = 'hello',", + " srcs = ['Foo.java'],", + " manifest = 'AndroidManifest.xml',", + " inline_constants = 0,", + " aapt_version='aapt2',", + " resource_files = ['res/values/strings.xml'],", + " shrink_resources = 1,", + " proguard_specs = ['proguard-spec.pro'],)"); + + useConfiguration("--android_sdk=//sdk:sdk"); + ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:hello"); + + Set artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)); + + assertThat(artifacts) + .containsAllOf( + getFirstArtifactEndingWith(artifacts, "resource_files.zip"), + getFirstArtifactEndingWith(artifacts, "proguard.jar"), + getFirstArtifactEndingWith(artifacts, "shrunk.ap_")); + + List processingArgs = + getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "resource_files.zip")); + + assertThat(flagValue("--resourcesOutput", processingArgs)) + .endsWith("hello_files/resource_files.zip"); + + List proguardArgs = + getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "proguard.jar")); + + assertThat(flagValue("-outjars", proguardArgs)).endsWith("hello_proguard.jar"); + + List shrinkingArgs = + getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "shrunk.ap_")); + + assertThat(flagValue("--tool", shrinkingArgs)).isEqualTo("SHRINK_AAPT2"); + + assertThat(flagValue("--aapt2", shrinkingArgs)).isEqualTo(flagValue("--aapt2", processingArgs)); + assertThat(flagValue("--resources", shrinkingArgs)) + .isEqualTo(flagValue("--resourcesOutput", processingArgs)); + assertThat(flagValue("--shrunkJar", shrinkingArgs)) + .isEqualTo(flagValue("-outjars", proguardArgs)); + assertThat(flagValue("--proguardMapping", shrinkingArgs)) + .isEqualTo(flagValue("-printmapping", proguardArgs)); + assertThat(flagValue("--rTxt", shrinkingArgs)) + .isEqualTo(flagValue("--rOutput", processingArgs)); + assertThat(flagValue("--primaryManifest", shrinkingArgs)) + .isEqualTo(flagValue("--manifestOutput", processingArgs)); + } } -- cgit v1.2.3