Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d00f0dc authored by Colin Cross's avatar Colin Cross
Browse files

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
parent a1591ab0
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -176,7 +176,7 @@ func constructWritablePath(ctx android.PathContext, path string) android.Writabl

// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig struct.  It 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, path string) (GlobalConfig, error) {
func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, []byte, error) {
	type GlobalJSONConfig struct {
		GlobalConfig

@@ -199,9 +199,9 @@ func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, error
	}

	config := GlobalJSONConfig{}
	err := loadConfig(ctx, path, &config)
	data, err := loadConfig(ctx, path, &config)
	if err != nil {
		return config.GlobalConfig, err
		return config.GlobalConfig, nil, err
	}

	// Construct paths that require a PathContext.
@@ -217,7 +217,7 @@ func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, error
	config.GlobalConfig.Tools.VerifyUsesLibraries = constructPath(ctx, config.Tools.VerifyUsesLibraries)
	config.GlobalConfig.Tools.ConstructContext = constructPath(ctx, config.Tools.ConstructContext)

	return config.GlobalConfig, nil
	return config.GlobalConfig, data, nil
}

// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct.  It is not used in Soong, which
@@ -241,7 +241,7 @@ func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error

	config := ModuleJSONConfig{}

	err := loadConfig(ctx, path, &config)
	_, err := loadConfig(ctx, path, &config)
	if err != nil {
		return config.ModuleConfig, err
	}
@@ -259,24 +259,24 @@ func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error
	return config.ModuleConfig, nil
}

func loadConfig(ctx android.PathContext, path string, config interface{}) error {
func loadConfig(ctx android.PathContext, path string, config interface{}) ([]byte, error) {
	r, err := ctx.Fs().Open(path)
	if err != nil {
		return err
		return nil, err
	}
	defer r.Close()

	data, err := ioutil.ReadAll(r)
	if err != nil {
		return err
		return nil, err
	}

	err = json.Unmarshal(data, config)
	if err != nil {
		return err
		return nil, err
	}

	return nil
	return data, nil
}

func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ func main() {

	ctx := &pathContext{android.TestConfig(*outDir, nil)}

	globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath)
	globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err)
		os.Exit(2)
+21 −0
Original line number Diff line number Diff line
@@ -115,6 +115,8 @@ func skipDexpreoptBootJars(ctx android.PathContext) bool {
type dexpreoptBootJars struct {
	defaultBootImage *bootImage
	otherImages      []*bootImage

	dexpreoptConfigForMake android.WritablePath
}

// dexpreoptBoot singleton rules
@@ -123,6 +125,9 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
		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 dumpOatRules(ctx android.SingletonContext, image *bootImage) {

}

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())
+18 −8
Original line number Diff line number Diff line
@@ -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")