Do all dexpreoptDisabled checks before registering a dex2oat host dep.
Also disable dexpreopting for host. These are necessary to avoid adding
dependencies on dex2oat in various non-platform builds where they will
break.
Since we cannot assume at least one module enables dexpreopting now,
the two dexpreopt singletons are silently disabled if there has been no
call to dexpreopt.GetGlobalSoongConfig.
Bug: 145934348
Bug: 148312086
Bug: 148319588
Bug: 148690468
Test: m
Test: env OUT_DIR=out-tools prebuilts/build-tools/build-prebuilts.sh
on the aosp-build-tools branch
Test: build/soong/soong_ui.bash --make-mode static_sdk_tools dist DIST_DIR=out-dist BUILD_HOST_static=1
on internal (cf b/148312086#comment8)
Test: build/soong/soong_ui.bash --make-mode dist DIST_DIR=out-apps TARGET_BUILD_APPS=Launcher3 TARGET_BUILD_VARIANT=userdebug
on internal without art/ and external/vixl/ (cf b/148319588)
Change-Id: I240dade7204b87fc2d12181534ab23439eca8b46
diff --git a/java/app.go b/java/app.go
index f55fc45..02f3e7f 100755
--- a/java/app.go
+++ b/java/app.go
@@ -27,7 +27,6 @@
"android/soong/android"
"android/soong/cc"
- "android/soong/dexpreopt"
"android/soong/tradefed"
)
@@ -143,6 +142,10 @@
noticeOutputs android.NoticeOutputs
}
+func (a *AndroidApp) IsInstallable() bool {
+ return Bool(a.properties.Installable)
+}
+
func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
return nil
}
@@ -339,7 +342,6 @@
installDir = filepath.Join("app", a.installApkName)
}
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
- a.dexpreopter.isInstallable = Bool(a.properties.Installable)
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
@@ -876,7 +878,6 @@
android.ModuleBase
android.DefaultableModuleBase
prebuilt android.Prebuilt
- dexpreopt.DexPreoptModule
properties AndroidAppImportProperties
dpiVariants interface{}
@@ -924,6 +925,10 @@
Filename *string
}
+func (a *AndroidAppImport) IsInstallable() bool {
+ return true
+}
+
// Updates properties with variant-specific values.
func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) {
config := ctx.Config()
@@ -1066,7 +1071,6 @@
}
a.dexpreopter.installPath = installDir.Join(ctx, a.BaseModuleName()+".apk")
- a.dexpreopter.isInstallable = true
a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 2b87cf7..4313964 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -19,6 +19,11 @@
"android/soong/dexpreopt"
)
+type dexpreopterInterface interface {
+ IsInstallable() bool // Structs that embed dexpreopter must implement this.
+ dexpreoptDisabled(ctx android.BaseModuleContext) bool
+}
+
type dexpreopter struct {
dexpreoptProperties DexpreoptProperties
@@ -26,7 +31,6 @@
uncompressedDex bool
isSDKLibrary bool
isTest bool
- isInstallable bool
isPresignedPrebuilt bool
manifestFile android.Path
@@ -58,7 +62,7 @@
}
}
-func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
+func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
global := dexpreopt.GetGlobalConfig(ctx)
if global.DisablePreopt {
@@ -81,7 +85,11 @@
return true
}
- if !d.isInstallable {
+ if !ctx.Module().(dexpreopterInterface).IsInstallable() {
+ return true
+ }
+
+ if ctx.Host() {
return true
}
@@ -95,12 +103,23 @@
return false
}
+func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) {
+ if d, ok := ctx.Module().(dexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) {
+ return
+ }
+ dexpreopt.RegisterToolDeps(ctx)
+}
+
func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
}
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath {
- if d.dexpreoptDisabled(ctx) {
+ // TODO(b/148690468): The check on d.installPath is to bail out in cases where
+ // the dexpreopter struct hasn't been fully initialized before we're called,
+ // e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively
+ // disabled, even if installable is true.
+ if d.dexpreoptDisabled(ctx) || d.installPath.Base() == "." {
return dexJarFile
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 2a2e6da..655a476 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -205,6 +205,10 @@
if skipDexpreoptBootJars(ctx) {
return
}
+ if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil {
+ // No module has enabled dexpreopting, so we assume there will be no boot image to make.
+ return
+ }
d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config")
writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
diff --git a/java/java.go b/java/java.go
index 2e53654..ceedd89 100644
--- a/java/java.go
+++ b/java/java.go
@@ -76,7 +76,9 @@
ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
ctx.RegisterModuleType("dex_import", DexImportFactory)
- ctx.FinalDepsMutators(dexpreopt.RegisterToolDepsMutator)
+ ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel()
+ })
ctx.RegisterSingletonType("logtags", LogtagsSingleton)
ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
@@ -371,7 +373,6 @@
android.DefaultableModuleBase
android.ApexModuleBase
android.SdkBase
- dexpreopt.DexPreoptModule
properties CompilerProperties
protoProperties android.ProtoProperties
@@ -1577,16 +1578,6 @@
}
} else {
outputFile = implementationAndResourcesJar
-
- // dexpreopt.GetGlobalSoongConfig needs to be called at least once even if
- // no module actually is dexpreopted, to ensure there's a cached
- // GlobalSoongConfig for the dexpreopt singletons, which will run
- // regardless.
- // TODO(b/147613152): Remove when the singletons no longer rely on the
- // cached GlobalSoongConfig.
- if !dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
- _ = dexpreopt.GetGlobalSoongConfig(ctx)
- }
}
ctx.CheckbuildFile(outputFile)
@@ -1794,6 +1785,10 @@
return j.jacocoReportClassesFile
}
+func (j *Module) IsInstallable() bool {
+ return Bool(j.properties.Installable)
+}
+
//
// Java libraries (.jar file)
//
@@ -1831,7 +1826,6 @@
j.checkSdkVersion(ctx)
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- j.dexpreopter.isInstallable = Bool(j.properties.Installable)
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
j.compile(ctx, nil)
@@ -2353,7 +2347,6 @@
android.ApexModuleBase
prebuilt android.Prebuilt
android.SdkBase
- dexpreopt.DexPreoptModule
properties ImportProperties
@@ -2564,7 +2557,6 @@
android.DefaultableModuleBase
android.ApexModuleBase
prebuilt android.Prebuilt
- dexpreopt.DexPreoptModule
properties DexImportProperties
@@ -2590,13 +2582,16 @@
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}
+func (j *DexImport) IsInstallable() bool {
+ return true
+}
+
func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(j.properties.Jars) != 1 {
ctx.PropertyErrorf("jars", "exactly one jar must be provided")
}
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
- j.dexpreopter.isInstallable = true
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")