Never strip and store dex files uncompressed when they are preopted on system.
In order for the runtime module to always be able to compile apps, make sure we keep a copy of the dex files optimally. Gated by a product flag if a product doesn't include the module yet. Test: build Change-Id: I4bfe00184fcfdf44b8d1866c5c550838b869c60a
This commit is contained in:
parent
eebdf43337
commit
4bb0106759
|
@ -47,6 +47,7 @@ type GlobalConfig struct {
|
||||||
SystemServerCompilerFilter string // default compiler filter to pass to dex2oat for system server jars
|
SystemServerCompilerFilter string // default compiler filter to pass to dex2oat for system server jars
|
||||||
|
|
||||||
GenerateDMFiles bool // generate Dex Metadata files
|
GenerateDMFiles bool // generate Dex Metadata files
|
||||||
|
NeverAllowStripping bool // whether stripping should not be done - used as build time check to make sure dex files are always available
|
||||||
|
|
||||||
NoDebugInfo bool // don't generate debug info by default
|
NoDebugInfo bool // don't generate debug info by default
|
||||||
AlwaysSystemServerDebugInfo bool // always generate mini debug info for system server modules (overrides NoDebugInfo=true)
|
AlwaysSystemServerDebugInfo bool // always generate mini debug info for system server modules (overrides NoDebugInfo=true)
|
||||||
|
|
|
@ -68,6 +68,9 @@ func GenerateStripRule(global GlobalConfig, module ModuleConfig) (rule *android.
|
||||||
strip := shouldStripDex(module, global)
|
strip := shouldStripDex(module, global)
|
||||||
|
|
||||||
if strip {
|
if strip {
|
||||||
|
if global.NeverAllowStripping {
|
||||||
|
panic(fmt.Errorf("Stripping requested on %q, though the product does not allow it", module.DexLocation))
|
||||||
|
}
|
||||||
// Only strips if the dex files are not already uncompressed
|
// Only strips if the dex files are not already uncompressed
|
||||||
rule.Command().
|
rule.Command().
|
||||||
Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, module.StripInputPath).
|
Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, module.StripInputPath).
|
||||||
|
@ -499,7 +502,7 @@ func shouldGenerateDM(module ModuleConfig, global GlobalConfig) bool {
|
||||||
contains(module.PreoptFlags, "--compiler-filter=verify")
|
contains(module.PreoptFlags, "--compiler-filter=verify")
|
||||||
}
|
}
|
||||||
|
|
||||||
func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
|
func OdexOnSystemOtherByName(name string, dexLocation string, global GlobalConfig) bool {
|
||||||
if !global.HasSystemOther {
|
if !global.HasSystemOther {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -508,12 +511,12 @@ func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if contains(global.SpeedApps, module.Name) || contains(global.SystemServerApps, module.Name) {
|
if contains(global.SpeedApps, name) || contains(global.SystemServerApps, name) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range global.PatternsOnSystemOther {
|
for _, f := range global.PatternsOnSystemOther {
|
||||||
if makefileMatch(filepath.Join(SystemPartition, f), module.DexLocation) {
|
if makefileMatch(filepath.Join(SystemPartition, f), dexLocation) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -521,6 +524,10 @@ func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func odexOnSystemOther(module ModuleConfig, global GlobalConfig) bool {
|
||||||
|
return OdexOnSystemOtherByName(module.Name, module.DexLocation, global)
|
||||||
|
}
|
||||||
|
|
||||||
func pathForLibrary(module ModuleConfig, lib string) string {
|
func pathForLibrary(module ModuleConfig, lib string) string {
|
||||||
path := module.LibraryPaths[lib]
|
path := module.LibraryPaths[lib]
|
||||||
if path == "" {
|
if path == "" {
|
||||||
|
|
|
@ -36,6 +36,7 @@ var testGlobalConfig = GlobalConfig{
|
||||||
DefaultCompilerFilter: "",
|
DefaultCompilerFilter: "",
|
||||||
SystemServerCompilerFilter: "",
|
SystemServerCompilerFilter: "",
|
||||||
GenerateDMFiles: false,
|
GenerateDMFiles: false,
|
||||||
|
NeverAllowStripping: false,
|
||||||
NoDebugInfo: false,
|
NoDebugInfo: false,
|
||||||
AlwaysSystemServerDebugInfo: false,
|
AlwaysSystemServerDebugInfo: false,
|
||||||
NeverSystemServerDebugInfo: false,
|
NeverSystemServerDebugInfo: false,
|
||||||
|
@ -110,6 +111,23 @@ func TestDexPreopt(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDexPreoptStrip(t *testing.T) {
|
||||||
|
// Test that we panic if we strip in a configuration where stripping is not allowed.
|
||||||
|
global, module := testGlobalConfig, testModuleConfig
|
||||||
|
|
||||||
|
global.NeverAllowStripping = true
|
||||||
|
module.NoStripping = false
|
||||||
|
module.Name = "test"
|
||||||
|
module.DexLocation = "/system/app/test/test.apk"
|
||||||
|
module.BuildPath = "out/test/test.apk"
|
||||||
|
module.Archs = []string{"arm"}
|
||||||
|
|
||||||
|
_, err := GenerateStripRule(global, module)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected an error when calling GenerateStripRule on a stripped module")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDexPreoptSystemOther(t *testing.T) {
|
func TestDexPreoptSystemOther(t *testing.T) {
|
||||||
global, module := testGlobalConfig, testModuleConfig
|
global, module := testGlobalConfig, testModuleConfig
|
||||||
|
|
||||||
|
|
17
java/app.go
17
java/app.go
|
@ -162,9 +162,18 @@ func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncompress dex in APKs of privileged apps, and modules used by privileged apps.
|
// Uncompress dex in APKs of privileged apps, and modules used by privileged apps.
|
||||||
return ctx.Config().UncompressPrivAppDex() &&
|
if ctx.Config().UncompressPrivAppDex() &&
|
||||||
(Bool(a.appProperties.Privileged) ||
|
(Bool(a.appProperties.Privileged) ||
|
||||||
inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()))
|
inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules())) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncompress if the dex files is preopted on /system.
|
||||||
|
if !a.dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, a.dexpreopter.installPath)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) {
|
||||||
|
@ -223,7 +232,6 @@ func (a *AndroidApp) proguardBuildActions(ctx android.ModuleContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
||||||
a.deviceProperties.UncompressDex = a.shouldUncompressDex(ctx)
|
|
||||||
|
|
||||||
var installDir string
|
var installDir string
|
||||||
if ctx.ModuleName() == "framework-res" {
|
if ctx.ModuleName() == "framework-res" {
|
||||||
|
@ -235,6 +243,9 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
||||||
installDir = filepath.Join("app", a.installApkName)
|
installDir = filepath.Join("app", a.installApkName)
|
||||||
}
|
}
|
||||||
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
|
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
|
||||||
|
a.dexpreopter.isInstallable = Bool(a.properties.Installable)
|
||||||
|
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
|
||||||
|
a.deviceProperties.UncompressDex = a.dexpreopter.uncompressedDex
|
||||||
|
|
||||||
if ctx.ModuleName() != "framework-res" {
|
if ctx.ModuleName() != "framework-res" {
|
||||||
a.Module.compile(ctx, a.aaptSrcJar)
|
a.Module.compile(ctx, a.aaptSrcJar)
|
||||||
|
|
|
@ -83,11 +83,7 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
|
||||||
|
|
||||||
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
|
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
|
||||||
|
|
||||||
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath {
|
func getGlobalConfig(ctx android.ModuleContext) dexpreopt.GlobalConfig {
|
||||||
if d.dexpreoptDisabled(ctx) {
|
|
||||||
return dexJarFile
|
|
||||||
}
|
|
||||||
|
|
||||||
globalConfig := ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
|
globalConfig := ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
|
||||||
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
|
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
|
||||||
ctx.AddNinjaFileDeps(f)
|
ctx.AddNinjaFileDeps(f)
|
||||||
|
@ -99,6 +95,19 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
||||||
}
|
}
|
||||||
return dexpreopt.GlobalConfig{}
|
return dexpreopt.GlobalConfig{}
|
||||||
}).(dexpreopt.GlobalConfig)
|
}).(dexpreopt.GlobalConfig)
|
||||||
|
return globalConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func odexOnSystemOther(ctx android.ModuleContext, installPath android.OutputPath) bool {
|
||||||
|
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), getGlobalConfig(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath {
|
||||||
|
if d.dexpreoptDisabled(ctx) {
|
||||||
|
return dexJarFile
|
||||||
|
}
|
||||||
|
|
||||||
|
globalConfig := getGlobalConfig(ctx)
|
||||||
|
|
||||||
var archs []string
|
var archs []string
|
||||||
for _, a := range ctx.MultiTargets() {
|
for _, a := range ctx.MultiTargets() {
|
||||||
|
|
17
java/java.go
17
java/java.go
|
@ -1239,8 +1239,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
|
||||||
j.dexJarFile = dexOutputFile
|
j.dexJarFile = dexOutputFile
|
||||||
|
|
||||||
// Dexpreopting
|
// Dexpreopting
|
||||||
j.dexpreopter.isInstallable = Bool(j.properties.Installable)
|
|
||||||
j.dexpreopter.uncompressedDex = j.deviceProperties.UncompressDex
|
|
||||||
dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
|
dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
|
||||||
|
|
||||||
j.maybeStrippedDexJarFile = dexOutputFile
|
j.maybeStrippedDexJarFile = dexOutputFile
|
||||||
|
@ -1417,10 +1415,13 @@ type Library struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *Library) shouldUncompressDex(ctx android.ModuleContext) bool {
|
func (j *Library) shouldUncompressDex(ctx android.ModuleContext) bool {
|
||||||
// Store uncompressed (and do not strip) dex files from boot class path jars that are
|
// Store uncompressed (and do not strip) dex files from boot class path jars.
|
||||||
// in an apex.
|
if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
|
||||||
if inList(ctx.ModuleName(), ctx.Config().BootJars()) &&
|
return true
|
||||||
android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
|
}
|
||||||
|
|
||||||
|
// Store uncompressed dex files that are preopted on /system.
|
||||||
|
if !j.dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, j.dexpreopter.installPath)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if ctx.Config().UncompressPrivAppDex() &&
|
if ctx.Config().UncompressPrivAppDex() &&
|
||||||
|
@ -1434,7 +1435,9 @@ func (j *Library) shouldUncompressDex(ctx android.ModuleContext) bool {
|
||||||
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
|
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
|
||||||
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
|
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
|
||||||
j.deviceProperties.UncompressDex = j.shouldUncompressDex(ctx)
|
j.dexpreopter.isInstallable = Bool(j.properties.Installable)
|
||||||
|
j.dexpreopter.uncompressedDex = j.shouldUncompressDex(ctx)
|
||||||
|
j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
|
||||||
j.compile(ctx)
|
j.compile(ctx)
|
||||||
|
|
||||||
if (Bool(j.properties.Installable) || ctx.Host()) && !android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
|
if (Bool(j.properties.Installable) || ctx.Host()) && !android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
|
||||||
|
|
Loading…
Reference in New Issue