Write dexpreopt.config again during the build
Writing $OUT/dexpreopt.config during build setup and then using
it during the build causes bad incremental builds if a cleanspec
removes $OUT/dexpreopt.config. Create a rule in Soong to write
out a copy so that it is a normal build artifact.
Bug: 132379813
Test: m checkbuild
Change-Id: I7755a7f8c1d6561fc83022a7f4cf7e4a64e989c9
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index f48428f..2a1a901 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -115,6 +115,8 @@
type dexpreoptBootJars struct {
defaultBootImage *bootImage
otherImages []*bootImage
+
+ dexpreoptConfigForMake android.WritablePath
}
// dexpreoptBoot singleton rules
@@ -123,6 +125,9 @@
return
}
+ d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config")
+ writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
+
global := dexpreoptGlobalConfig(ctx)
// Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
@@ -453,8 +458,24 @@
}
+func writeGlobalConfigForMake(ctx android.SingletonContext, path android.WritablePath) {
+ data := dexpreoptGlobalConfigRaw(ctx).data
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Output: path,
+ Args: map[string]string{
+ "content": string(data),
+ },
+ })
+}
+
// Export paths for default boot image to Make
func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
+ if d.dexpreoptConfigForMake != nil {
+ ctx.Strict("DEX_PREOPT_CONFIG_FOR_MAKE", d.dexpreoptConfigForMake.String())
+ }
+
image := d.defaultBootImage
if image != nil {
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 270fcb4..d903f45 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -15,40 +15,50 @@
package java
import (
- "android/soong/android"
- "android/soong/dexpreopt"
"path/filepath"
"strings"
+
+ "android/soong/android"
+ "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 f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
ctx.AddNinjaFileDeps(f)
- globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, f)
+ globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f)
if err != nil {
panic(err)
}
- return globalConfig
+ 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 dexpreopt.GlobalConfig{
+ return globalConfigAndRaw{dexpreopt.GlobalConfig{
DisablePreopt: true,
- }
+ }, nil}
})
- }).(dexpreopt.GlobalConfig)
+ }).(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 globalConfig })
+ config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
}
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")