diff options
Diffstat (limited to 'android/module.go')
| -rw-r--r-- | android/module.go | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/android/module.go b/android/module.go index 9024896e5..98084f359 100644 --- a/android/module.go +++ b/android/module.go @@ -15,6 +15,9 @@ package android import ( + "crypto/md5" + "encoding/hex" + "encoding/json" "fmt" "net/url" "os" @@ -354,6 +357,10 @@ type BaseModuleContext interface { AddMissingDependencies(missingDeps []string) + // getMissingDependencies returns the list of missing dependencies. + // Calling this function prevents adding new dependencies. + getMissingDependencies() []string + // AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build AddUnconvertedBp2buildDep(dep string) @@ -710,6 +717,31 @@ func SortedUniqueNamedPaths(l NamedPaths) NamedPaths { return l[:k+1] } +// soongConfigTrace holds all references to VendorVars. Uses []string for blueprint:"mutated" +type soongConfigTrace struct { + Bools []string `json:",omitempty"` + Strings []string `json:",omitempty"` + IsSets []string `json:",omitempty"` +} + +func (c *soongConfigTrace) isEmpty() bool { + return len(c.Bools) == 0 && len(c.Strings) == 0 && len(c.IsSets) == 0 +} + +// Returns hash of serialized trace records (empty string if there's no trace recorded) +func (c *soongConfigTrace) hash() string { + // Use MD5 for speed. We don't care collision or preimage attack + if c.isEmpty() { + return "" + } + j, err := json.Marshal(c) + if err != nil { + panic(fmt.Errorf("json marshal of %#v failed: %#v", *c, err)) + } + hash := md5.Sum(j) + return hex.EncodeToString(hash[:]) +} + type nameProperties struct { // The name of the module. Must be unique across all modules. Name *string @@ -939,7 +971,8 @@ type commonProperties struct { NamespaceExportedToMake bool `blueprint:"mutated"` - MissingDeps []string `blueprint:"mutated"` + MissingDeps []string `blueprint:"mutated"` + CheckedMissingDeps bool `blueprint:"mutated"` // Name and variant strings stored by mutators to enable Module.String() DebugName string `blueprint:"mutated"` @@ -953,6 +986,10 @@ type commonProperties struct { // Bazel conversion status BazelConversionStatus BazelConversionStatus `blueprint:"mutated"` + + // SoongConfigTrace records accesses to VendorVars (soong_config) + SoongConfigTrace soongConfigTrace `blueprint:"mutated"` + SoongConfigTraceHash string `blueprint:"mutated"` } // CommonAttributes represents the common Bazel attributes from which properties @@ -2862,6 +2899,20 @@ func (b *baseModuleContext) AddMissingDependencies(deps []string) { } } +func (b *baseModuleContext) checkedMissingDeps() bool { + return b.Module().base().commonProperties.CheckedMissingDeps +} + +func (b *baseModuleContext) getMissingDependencies() []string { + checked := &b.Module().base().commonProperties.CheckedMissingDeps + *checked = true + var missingDeps []string + missingDeps = append(missingDeps, b.Module().base().commonProperties.MissingDeps...) + missingDeps = append(missingDeps, b.bp.EarlyGetMissingDependencies()...) + missingDeps = FirstUniqueStrings(missingDeps) + return missingDeps +} + type AllowDisabledModuleDependency interface { blueprint.DependencyTag AllowDisabledModuleDependency(target Module) bool @@ -3141,6 +3192,10 @@ func (m *moduleContext) ModuleSubDir() string { return m.bp.ModuleSubDir() } +func (m *moduleContext) ModuleSoongConfigHash() string { + return m.module.base().commonProperties.SoongConfigTraceHash +} + func (b *baseModuleContext) Target() Target { return b.target } @@ -3725,6 +3780,8 @@ func (m *moduleContext) TargetRequiredModuleNames() []string { func init() { RegisterParallelSingletonType("buildtarget", BuildTargetSingleton) + RegisterParallelSingletonType("soongconfigtrace", soongConfigTraceSingletonFunc) + FinalDepsMutators(registerSoongConfigTraceMutator) } func BuildTargetSingleton() Singleton { @@ -3906,3 +3963,54 @@ func (d *installPathsDepSet) ToList() InstallPaths { } return d.depSet.ToList().(InstallPaths) } + +func registerSoongConfigTraceMutator(ctx RegisterMutatorsContext) { + ctx.BottomUp("soongconfigtrace", soongConfigTraceMutator).Parallel() +} + +// soongConfigTraceMutator accumulates recorded soong_config trace from children. Also it normalizes +// SoongConfigTrace to make it consistent. +func soongConfigTraceMutator(ctx BottomUpMutatorContext) { + trace := &ctx.Module().base().commonProperties.SoongConfigTrace + ctx.VisitDirectDeps(func(m Module) { + childTrace := &m.base().commonProperties.SoongConfigTrace + trace.Bools = append(trace.Bools, childTrace.Bools...) + trace.Strings = append(trace.Strings, childTrace.Strings...) + trace.IsSets = append(trace.IsSets, childTrace.IsSets...) + }) + trace.Bools = SortedUniqueStrings(trace.Bools) + trace.Strings = SortedUniqueStrings(trace.Strings) + trace.IsSets = SortedUniqueStrings(trace.IsSets) + + ctx.Module().base().commonProperties.SoongConfigTraceHash = trace.hash() +} + +// soongConfigTraceSingleton writes a map from each module's config hash value to trace data. +func soongConfigTraceSingletonFunc() Singleton { + return &soongConfigTraceSingleton{} +} + +type soongConfigTraceSingleton struct { +} + +func (s *soongConfigTraceSingleton) GenerateBuildActions(ctx SingletonContext) { + outFile := PathForOutput(ctx, "soong_config_trace.json") + + traces := make(map[string]*soongConfigTrace) + ctx.VisitAllModules(func(module Module) { + trace := &module.base().commonProperties.SoongConfigTrace + if !trace.isEmpty() { + hash := module.base().commonProperties.SoongConfigTraceHash + traces[hash] = trace + } + }) + + j, err := json.Marshal(traces) + if err != nil { + ctx.Errorf("json marshal to %q failed: %#v", outFile, err) + return + } + + WriteFileRule(ctx, outFile, string(j)) + ctx.Phony("soong_config_trace", outFile) +} |