diff --git a/dexpreopt/config.go b/dexpreopt/config.go index 63d55df7f..cd74ec847 100644 --- a/dexpreopt/config.go +++ b/dexpreopt/config.go @@ -176,10 +176,9 @@ func constructWritablePath(ctx android.PathContext, path string) android.Writabl return constructPath(ctx, path).(android.WritablePath) } -// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig -// struct. LoadGlobalConfig is used directly in Soong and in dexpreopt_gen -// called from Make to read the $OUT/dexpreopt.config written by Make. -func LoadGlobalConfig(ctx android.PathContext, data []byte) (GlobalConfig, error) { +// ParseGlobalConfig parses the given data assumed to be read from the global +// dexpreopt.config file into a GlobalConfig struct. +func ParseGlobalConfig(ctx android.PathContext, data []byte) (GlobalConfig, error) { type GlobalJSONConfig struct { GlobalConfig @@ -202,10 +201,65 @@ func LoadGlobalConfig(ctx android.PathContext, data []byte) (GlobalConfig, error return config.GlobalConfig, nil } -// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct. It is not used in Soong, which -// receives a ModuleConfig struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called from oMake to -// read the module dexpreopt.config written by Make. -func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) { +type globalConfigAndRaw struct { + global GlobalConfig + data []byte +} + +// GetGlobalConfig returns the global dexpreopt.config that's created in the +// make config phase. It is loaded once the first time it is called for any +// ctx.Config(), and returns the same data for all future calls with the same +// ctx.Config(). A value can be inserted for tests using +// setDexpreoptTestGlobalConfig. +func GetGlobalConfig(ctx android.PathContext) GlobalConfig { + return getGlobalConfigRaw(ctx).global +} + +// GetGlobalConfigRawData is the same as GetGlobalConfig, except that it returns +// the literal content of dexpreopt.config. +func GetGlobalConfigRawData(ctx android.PathContext) []byte { + return getGlobalConfigRaw(ctx).data +} + +var globalConfigOnceKey = android.NewOnceKey("DexpreoptGlobalConfig") +var testGlobalConfigOnceKey = android.NewOnceKey("TestDexpreoptGlobalConfig") + +func getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw { + return ctx.Config().Once(globalConfigOnceKey, func() interface{} { + if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil { + panic(err) + } else if data != nil { + globalConfig, err := ParseGlobalConfig(ctx, data) + if err != nil { + panic(err) + } + return globalConfigAndRaw{globalConfig, data} + } + + // No global config filename set, see if there is a test config set + return ctx.Config().Once(testGlobalConfigOnceKey, func() interface{} { + // Nope, return a config with preopting disabled + return globalConfigAndRaw{GlobalConfig{ + DisablePreopt: true, + DisableGenerateProfile: true, + }, nil} + }) + }).(globalConfigAndRaw) +} + +// SetTestGlobalConfig sets a GlobalConfig that future calls to GetGlobalConfig +// will return. It must be called before the first call to GetGlobalConfig for +// the config. +func SetTestGlobalConfig(config android.Config, globalConfig GlobalConfig) { + config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} }) +} + +// ParseModuleConfig parses a per-module dexpreopt.config file into a +// ModuleConfig struct. It is not used in Soong, which receives a ModuleConfig +// struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called +// from Make to read the module dexpreopt.config written in the Make config +// stage. +func ParseModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) { type ModuleJSONConfig struct { ModuleConfig @@ -304,9 +358,10 @@ type globalJsonSoongConfig struct { ConstructContext string } -// LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a -// GlobalSoongConfig struct. It is only used in dexpreopt_gen. -func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) { +// ParseGlobalSoongConfig parses the given data assumed to be read from the +// global dexpreopt_soong.config file into a GlobalSoongConfig struct. It is +// only used in dexpreopt_gen. +func ParseGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) { var jc globalJsonSoongConfig err := json.Unmarshal(data, &jc) diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go index 708bb9b23..4da003e11 100644 --- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go +++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go @@ -84,9 +84,9 @@ func main() { os.Exit(2) } - globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, globalSoongConfigData) + globalSoongConfig, err := dexpreopt.ParseGlobalSoongConfig(ctx, globalSoongConfigData) if err != nil { - fmt.Fprintf(os.Stderr, "error loading global Soong config %q: %s\n", *globalSoongConfigPath, err) + fmt.Fprintf(os.Stderr, "error parsing global Soong config %q: %s\n", *globalSoongConfigPath, err) os.Exit(2) } @@ -96,9 +96,9 @@ func main() { os.Exit(2) } - globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, globalConfigData) + globalConfig, err := dexpreopt.ParseGlobalConfig(ctx, globalConfigData) if err != nil { - fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err) + fmt.Fprintf(os.Stderr, "error parsing global config %q: %s\n", *globalConfigPath, err) os.Exit(2) } @@ -108,9 +108,9 @@ func main() { os.Exit(2) } - moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, moduleConfigData) + moduleConfig, err := dexpreopt.ParseModuleConfig(ctx, moduleConfigData) if err != nil { - fmt.Fprintf(os.Stderr, "error loading module config %q: %s\n", *moduleConfigPath, err) + fmt.Fprintf(os.Stderr, "error parsing module config %q: %s\n", *moduleConfigPath, err) os.Exit(2) } diff --git a/java/dexpreopt.go b/java/dexpreopt.go index 0734b3fce..0fd1f28f9 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -59,7 +59,7 @@ type DexpreoptProperties struct { } func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool { - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) if global.DisablePreopt { return true @@ -96,7 +96,7 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool { } func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool { - return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx)) + return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx)) } func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath { @@ -105,7 +105,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo } globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) bootImage := defaultBootImageConfig(ctx) if global.UseApexImage { bootImage = frameworkJZBootImageConfig(ctx) diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index a497b08fc..0082d038a 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -162,7 +162,7 @@ func dexpreoptBootJarsFactory() android.Singleton { } func skipDexpreoptBootJars(ctx android.PathContext) bool { - if dexpreoptGlobalConfig(ctx).DisablePreopt { + if dexpreopt.GetGlobalConfig(ctx).DisablePreopt { return true } @@ -195,7 +195,7 @@ func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]and files := artBootImageConfig(ctx).imagesDeps // For JIT-zygote config, also include dexpreopt files for the primary JIT-zygote image. - if dexpreoptGlobalConfig(ctx).UseApexImage { + if dexpreopt.GetGlobalConfig(ctx).UseApexImage { for arch, paths := range artJZBootImageConfig(ctx).imagesDeps { files[arch] = append(files[arch], paths...) } @@ -213,7 +213,7 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) { d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config") writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake) - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) // Skip recompiling the boot image for the second sanitization phase. We'll get separate paths // and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds. @@ -305,7 +305,7 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage, arch android.ArchType, profile android.Path, missingDeps []string) android.WritablePaths { globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx) - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String()) symbolsFile := symbolsDir.Join(ctx, image.stem+".oat") @@ -444,7 +444,7 @@ Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath { globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx) - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() { return nil @@ -499,7 +499,7 @@ var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule") func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath { globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx) - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) if global.DisableGenerateProfile || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() { return nil @@ -587,7 +587,7 @@ func dumpOatRules(ctx android.SingletonContext, image *bootImage) { } func writeGlobalConfigForMake(ctx android.SingletonContext, path android.WritablePath) { - data := dexpreoptGlobalConfigRaw(ctx).data + data := dexpreopt.GetGlobalConfigRawData(ctx) ctx.Build(pctx, android.BuildParams{ Rule: android.WriteFile, diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go index 4ce30f678..c3b2133a9 100644 --- a/java/dexpreopt_bootjars_test.go +++ b/java/dexpreopt_bootjars_test.go @@ -49,7 +49,7 @@ func TestDexpreoptBootJars(t *testing.T) { pathCtx := android.PathContextForTesting(config) dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx) dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"} - setDexpreoptTestGlobalConfig(config, dexpreoptConfig) + dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig) ctx := testContext() diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index f776b459f..a1a9a764c 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -22,56 +22,12 @@ import ( "android/soong/dexpreopt" ) -// dexpreoptGlobalConfig returns the global dexpreopt.config. It is loaded once the first time it is called for any -// ctx.Config(), and returns the same data for all future calls with the same ctx.Config(). A value can be inserted -// for tests using setDexpreoptTestGlobalConfig. -func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig { - return dexpreoptGlobalConfigRaw(ctx).global -} - -type globalConfigAndRaw struct { - global dexpreopt.GlobalConfig - data []byte -} - -func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw { - return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} { - if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil { - panic(err) - } else if data != nil { - globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data) - if err != nil { - panic(err) - } - return globalConfigAndRaw{globalConfig, data} - } - - // No global config filename set, see if there is a test config set - return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} { - // Nope, return a config with preopting disabled - return globalConfigAndRaw{dexpreopt.GlobalConfig{ - DisablePreopt: true, - DisableGenerateProfile: true, - }, nil} - }) - }).(globalConfigAndRaw) -} - -// setDexpreoptTestGlobalConfig sets a GlobalConfig that future calls to dexpreoptGlobalConfig will return. It must -// be called before the first call to dexpreoptGlobalConfig for the config. -func setDexpreoptTestGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) { - config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} }) -} - -var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig") -var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig") - // systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed // once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same // ctx.Config(). func systemServerClasspath(ctx android.PathContext) []string { return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string { - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) var systemServerClasspathLocations []string for _, m := range global.SystemServerJars { @@ -132,7 +88,7 @@ var ( func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { return ctx.Config().Once(bootImageConfigKey, func() interface{} { - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) targets := dexpreoptTargets(ctx) deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName()) @@ -273,7 +229,7 @@ func frameworkJZBootImageConfig(ctx android.PathContext) bootImageConfig { func defaultBootclasspath(ctx android.PathContext) []string { return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string { - global := dexpreoptGlobalConfig(ctx) + global := dexpreopt.GetGlobalConfig(ctx) image := defaultBootImageConfig(ctx) updatableBootclasspath := make([]string, len(global.UpdatableBootJars)) diff --git a/java/java_test.go b/java/java_test.go index b4795c065..f047486e6 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -99,7 +99,7 @@ func run(t *testing.T, ctx *android.TestContext, config android.Config) { t.Helper() pathCtx := android.PathContextForTesting(config) - setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) + dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) ctx.Register(config) _, errs := ctx.ParseBlueprintsFiles("Android.bp") @@ -118,7 +118,7 @@ func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config ctx := testContext() pathCtx := android.PathContextForTesting(config) - setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) + dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx)) ctx.Register(config) _, errs := ctx.ParseBlueprintsFiles("Android.bp")