Create a singleton all_apex_contributions module type

This will be a container for the the apex_contributions
selected using build flags. This module will be used to query the state of
selected apex contributions instead of a global that can be mutated by
anyone.

It will set a provider containing metadata for source vs prebuilts
selection. To reduce the overhead of a new mutator, this will be done in
the existing `prebuilt_select` mutator.

It will validate that there are no dups (`foo` and `prebuilt_foo` cannot
be both selected)

Bug: 308174923

Test: go test ./android

Change-Id: Ie42999a71f35d70e0e977f5ab07ce451608d9f35
This commit is contained in:
Spandan Das
2023-10-26 20:48:02 +00:00
parent 04445d5443
commit e3fcb41ff7
5 changed files with 198 additions and 1 deletions

View File

@@ -15,6 +15,7 @@
package android
import (
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -24,6 +25,7 @@ func init() {
func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
}
type apexContributions struct {
@@ -65,3 +67,109 @@ func apexContributionsFactory() Module {
// prebuilts selection.
func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
}
// A container for apex_contributions.
// Based on product_config, it will create a dependency on the selected
// apex_contributions per mainline module
type allApexContributions struct {
SingletonModuleBase
}
func allApexContributionsFactory() SingletonModule {
module := &allApexContributions{}
InitAndroidModule(module)
return module
}
type apexContributionsDepTag struct {
blueprint.BaseDependencyTag
}
var (
acDepTag = apexContributionsDepTag{}
)
// Creates a dep to each selected apex_contributions
func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
ctx.AddDependency(ctx.Module(), acDepTag, ctx.Config().AllApexContributions()...)
}
// Set PrebuiltSelectionInfoProvider in post deps phase
func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
for _, content := range m.Contents() {
if !ctx.OtherModuleExists(content) {
ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
}
pi := &PrebuiltSelectionInfo{
baseModuleName: RemoveOptionalPrebuiltPrefix(content),
selectedModuleName: content,
metadataModuleName: m.Name(),
apiDomain: m.ApiDomain(),
}
p.Add(ctx, pi)
}
}
if ctx.Config().Bp2buildMode() { // Skip bp2build
return
}
p := PrebuiltSelectionInfoMap{}
ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
if m, ok := child.(*apexContributions); ok {
addContentsToProvider(&p, m)
} else {
ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
}
})
ctx.SetProvider(PrebuiltSelectionInfoProvider, p)
}
// A provider containing metadata about whether source or prebuilt should be used
// This provider will be used in prebuilt_select mutator to redirect deps
var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider(PrebuiltSelectionInfoMap{}, "prebuilt_select")
// Map of baseModuleName to the selected source or prebuilt
type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
// Add a new entry to the map with some validations
func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
if p == nil {
return
}
// Do not allow dups. If the base module (without the prebuilt_) has been added before, raise an exception.
if old, exists := (*pm)[p.baseModuleName]; exists {
ctx.ModuleErrorf("Cannot use Soong module: %s from apex_contributions: %s because it has been added previously as: %s from apex_contributions: %s\n",
p.selectedModuleName, p.metadataModuleName, old.selectedModuleName, old.metadataModuleName,
)
}
(*pm)[p.baseModuleName] = *p
}
type PrebuiltSelectionInfo struct {
// e.g. libc
baseModuleName string
// e.g. (libc|prebuilt_libc)
selectedModuleName string
// Name of the apex_contributions module
metadataModuleName string
// e.g. com.android.runtime
apiDomain string
}
// Returns true if `name` is explicitly requested using one of the selected
// apex_contributions metadata modules.
func (p *PrebuiltSelectionInfoMap) IsSelected(baseModuleName, name string) bool {
if i, exists := (*p)[baseModuleName]; exists {
return i.selectedModuleName == name
} else {
return false
}
}
// This module type does not have any build actions.
func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
}
func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
}