Add flag for optimized resource shrinking with R8
If the flag is set we will:
- pass --optimized-resource-shrinking to the r8 invocation
- use non final fields for the generated R classes
- not pass the aapt2 generated proguard rules, R8 will do the tracing of xml files
Bug: 325905703
Test: This is simply passing the flag through to R8, this is off by default
Change-Id: Ib2043f3201578c3bcd39c1de9a524fd78f6d795c
diff --git a/java/aar.go b/java/aar.go
index 2835792..5061879 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -351,6 +351,7 @@
classLoaderContexts dexpreopt.ClassLoaderContextMap
excludedLibs []string
enforceDefaultTargetSdkVersion bool
+ forceNonFinalResourceIDs bool
extraLinkFlags []string
aconfigTextFiles android.Paths
}
@@ -544,7 +545,8 @@
if a.useResourceProcessorBusyBox(ctx) {
rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
- resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags)
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary, a.aaptProperties.Aaptflags,
+ opts.forceNonFinalResourceIDs)
aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
transitiveRJars = append(transitiveRJars, rJar)
a.rJar = rJar
@@ -608,7 +610,8 @@
// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
// supports producing classes for static dependencies that only include resources from that dependency.
func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
- rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string) {
+ rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool, aaptFlags []string,
+ forceNonFinalIds bool) {
var args []string
var deps android.Paths
@@ -618,6 +621,9 @@
// to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
// package.
args, deps = transitiveDeps.resourceProcessorDeps()
+ if forceNonFinalIds {
+ args = append(args, "--finalFields=false")
+ }
} else {
// When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
// library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
@@ -1221,7 +1227,7 @@
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
- resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil)
+ resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true, nil, false)
aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
diff --git a/java/app.go b/java/app.go
index 4656888..2abc451 100755
--- a/java/app.go
+++ b/java/app.go
@@ -519,12 +519,15 @@
a.aapt.defaultManifestVersion = android.DefaultUpdatableModuleVersion
}
+ // Use non final ids if we are doing optimized shrinking and are using R8.
+ nonFinalIds := Bool(a.dexProperties.Optimize.Optimized_shrink_resources) && a.dexer.effectiveOptimizeEnabled()
a.aapt.buildActions(ctx,
aaptBuildActionOptions{
sdkContext: android.SdkContext(a),
classLoaderContexts: a.classLoaderContexts,
excludedLibs: a.usesLibraryProperties.Exclude_uses_libs,
enforceDefaultTargetSdkVersion: a.enforceDefaultTargetSdkVersion(),
+ forceNonFinalResourceIDs: nonFinalIds,
extraLinkFlags: aaptLinkFlags,
aconfigTextFiles: getAconfigFilePaths(ctx),
},
@@ -547,7 +550,13 @@
staticLibProguardFlagFiles = android.FirstUniquePaths(staticLibProguardFlagFiles)
a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, staticLibProguardFlagFiles...)
- a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
+ if !Bool(a.dexProperties.Optimize.Optimized_shrink_resources) {
+ // When using the optimized shrinking the R8 enqueuer will traverse the xml files that become
+ // live for code references and (transitively) mark these as live.
+ // In this case we explicitly don't wan't the aapt2 generated keep files (which would keep the now
+ // dead code alive)
+ a.Module.extraProguardFlagsFiles = append(a.Module.extraProguardFlagsFiles, a.proguardOptionsFile)
+ }
}
func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath {
@@ -580,7 +589,7 @@
var packageResources = a.exportPackage
if ctx.ModuleName() != "framework-res" {
- if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ if a.dexProperties.resourceShrinkingEnabled() {
protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
aapt2Convert(ctx, protoFile, packageResources, "proto")
a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
@@ -603,7 +612,7 @@
}
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
- if Bool(a.dexProperties.Optimize.Shrink_resources) {
+ if a.dexProperties.resourceShrinkingEnabled() {
binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
packageResources = binaryResources
diff --git a/java/dex.go b/java/dex.go
index 4474c63..6caaa7f 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -66,6 +66,12 @@
// If true, optimize for size by removing unused resources. Defaults to false.
Shrink_resources *bool
+ // If true, use optimized resource shrinking in R8, overriding the
+ // Shrink_resources setting. Defaults to false.
+ // Optimized shrinking means that R8 will trace and treeshake resources together with code
+ // and apply additional optimizations. This implies non final fields in the R classes.
+ Optimized_shrink_resources *bool
+
// Flags to pass to proguard.
Proguard_flags []string
@@ -105,6 +111,10 @@
return BoolDefault(d.dexProperties.Optimize.Enabled, d.dexProperties.Optimize.EnabledByDefault)
}
+func (d *DexProperties) resourceShrinkingEnabled() bool {
+ return BoolDefault(d.Optimize.Optimized_shrink_resources, Bool(d.Optimize.Shrink_resources))
+}
+
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -351,10 +361,14 @@
r8Flags = append(r8Flags, "-ignorewarnings")
}
+ // resourcesInput is empty when we don't use resource shrinking, if on, pass these to R8
if d.resourcesInput.Valid() {
r8Flags = append(r8Flags, "--resource-input", d.resourcesInput.Path().String())
r8Deps = append(r8Deps, d.resourcesInput.Path())
r8Flags = append(r8Flags, "--resource-output", d.resourcesOutput.Path().String())
+ if Bool(opt.Optimized_shrink_resources) {
+ r8Flags = append(r8Flags, "--optimized-resource-shrinking")
+ }
}
return r8Flags, r8Deps