Use hashed subdir for soong_config modules
This is to differentiate soong intermediate directories for soong config
modules. This will help incremental build across different
devices.
Test result of building panther, building cheetah, and building panther
again:
Before this change
- build time: 02:57
- # of tasks: 31044
After this change
- build time: 01:48
- # of tasks: 1694
Build time includes build.ninja generating time (which is more than 1
minute), so the overriden artifacts become far fewer.
And "NINJA_ARGS='-n -d explain' m" only gave 4 "command line changed"
nodes.
Bug: 279362051
Test: see above
Change-Id: I4891cbe823ae21628465e5c6eb26a4837ccdd202
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index 5fa6012..0246a08 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -421,6 +421,57 @@
}).(map[string]blueprint.ModuleFactory)
}
+// tracingConfig is a wrapper to soongconfig.SoongConfig which records all accesses to SoongConfig.
+type tracingConfig struct {
+ config soongconfig.SoongConfig
+ boolSet map[string]bool
+ stringSet map[string]string
+ isSetSet map[string]bool
+}
+
+func (c *tracingConfig) Bool(name string) bool {
+ c.boolSet[name] = c.config.Bool(name)
+ return c.boolSet[name]
+}
+
+func (c *tracingConfig) String(name string) string {
+ c.stringSet[name] = c.config.String(name)
+ return c.stringSet[name]
+}
+
+func (c *tracingConfig) IsSet(name string) bool {
+ c.isSetSet[name] = c.config.IsSet(name)
+ return c.isSetSet[name]
+}
+
+func (c *tracingConfig) getTrace() soongConfigTrace {
+ ret := soongConfigTrace{}
+
+ for k, v := range c.boolSet {
+ ret.Bools = append(ret.Bools, fmt.Sprintf("%q:%t", k, v))
+ }
+ for k, v := range c.stringSet {
+ ret.Strings = append(ret.Strings, fmt.Sprintf("%q:%q", k, v))
+ }
+ for k, v := range c.isSetSet {
+ ret.IsSets = append(ret.IsSets, fmt.Sprintf("%q:%t", k, v))
+ }
+
+ return ret
+}
+
+func newTracingConfig(config soongconfig.SoongConfig) *tracingConfig {
+ c := tracingConfig{
+ config: config,
+ boolSet: make(map[string]bool),
+ stringSet: make(map[string]string),
+ isSetSet: make(map[string]bool),
+ }
+ return &c
+}
+
+var _ soongconfig.SoongConfig = (*tracingConfig)(nil)
+
// configModuleFactory takes an existing soongConfigModuleFactory and a
// ModuleType to create a new ModuleFactory that uses a custom loadhook.
func configModuleFactory(factory blueprint.ModuleFactory, moduleType *soongconfig.ModuleType, bp2build bool) blueprint.ModuleFactory {
@@ -485,8 +536,8 @@
// conditional on Soong config variables by reading the product
// config variables from Make.
AddLoadHook(module, func(ctx LoadHookContext) {
- config := ctx.Config().VendorConfig(moduleType.ConfigNamespace)
- newProps, err := soongconfig.PropertiesToApply(moduleType, conditionalProps, config)
+ tracingConfig := newTracingConfig(ctx.Config().VendorConfig(moduleType.ConfigNamespace))
+ newProps, err := soongconfig.PropertiesToApply(moduleType, conditionalProps, tracingConfig)
if err != nil {
ctx.ModuleErrorf("%s", err)
return
@@ -494,6 +545,8 @@
for _, ps := range newProps {
ctx.AppendProperties(ps)
}
+
+ module.(Module).base().commonProperties.SoongConfigTrace = tracingConfig.getTrace()
})
}
return module, props