Merge changes from topic "apex_contributions_build_flags" into main
* changes: Special-case java_sdk_library in source vs prebuilt selection Use `all_apex_contributions` for source/prebuilts selection Create a singleton all_apex_contributions module type
This commit is contained in:
commit
c31b24977e
7 changed files with 484 additions and 4 deletions
|
@ -130,3 +130,8 @@ buildinfo_prop {
|
||||||
// Currently, only microdroid can refer to buildinfo.prop
|
// Currently, only microdroid can refer to buildinfo.prop
|
||||||
visibility: ["//packages/modules/Virtualization/microdroid"],
|
visibility: ["//packages/modules/Virtualization/microdroid"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// container for apex_contributions selected using build flags
|
||||||
|
all_apex_contributions {
|
||||||
|
name: "all_apex_contributions",
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package android
|
package android
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/google/blueprint"
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ func init() {
|
||||||
|
|
||||||
func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
|
func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
|
||||||
ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
|
ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
|
||||||
|
ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
type apexContributions struct {
|
type apexContributions struct {
|
||||||
|
@ -65,3 +67,109 @@ func apexContributionsFactory() Module {
|
||||||
// prebuilts selection.
|
// prebuilts selection.
|
||||||
func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
|
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) {
|
||||||
|
}
|
||||||
|
|
|
@ -2129,3 +2129,41 @@ func (c *config) GetBuildFlag(name string) (string, bool) {
|
||||||
val, ok := c.productVariables.BuildFlags[name]
|
val, ok := c.productVariables.BuildFlags[name]
|
||||||
return val, ok
|
return val, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
mainlineApexContributionBuildFlags = []string{
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_APPSEARCH",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_ART",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_CONNECTIVITY",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_CONSCRYPT",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_CRASHRECOVERY",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_DEVICELOCK",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_HEALTHFITNESS",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_IPSEC",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_MEDIA",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_MEDIAPROVIDER",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_ONDEVICEPERSONALIZATION",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_PERMISSION",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_REMOTEKEYPROVISIONING",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_SCHEDULING",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_SDKEXTENSIONS",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_STATSD",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_UWB",
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_WIFI",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Returns the list of _selected_ apex_contributions
|
||||||
|
// Each mainline module will have one entry in the list
|
||||||
|
func (c *config) AllApexContributions() []string {
|
||||||
|
ret := []string{}
|
||||||
|
for _, f := range mainlineApexContributionBuildFlags {
|
||||||
|
if val, exists := c.GetBuildFlag(f); exists && val != "" {
|
||||||
|
ret = append(ret, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
|
@ -3231,6 +3231,8 @@ func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
|
||||||
return true
|
return true
|
||||||
} else if tag == licensesTag {
|
} else if tag == licensesTag {
|
||||||
return true
|
return true
|
||||||
|
} else if tag == acDepTag {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,7 +387,7 @@ func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) {
|
||||||
|
|
||||||
func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
|
func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
|
||||||
ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel()
|
ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel()
|
||||||
ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
|
ctx.BottomUp("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
|
||||||
ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
|
ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,6 +406,8 @@ func PrebuiltRenameMutator(ctx BottomUpMutatorContext) {
|
||||||
|
|
||||||
// PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the
|
// PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the
|
||||||
// corresponding source module, if one exists for the same variant.
|
// corresponding source module, if one exists for the same variant.
|
||||||
|
// Add a dependency from the prebuilt to `all_apex_contributions`
|
||||||
|
// The metadata will be used for source vs prebuilts selection
|
||||||
func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
|
func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
|
||||||
m := ctx.Module()
|
m := ctx.Module()
|
||||||
// If this module is a prebuilt, is enabled and has not been renamed to source then add a
|
// If this module is a prebuilt, is enabled and has not been renamed to source then add a
|
||||||
|
@ -416,6 +418,14 @@ func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
|
||||||
ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
|
ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
|
||||||
p.properties.SourceExists = true
|
p.properties.SourceExists = true
|
||||||
}
|
}
|
||||||
|
// Add a dependency from the prebuilt to the `all_apex_contributions`
|
||||||
|
// metadata module
|
||||||
|
// TODO: When all branches contain this singleton module, make this strict
|
||||||
|
// TODO: Add this dependency only for mainline prebuilts and not every prebuilt module
|
||||||
|
if ctx.OtherModuleExists("all_apex_contributions") {
|
||||||
|
ctx.AddDependency(m, acDepTag, "all_apex_contributions")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +445,11 @@ func checkInvariantsForSourceAndPrebuilt(ctx BaseModuleContext, s, p Module) {
|
||||||
|
|
||||||
// PrebuiltSelectModuleMutator marks prebuilts that are used, either overriding source modules or
|
// PrebuiltSelectModuleMutator marks prebuilts that are used, either overriding source modules or
|
||||||
// because the source module doesn't exist. It also disables installing overridden source modules.
|
// because the source module doesn't exist. It also disables installing overridden source modules.
|
||||||
func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
|
//
|
||||||
|
// If the visited module is the metadata module `all_apex_contributions`, it sets a
|
||||||
|
// provider containing metadata about whether source or prebuilt of mainline modules should be used.
|
||||||
|
// This logic was added here to prevent the overhead of creating a new mutator.
|
||||||
|
func PrebuiltSelectModuleMutator(ctx BottomUpMutatorContext) {
|
||||||
m := ctx.Module()
|
m := ctx.Module()
|
||||||
if p := GetEmbeddedPrebuilt(m); p != nil {
|
if p := GetEmbeddedPrebuilt(m); p != nil {
|
||||||
if p.srcsSupplier == nil && p.srcsPropertyName == "" {
|
if p.srcsSupplier == nil && p.srcsPropertyName == "" {
|
||||||
|
@ -444,6 +458,17 @@ func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
|
||||||
if !p.properties.SourceExists {
|
if !p.properties.SourceExists {
|
||||||
p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil, m)
|
p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil, m)
|
||||||
}
|
}
|
||||||
|
// Propagate the provider received from `all_apex_contributions`
|
||||||
|
// to the source module
|
||||||
|
ctx.VisitDirectDepsWithTag(acDepTag, func(am Module) {
|
||||||
|
if ctx.Config().Bp2buildMode() {
|
||||||
|
// This provider key is not applicable in bp2build
|
||||||
|
return
|
||||||
|
}
|
||||||
|
psi := ctx.OtherModuleProvider(am, PrebuiltSelectionInfoProvider).(PrebuiltSelectionInfoMap)
|
||||||
|
ctx.SetProvider(PrebuiltSelectionInfoProvider, psi)
|
||||||
|
})
|
||||||
|
|
||||||
} else if s, ok := ctx.Module().(Module); ok {
|
} else if s, ok := ctx.Module().(Module); ok {
|
||||||
ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(prebuiltModule Module) {
|
ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(prebuiltModule Module) {
|
||||||
p := GetEmbeddedPrebuilt(prebuiltModule)
|
p := GetEmbeddedPrebuilt(prebuiltModule)
|
||||||
|
@ -455,6 +480,11 @@ func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// If this is `all_apex_contributions`, set a provider containing
|
||||||
|
// metadata about source vs prebuilts selection
|
||||||
|
if am, ok := m.(*allApexContributions); ok {
|
||||||
|
am.SetPrebuiltSelectionInfoProvider(ctx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrebuiltPostDepsMutator replaces dependencies on the source module with dependencies on the
|
// PrebuiltPostDepsMutator replaces dependencies on the source module with dependencies on the
|
||||||
|
@ -480,9 +510,66 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A wrapper around PrebuiltSelectionInfoMap.IsSelected with special handling for java_sdk_library
|
||||||
|
// java_sdk_library is a macro that creates
|
||||||
|
// 1. top-level impl library
|
||||||
|
// 2. stub libraries (suffixed with .stubs...)
|
||||||
|
//
|
||||||
|
// java_sdk_library_import is a macro that creates
|
||||||
|
// 1. top-level "impl" library
|
||||||
|
// 2. stub libraries (suffixed with .stubs...)
|
||||||
|
//
|
||||||
|
// the impl of java_sdk_library_import is a "hook" for hiddenapi and dexpreopt processing. It does not have an impl jar, but acts as a shim
|
||||||
|
// to provide the jar deapxed from the prebuilt apex
|
||||||
|
//
|
||||||
|
// isSelected uses `all_apex_contributions` to supersede source vs prebuilts selection of the stub libraries. It does not supersede the
|
||||||
|
// selection of the top-level "impl" library so that this hook can work
|
||||||
|
//
|
||||||
|
// TODO (b/308174306) - Fix this when we need to support multiple prebuilts in main
|
||||||
|
func isSelected(psi PrebuiltSelectionInfoMap, m Module) bool {
|
||||||
|
if sdkLibrary, ok := m.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
|
||||||
|
sln := proptools.String(sdkLibrary.SdkLibraryName())
|
||||||
|
// This is the top-level library
|
||||||
|
// Do not supersede the existing prebuilts vs source selection mechanisms
|
||||||
|
if sln == m.base().BaseModuleName() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stub library created by java_sdk_library_import
|
||||||
|
if p := GetEmbeddedPrebuilt(m); p != nil {
|
||||||
|
return psi.IsSelected(sln, PrebuiltNameFromSource(sln))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stub library created by java_sdk_library
|
||||||
|
return psi.IsSelected(sln, sln)
|
||||||
|
}
|
||||||
|
return psi.IsSelected(m.base().BaseModuleName(), m.Name())
|
||||||
|
}
|
||||||
|
|
||||||
// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
|
// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
|
||||||
// will be used if it is marked "prefer" or if the source module is disabled.
|
// will be used if it is marked "prefer" or if the source module is disabled.
|
||||||
func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module, prebuilt Module) bool {
|
func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool {
|
||||||
|
// Use `all_apex_contributions` for source vs prebuilt selection.
|
||||||
|
psi := PrebuiltSelectionInfoMap{}
|
||||||
|
ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(am Module) {
|
||||||
|
if ctx.OtherModuleHasProvider(am, PrebuiltSelectionInfoProvider) {
|
||||||
|
psi = ctx.OtherModuleProvider(am, PrebuiltSelectionInfoProvider).(PrebuiltSelectionInfoMap)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// If the source module is explicitly listed in the metadata module, use that
|
||||||
|
if source != nil && isSelected(psi, source) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// If the prebuilt module is explicitly listed in the metadata module, use that
|
||||||
|
if isSelected(psi, prebuilt) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the baseModuleName could not be found in the metadata module,
|
||||||
|
// fall back to the existing source vs prebuilt selection.
|
||||||
|
// TODO: Drop the fallback mechanisms
|
||||||
|
|
||||||
if !ctx.Config().Bp2buildMode() {
|
if !ctx.Config().Bp2buildMode() {
|
||||||
if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
|
if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -334,6 +334,78 @@ func TestPrebuilts(t *testing.T) {
|
||||||
// be used.
|
// be used.
|
||||||
prebuilt: []OsType{Android, buildOS},
|
prebuilt: []OsType{Android, buildOS},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "apex_contributions supersedes any source preferred via use_source_config_var",
|
||||||
|
modules: `
|
||||||
|
source {
|
||||||
|
name: "bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt {
|
||||||
|
name: "bar",
|
||||||
|
use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
|
||||||
|
srcs: ["prebuilt_file"],
|
||||||
|
}
|
||||||
|
apex_contributions {
|
||||||
|
name: "my_mainline_module_contribution",
|
||||||
|
api_domain: "apexfoo",
|
||||||
|
// this metadata module contains prebuilt
|
||||||
|
contents: ["prebuilt_bar"],
|
||||||
|
}
|
||||||
|
all_apex_contributions {
|
||||||
|
name: "all_apex_contributions",
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
|
||||||
|
variables.VendorVars = map[string]map[string]string{
|
||||||
|
"acme": {
|
||||||
|
"use_source": "true",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
variables.BuildFlags = map[string]string{
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contribution",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
// use_source_config_var indicates that source should be used
|
||||||
|
// but this is superseded by `my_mainline_module_contribution`
|
||||||
|
prebuilt: []OsType{Android, buildOS},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "apex_contributions supersedes any prebuilt preferred via use_source_config_var",
|
||||||
|
modules: `
|
||||||
|
source {
|
||||||
|
name: "bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
prebuilt {
|
||||||
|
name: "bar",
|
||||||
|
use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
|
||||||
|
srcs: ["prebuilt_file"],
|
||||||
|
}
|
||||||
|
apex_contributions {
|
||||||
|
name: "my_mainline_module_contribution",
|
||||||
|
api_domain: "apexfoo",
|
||||||
|
// this metadata module contains source
|
||||||
|
contents: ["bar"],
|
||||||
|
}
|
||||||
|
all_apex_contributions {
|
||||||
|
name: "all_apex_contributions",
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
|
||||||
|
variables.VendorVars = map[string]map[string]string{
|
||||||
|
"acme": {
|
||||||
|
"use_source": "false",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
variables.BuildFlags = map[string]string{
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contribution",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
// use_source_config_var indicates that prebuilt should be used
|
||||||
|
// but this is superseded by `my_mainline_module_contribution`
|
||||||
|
prebuilt: nil,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true",
|
name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true",
|
||||||
modules: `
|
modules: `
|
||||||
|
@ -497,7 +569,7 @@ func TestPrebuilts(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testPrebuiltError(t *testing.T, expectedError, bp string) {
|
func testPrebuiltErrorWithFixture(t *testing.T, expectedError, bp string, fixture FixturePreparer) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
fs := MockFS{
|
fs := MockFS{
|
||||||
"prebuilt_file": nil,
|
"prebuilt_file": nil,
|
||||||
|
@ -508,9 +580,15 @@ func testPrebuiltError(t *testing.T, expectedError, bp string) {
|
||||||
PrepareForTestWithOverrides,
|
PrepareForTestWithOverrides,
|
||||||
fs.AddToFixture(),
|
fs.AddToFixture(),
|
||||||
FixtureRegisterWithContext(registerTestPrebuiltModules),
|
FixtureRegisterWithContext(registerTestPrebuiltModules),
|
||||||
|
OptionalFixturePreparer(fixture),
|
||||||
).
|
).
|
||||||
ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(expectedError)).
|
ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern(expectedError)).
|
||||||
RunTestWithBp(t, bp)
|
RunTestWithBp(t, bp)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPrebuiltError(t *testing.T, expectedError, bp string) {
|
||||||
|
testPrebuiltErrorWithFixture(t, expectedError, bp, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrebuiltShouldNotChangePartition(t *testing.T) {
|
func TestPrebuiltShouldNotChangePartition(t *testing.T) {
|
||||||
|
@ -559,6 +637,7 @@ func registerTestPrebuiltModules(ctx RegistrationContext) {
|
||||||
ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
|
ctx.RegisterModuleType("soong_config_module_type", SoongConfigModuleTypeFactory)
|
||||||
ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
|
ctx.RegisterModuleType("soong_config_string_variable", SoongConfigStringVariableDummyFactory)
|
||||||
ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
|
ctx.RegisterModuleType("soong_config_bool_variable", SoongConfigBoolVariableDummyFactory)
|
||||||
|
RegisterApexContributionsBuildComponents(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
type prebuiltModule struct {
|
type prebuiltModule struct {
|
||||||
|
@ -653,3 +732,33 @@ func newOverrideSourceModule() Module {
|
||||||
InitOverrideModule(m)
|
InitOverrideModule(m)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrebuiltErrorCannotListBothSourceAndPrebuiltInContributions(t *testing.T) {
|
||||||
|
selectMainlineModuleContritbutions := GroupFixturePreparers(
|
||||||
|
FixtureModifyProductVariables(func(variables FixtureProductVariables) {
|
||||||
|
variables.BuildFlags = map[string]string{
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_apex_contributions",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
testPrebuiltErrorWithFixture(t, `Cannot use Soong module: prebuilt_foo from apex_contributions: my_apex_contributions because it has been added previously as: foo from apex_contributions: my_apex_contributions`, `
|
||||||
|
source {
|
||||||
|
name: "foo",
|
||||||
|
}
|
||||||
|
prebuilt {
|
||||||
|
name: "foo",
|
||||||
|
srcs: ["prebuilt_file"],
|
||||||
|
}
|
||||||
|
apex_contributions {
|
||||||
|
name: "my_apex_contributions",
|
||||||
|
api_domain: "my_mainline_module",
|
||||||
|
contents: [
|
||||||
|
"foo",
|
||||||
|
"prebuilt_foo",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
all_apex_contributions {
|
||||||
|
name: "all_apex_contributions",
|
||||||
|
}
|
||||||
|
`, selectMainlineModuleContritbutions)
|
||||||
|
}
|
||||||
|
|
|
@ -1068,6 +1068,137 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a module is listed in `mainline_module_contributions, it should be used
|
||||||
|
// It will supersede any other source vs prebuilt selection mechanism like `prefer` attribute
|
||||||
|
func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) {
|
||||||
|
bp := `
|
||||||
|
apex_contributions {
|
||||||
|
name: "my_mainline_module_contributions",
|
||||||
|
api_domain: "my_mainline_module",
|
||||||
|
contents: [
|
||||||
|
// legacy mechanism prefers the prebuilt
|
||||||
|
// mainline_module_contributions supersedes this since source is listed explicitly
|
||||||
|
"sdklib.prebuilt_preferred_using_legacy_flags",
|
||||||
|
|
||||||
|
// legacy mechanism prefers the source
|
||||||
|
// mainline_module_contributions supersedes this since prebuilt is listed explicitly
|
||||||
|
"prebuilt_sdklib.source_preferred_using_legacy_flags",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
all_apex_contributions {
|
||||||
|
name: "all_apex_contributions",
|
||||||
|
}
|
||||||
|
java_sdk_library {
|
||||||
|
name: "sdklib.prebuilt_preferred_using_legacy_flags",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
sdk_version: "none",
|
||||||
|
system_modules: "none",
|
||||||
|
public: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
system: {
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "sdklib.prebuilt_preferred_using_legacy_flags",
|
||||||
|
prefer: true, // prebuilt is preferred using legacy mechanism
|
||||||
|
public: {
|
||||||
|
jars: ["a.jar"],
|
||||||
|
stub_srcs: ["a.java"],
|
||||||
|
current_api: "current.txt",
|
||||||
|
removed_api: "removed.txt",
|
||||||
|
annotations: "annotations.zip",
|
||||||
|
},
|
||||||
|
system: {
|
||||||
|
jars: ["a.jar"],
|
||||||
|
stub_srcs: ["a.java"],
|
||||||
|
current_api: "current.txt",
|
||||||
|
removed_api: "removed.txt",
|
||||||
|
annotations: "annotations.zip",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
java_sdk_library {
|
||||||
|
name: "sdklib.source_preferred_using_legacy_flags",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
sdk_version: "none",
|
||||||
|
system_modules: "none",
|
||||||
|
public: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
system: {
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "sdklib.source_preferred_using_legacy_flags",
|
||||||
|
prefer: false, // source is preferred using legacy mechanism
|
||||||
|
public: {
|
||||||
|
jars: ["a.jar"],
|
||||||
|
stub_srcs: ["a.java"],
|
||||||
|
current_api: "current.txt",
|
||||||
|
removed_api: "removed.txt",
|
||||||
|
annotations: "annotations.zip",
|
||||||
|
},
|
||||||
|
system: {
|
||||||
|
jars: ["a.jar"],
|
||||||
|
stub_srcs: ["a.java"],
|
||||||
|
current_api: "current.txt",
|
||||||
|
removed_api: "removed.txt",
|
||||||
|
annotations: "annotations.zip",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// rdeps
|
||||||
|
java_library {
|
||||||
|
name: "public",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
libs: [
|
||||||
|
// this should get source since source is listed in my_mainline_module_contributions
|
||||||
|
"sdklib.prebuilt_preferred_using_legacy_flags.stubs",
|
||||||
|
"sdklib.prebuilt_preferred_using_legacy_flags.stubs.system",
|
||||||
|
|
||||||
|
// this should get prebuilt since source is listed in my_mainline_module_contributions
|
||||||
|
"sdklib.source_preferred_using_legacy_flags.stubs",
|
||||||
|
"sdklib.source_preferred_using_legacy_flags.stubs.system",
|
||||||
|
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForJavaTest,
|
||||||
|
PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
FixtureWithLastReleaseApis("sdklib.source_preferred_using_legacy_flags", "sdklib.prebuilt_preferred_using_legacy_flags"),
|
||||||
|
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
|
||||||
|
android.RegisterApexContributionsBuildComponents(ctx)
|
||||||
|
}),
|
||||||
|
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
|
||||||
|
variables.BuildFlags = map[string]string{
|
||||||
|
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
).RunTestWithBp(t, bp)
|
||||||
|
|
||||||
|
// Make sure that rdeps get the correct source vs prebuilt based on mainline_module_contributions
|
||||||
|
public := result.ModuleForTests("public", "android_common")
|
||||||
|
rule := public.Output("javac/public.jar")
|
||||||
|
inputs := rule.Implicits.Strings()
|
||||||
|
expectedInputs := []string{
|
||||||
|
// source
|
||||||
|
"out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.jar",
|
||||||
|
"out/soong/.intermediates/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system/android_common/turbine-combined/sdklib.prebuilt_preferred_using_legacy_flags.stubs.system.jar",
|
||||||
|
|
||||||
|
// prebuilt
|
||||||
|
"out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.jar",
|
||||||
|
"out/soong/.intermediates/prebuilt_sdklib.source_preferred_using_legacy_flags.stubs.system/android_common/combined/sdklib.source_preferred_using_legacy_flags.stubs.system.jar",
|
||||||
|
}
|
||||||
|
for _, expected := range expectedInputs {
|
||||||
|
if !android.InList(expected, inputs) {
|
||||||
|
t.Errorf("expected %q to contain %q", inputs, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestJavaSdkLibraryEnforce(t *testing.T) {
|
func TestJavaSdkLibraryEnforce(t *testing.T) {
|
||||||
partitionToBpOption := func(partition string) string {
|
partitionToBpOption := func(partition string) string {
|
||||||
switch partition {
|
switch partition {
|
||||||
|
|
Loading…
Reference in a new issue