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
This commit is contained in:
parent
8d80ceeb12
commit
6d415273c0
|
@ -317,32 +317,11 @@ var dex2oatDepTag = struct {
|
|||
blueprint.BaseDependencyTag
|
||||
}{}
|
||||
|
||||
type DexPreoptModule interface {
|
||||
dexPreoptModuleSignature() // Not called - only for type detection.
|
||||
}
|
||||
|
||||
// RegisterToolDepsMutator registers a mutator that adds the necessary
|
||||
// dependencies to binary modules for tools that are required later when
|
||||
// Get(Cached)GlobalSoongConfig is called. It should be passed to
|
||||
// android.RegistrationContext.FinalDepsMutators, and module types that need
|
||||
// dependencies also need to embed DexPreoptModule.
|
||||
func RegisterToolDepsMutator(ctx android.RegisterMutatorsContext) {
|
||||
ctx.BottomUp("dexpreopt_tool_deps", toolDepsMutator).Parallel()
|
||||
}
|
||||
|
||||
func toolDepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
if GetGlobalConfig(ctx).DisablePreopt {
|
||||
// Only register dependencies if dexpreopting is enabled. Necessary to avoid
|
||||
// them in non-platform builds where dex2oat etc isn't available.
|
||||
//
|
||||
// It would be nice to not register this mutator at all then, but
|
||||
// RegisterMutatorsContext available at registration doesn't have the state
|
||||
// necessary to pass as PathContext to constructPath etc.
|
||||
return
|
||||
}
|
||||
if _, ok := ctx.Module().(DexPreoptModule); !ok {
|
||||
return
|
||||
}
|
||||
// RegisterToolDeps adds the necessary dependencies to binary modules for tools
|
||||
// that are required later when Get(Cached)GlobalSoongConfig is called. It
|
||||
// should be called from a mutator that's registered with
|
||||
// android.RegistrationContext.FinalDepsMutators.
|
||||
func RegisterToolDeps(ctx android.BottomUpMutatorContext) {
|
||||
dex2oatBin := dex2oatModuleName(ctx.Config())
|
||||
v := ctx.Config().BuildOSTarget.Variations()
|
||||
ctx.AddFarVariationDependencies(v, dex2oatDepTag, dex2oatBin)
|
||||
|
@ -418,10 +397,13 @@ func GetGlobalSoongConfig(ctx android.ModuleContext) *GlobalSoongConfig {
|
|||
// GetCachedGlobalSoongConfig returns a cached GlobalSoongConfig created by an
|
||||
// earlier GetGlobalSoongConfig call. This function works with any context
|
||||
// compatible with a basic PathContext, since it doesn't try to create a
|
||||
// GlobalSoongConfig (which requires a full ModuleContext). It will panic if
|
||||
// called before the first GetGlobalSoongConfig call.
|
||||
// GlobalSoongConfig with the proper paths (which requires a full
|
||||
// ModuleContext). If there has been no prior call to GetGlobalSoongConfig, nil
|
||||
// is returned.
|
||||
func GetCachedGlobalSoongConfig(ctx android.PathContext) *GlobalSoongConfig {
|
||||
return ctx.Config().Get(globalSoongConfigOnceKey).(*GlobalSoongConfig)
|
||||
return ctx.Config().Once(globalSoongConfigOnceKey, func() interface{} {
|
||||
return (*GlobalSoongConfig)(nil)
|
||||
}).(*GlobalSoongConfig)
|
||||
}
|
||||
|
||||
type globalJsonSoongConfig struct {
|
||||
|
@ -464,6 +446,12 @@ func (s *globalSoongConfigSingleton) GenerateBuildActions(ctx android.SingletonC
|
|||
}
|
||||
|
||||
config := GetCachedGlobalSoongConfig(ctx)
|
||||
if config == nil {
|
||||
// No module has enabled dexpreopting, so we assume there will be no calls
|
||||
// to dexpreopt_gen.
|
||||
return
|
||||
}
|
||||
|
||||
jc := globalJsonSoongConfig{
|
||||
Profman: config.Profman.String(),
|
||||
Dex2oat: config.Dex2oat.String(),
|
||||
|
@ -495,6 +483,9 @@ func (s *globalSoongConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
|
|||
}
|
||||
|
||||
config := GetCachedGlobalSoongConfig(ctx)
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Strict("DEX2OAT", config.Dex2oat.String())
|
||||
ctx.Strict("DEXPREOPT_GEN_DEPS", strings.Join([]string{
|
||||
|
|
12
java/app.go
12
java/app.go
|
@ -27,7 +27,6 @@ import (
|
|||
|
||||
"android/soong/android"
|
||||
"android/soong/cc"
|
||||
"android/soong/dexpreopt"
|
||||
"android/soong/tradefed"
|
||||
)
|
||||
|
||||
|
@ -143,6 +142,10 @@ type AndroidApp struct {
|
|||
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 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
|
|||
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 @@ type AndroidAppImport struct {
|
|||
android.ModuleBase
|
||||
android.DefaultableModuleBase
|
||||
prebuilt android.Prebuilt
|
||||
dexpreopt.DexPreoptModule
|
||||
|
||||
properties AndroidAppImportProperties
|
||||
dpiVariants interface{}
|
||||
|
@ -924,6 +925,10 @@ type AndroidAppImportProperties struct {
|
|||
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 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext
|
|||
}
|
||||
|
||||
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)
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@ import (
|
|||
"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 @@ type dexpreopter struct {
|
|||
uncompressedDex bool
|
||||
isSDKLibrary bool
|
||||
isTest bool
|
||||
isInstallable bool
|
||||
isPresignedPrebuilt bool
|
||||
|
||||
manifestFile android.Path
|
||||
|
@ -58,7 +62,7 @@ type DexpreoptProperties struct {
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
if !d.isInstallable {
|
||||
if !ctx.Module().(dexpreopterInterface).IsInstallable() {
|
||||
return true
|
||||
}
|
||||
|
||||
if ctx.Host() {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -95,12 +103,23 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
|
|||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -205,6 +205,10 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
|
|||
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)
|
||||
|
|
27
java/java.go
27
java/java.go
|
@ -76,7 +76,9 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
|
|||
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 @@ type Module struct {
|
|||
android.DefaultableModuleBase
|
||||
android.ApexModuleBase
|
||||
android.SdkBase
|
||||
dexpreopt.DexPreoptModule
|
||||
|
||||
properties CompilerProperties
|
||||
protoProperties android.ProtoProperties
|
||||
|
@ -1577,16 +1578,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
|
|||
}
|
||||
} 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 @@ func (j *Module) JacocoReportClassesFile() android.Path {
|
|||
return j.jacocoReportClassesFile
|
||||
}
|
||||
|
||||
func (j *Module) IsInstallable() bool {
|
||||
return Bool(j.properties.Installable)
|
||||
}
|
||||
|
||||
//
|
||||
// Java libraries (.jar file)
|
||||
//
|
||||
|
@ -1831,7 +1826,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
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 @@ type Import struct {
|
|||
android.ApexModuleBase
|
||||
prebuilt android.Prebuilt
|
||||
android.SdkBase
|
||||
dexpreopt.DexPreoptModule
|
||||
|
||||
properties ImportProperties
|
||||
|
||||
|
@ -2564,7 +2557,6 @@ type DexImport struct {
|
|||
android.DefaultableModuleBase
|
||||
android.ApexModuleBase
|
||||
prebuilt android.Prebuilt
|
||||
dexpreopt.DexPreoptModule
|
||||
|
||||
properties DexImportProperties
|
||||
|
||||
|
@ -2590,13 +2582,16 @@ func (j *DexImport) Stem() string {
|
|||
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")
|
||||
|
|
Loading…
Reference in New Issue