Merge "Revert "Use R8 for resource shrinking"" into main
This commit is contained in:
commit
2e09e68e56
6 changed files with 124 additions and 46 deletions
|
@ -66,6 +66,7 @@ bootstrap_go_package {
|
||||||
"plugin.go",
|
"plugin.go",
|
||||||
"prebuilt_apis.go",
|
"prebuilt_apis.go",
|
||||||
"proto.go",
|
"proto.go",
|
||||||
|
"resourceshrinker.go",
|
||||||
"robolectric.go",
|
"robolectric.go",
|
||||||
"rro.go",
|
"rro.go",
|
||||||
"sdk.go",
|
"sdk.go",
|
||||||
|
@ -105,6 +106,7 @@ bootstrap_go_package {
|
||||||
"plugin_test.go",
|
"plugin_test.go",
|
||||||
"prebuilt_apis_test.go",
|
"prebuilt_apis_test.go",
|
||||||
"proto_test.go",
|
"proto_test.go",
|
||||||
|
"resourceshrinker_test.go",
|
||||||
"rro_test.go",
|
"rro_test.go",
|
||||||
"sdk_test.go",
|
"sdk_test.go",
|
||||||
"sdk_library_test.go",
|
"sdk_library_test.go",
|
||||||
|
|
24
java/app.go
24
java/app.go
|
@ -532,7 +532,7 @@ func (a *AndroidApp) installPath(ctx android.ModuleContext) android.InstallPath
|
||||||
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
|
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
|
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
||||||
a.dexpreopter.installPath = a.installPath(ctx)
|
a.dexpreopter.installPath = a.installPath(ctx)
|
||||||
a.dexpreopter.isApp = true
|
a.dexpreopter.isApp = true
|
||||||
if a.dexProperties.Uncompress_dex == nil {
|
if a.dexProperties.Uncompress_dex == nil {
|
||||||
|
@ -545,15 +545,7 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, a
|
||||||
a.dexpreopter.manifestFile = a.mergedManifestFile
|
a.dexpreopter.manifestFile = a.mergedManifestFile
|
||||||
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
|
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
|
||||||
|
|
||||||
var packageResources = a.exportPackage
|
|
||||||
|
|
||||||
if ctx.ModuleName() != "framework-res" {
|
if ctx.ModuleName() != "framework-res" {
|
||||||
if Bool(a.dexProperties.Optimize.Shrink_resources) {
|
|
||||||
protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
|
|
||||||
aapt2Convert(ctx, protoFile, packageResources, "proto")
|
|
||||||
a.dexer.resourcesInput = android.OptionalPathForPath(protoFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
var extraSrcJars android.Paths
|
var extraSrcJars android.Paths
|
||||||
var extraClasspathJars android.Paths
|
var extraClasspathJars android.Paths
|
||||||
var extraCombinedJars android.Paths
|
var extraCombinedJars android.Paths
|
||||||
|
@ -571,14 +563,9 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, a
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
|
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
|
||||||
if Bool(a.dexProperties.Optimize.Shrink_resources) {
|
|
||||||
binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
|
|
||||||
aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
|
|
||||||
packageResources = binaryResources
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.dexJarFile.PathOrNil(), packageResources
|
return a.dexJarFile.PathOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
|
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
|
||||||
|
@ -763,6 +750,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
|
|
||||||
// Process all building blocks, from AAPT to certificates.
|
// Process all building blocks, from AAPT to certificates.
|
||||||
a.aaptBuildActions(ctx)
|
a.aaptBuildActions(ctx)
|
||||||
|
|
||||||
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
|
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
|
||||||
a.usesLibrary.freezeEnforceUsesLibraries()
|
a.usesLibrary.freezeEnforceUsesLibraries()
|
||||||
|
|
||||||
|
@ -788,7 +776,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
a.linter.resources = a.aapt.resourceFiles
|
a.linter.resources = a.aapt.resourceFiles
|
||||||
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
|
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
|
||||||
|
|
||||||
dexJarFile, packageResources := a.dexBuildActions(ctx)
|
dexJarFile := a.dexBuildActions(ctx)
|
||||||
|
|
||||||
jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
|
jniLibs, prebuiltJniPackages, certificates := collectAppDeps(ctx, a, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
|
||||||
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
|
jniJarFile := a.jniBuildActions(jniLibs, prebuiltJniPackages, ctx)
|
||||||
|
@ -812,7 +800,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
}
|
}
|
||||||
rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
|
rotationMinSdkVersion := String(a.overridableAppProperties.RotationMinSdkVersion)
|
||||||
|
|
||||||
CreateAndSignAppPackage(ctx, packageFile, packageResources, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
|
CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, Bool(a.dexProperties.Optimize.Shrink_resources))
|
||||||
a.outputFile = packageFile
|
a.outputFile = packageFile
|
||||||
if v4SigningRequested {
|
if v4SigningRequested {
|
||||||
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
|
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
|
||||||
|
@ -841,7 +829,7 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
if v4SigningRequested {
|
if v4SigningRequested {
|
||||||
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
|
v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
|
||||||
}
|
}
|
||||||
CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion)
|
CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile, rotationMinSdkVersion, false)
|
||||||
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
|
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
|
||||||
if v4SigningRequested {
|
if v4SigningRequested {
|
||||||
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
|
a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
|
||||||
|
|
|
@ -52,7 +52,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk",
|
||||||
})
|
})
|
||||||
|
|
||||||
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
|
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
|
||||||
packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string) {
|
packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path, rotationMinSdkVersion string, shrinkResources bool) {
|
||||||
|
|
||||||
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
|
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
|
||||||
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
|
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
|
||||||
|
@ -71,6 +71,12 @@ func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.Writa
|
||||||
Output: unsignedApk,
|
Output: unsignedApk,
|
||||||
Implicits: deps,
|
Implicits: deps,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if shrinkResources {
|
||||||
|
shrunkenApk := android.PathForModuleOut(ctx, "resource-shrunken", unsignedApk.Base())
|
||||||
|
ShrinkResources(ctx, unsignedApk, shrunkenApk)
|
||||||
|
unsignedApk = shrunkenApk
|
||||||
|
}
|
||||||
SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile, rotationMinSdkVersion)
|
SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile, rotationMinSdkVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
27
java/dex.go
27
java/dex.go
|
@ -95,8 +95,6 @@ type dexer struct {
|
||||||
proguardDictionary android.OptionalPath
|
proguardDictionary android.OptionalPath
|
||||||
proguardConfiguration android.OptionalPath
|
proguardConfiguration android.OptionalPath
|
||||||
proguardUsageZip android.OptionalPath
|
proguardUsageZip android.OptionalPath
|
||||||
resourcesInput android.OptionalPath
|
|
||||||
resourcesOutput android.OptionalPath
|
|
||||||
|
|
||||||
providesTransitiveHeaderJars
|
providesTransitiveHeaderJars
|
||||||
}
|
}
|
||||||
|
@ -163,7 +161,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
|
||||||
"$r8Template": &remoteexec.REParams{
|
"$r8Template": &remoteexec.REParams{
|
||||||
Labels: map[string]string{"type": "compile", "compiler": "r8"},
|
Labels: map[string]string{"type": "compile", "compiler": "r8"},
|
||||||
Inputs: []string{"$implicits", "${config.R8Jar}"},
|
Inputs: []string{"$implicits", "${config.R8Jar}"},
|
||||||
OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}"},
|
OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}"},
|
||||||
ExecStrategy: "${config.RER8ExecStrategy}",
|
ExecStrategy: "${config.RER8ExecStrategy}",
|
||||||
ToolchainInputs: []string{"${config.JavaCmd}"},
|
ToolchainInputs: []string{"${config.JavaCmd}"},
|
||||||
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
|
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
|
||||||
|
@ -183,7 +181,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
|
||||||
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
|
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
|
||||||
},
|
},
|
||||||
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
|
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
|
||||||
"r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput"}, []string{"implicits"})
|
"r8Flags", "zipFlags", "mergeZipsFlags"}, []string{"implicits"})
|
||||||
|
|
||||||
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
|
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
|
||||||
dexParams *compileDexParams) (flags []string, deps android.Paths) {
|
dexParams *compileDexParams) (flags []string, deps android.Paths) {
|
||||||
|
@ -352,12 +350,6 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Fl
|
||||||
r8Flags = append(r8Flags, "-ignorewarnings")
|
r8Flags = append(r8Flags, "-ignorewarnings")
|
||||||
}
|
}
|
||||||
|
|
||||||
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())
|
|
||||||
}
|
|
||||||
|
|
||||||
return r8Flags, r8Deps
|
return r8Flags, r8Deps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,8 +391,6 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
|
||||||
android.ModuleNameWithPossibleOverride(ctx), "unused.txt")
|
android.ModuleNameWithPossibleOverride(ctx), "unused.txt")
|
||||||
proguardUsageZip := android.PathForModuleOut(ctx, "proguard_usage.zip")
|
proguardUsageZip := android.PathForModuleOut(ctx, "proguard_usage.zip")
|
||||||
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
|
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
|
||||||
resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk")
|
|
||||||
d.resourcesOutput = android.OptionalPathForPath(resourcesOutput)
|
|
||||||
r8Flags, r8Deps := d.r8Flags(ctx, dexParams.flags)
|
r8Flags, r8Deps := d.r8Flags(ctx, dexParams.flags)
|
||||||
r8Deps = append(r8Deps, commonDeps...)
|
r8Deps = append(r8Deps, commonDeps...)
|
||||||
rule := r8
|
rule := r8
|
||||||
|
@ -419,19 +409,14 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
|
||||||
rule = r8RE
|
rule = r8RE
|
||||||
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
|
args["implicits"] = strings.Join(r8Deps.Strings(), ",")
|
||||||
}
|
}
|
||||||
implicitOutputs := android.WritablePaths{
|
|
||||||
proguardDictionary,
|
|
||||||
proguardUsageZip,
|
|
||||||
proguardConfiguration}
|
|
||||||
if d.resourcesInput.Valid() {
|
|
||||||
implicitOutputs = append(implicitOutputs, resourcesOutput)
|
|
||||||
args["resourcesOutput"] = resourcesOutput.String()
|
|
||||||
}
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: rule,
|
Rule: rule,
|
||||||
Description: "r8",
|
Description: "r8",
|
||||||
Output: javalibJar,
|
Output: javalibJar,
|
||||||
ImplicitOutputs: implicitOutputs,
|
ImplicitOutputs: android.WritablePaths{
|
||||||
|
proguardDictionary,
|
||||||
|
proguardUsageZip,
|
||||||
|
proguardConfiguration},
|
||||||
Input: dexParams.classesJar,
|
Input: dexParams.classesJar,
|
||||||
Implicits: r8Deps,
|
Implicits: r8Deps,
|
||||||
Args: args,
|
Args: args,
|
||||||
|
|
44
java/resourceshrinker.go
Normal file
44
java/resourceshrinker.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2022 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package java
|
||||||
|
|
||||||
|
import (
|
||||||
|
"android/soong/android"
|
||||||
|
|
||||||
|
"github.com/google/blueprint"
|
||||||
|
)
|
||||||
|
|
||||||
|
var shrinkResources = pctx.AndroidStaticRule("shrinkResources",
|
||||||
|
blueprint.RuleParams{
|
||||||
|
// Note that we suppress stdout to avoid successful log confirmations.
|
||||||
|
Command: `${config.ResourceShrinkerCmd} --output $out --input $in --raw_resources $raw_resources >/dev/null`,
|
||||||
|
CommandDeps: []string{"${config.ResourceShrinkerCmd}"},
|
||||||
|
}, "raw_resources")
|
||||||
|
|
||||||
|
func ShrinkResources(ctx android.ModuleContext, apk android.Path, outputFile android.WritablePath) {
|
||||||
|
protoFile := android.PathForModuleOut(ctx, apk.Base()+".proto.apk")
|
||||||
|
aapt2Convert(ctx, protoFile, apk, "proto")
|
||||||
|
strictModeFile := android.PathForSource(ctx, "prebuilts/cmdline-tools/shrinker.xml")
|
||||||
|
protoOut := android.PathForModuleOut(ctx, apk.Base()+".proto.out.apk")
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: shrinkResources,
|
||||||
|
Input: protoFile,
|
||||||
|
Output: protoOut,
|
||||||
|
Args: map[string]string{
|
||||||
|
"raw_resources": strictModeFile.String(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
aapt2Convert(ctx, outputFile, protoOut, "binary")
|
||||||
|
}
|
53
java/resourceshrinker_test.go
Normal file
53
java/resourceshrinker_test.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright 2022 Google Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package java
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"android/soong/android"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestShrinkResourcesArgs(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
PrepareForTestWithJavaDefaultModules,
|
||||||
|
).RunTestWithBp(t, `
|
||||||
|
android_app {
|
||||||
|
name: "app_shrink",
|
||||||
|
platform_apis: true,
|
||||||
|
optimize: {
|
||||||
|
shrink_resources: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
android_app {
|
||||||
|
name: "app_no_shrink",
|
||||||
|
platform_apis: true,
|
||||||
|
optimize: {
|
||||||
|
shrink_resources: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
appShrink := result.ModuleForTests("app_shrink", "android_common")
|
||||||
|
appShrinkResources := appShrink.Rule("shrinkResources")
|
||||||
|
android.AssertStringDoesContain(t, "expected shrinker.xml in app_shrink resource shrinker flags",
|
||||||
|
appShrinkResources.Args["raw_resources"], "shrinker.xml")
|
||||||
|
|
||||||
|
appNoShrink := result.ModuleForTests("app_no_shrink", "android_common")
|
||||||
|
if appNoShrink.MaybeRule("shrinkResources").Rule != nil {
|
||||||
|
t.Errorf("unexpected shrinkResources rule for app_no_shrink")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue