Broaden the granularity of config_setting from apex_name to api_domain

The use case for this is for creating a select statement for stub/impl
selection. Since Bazel propagates apex_name from the top-level apex,
the source apex and test apex builds a specific library in two different
configurations. We need select statements for both these two
configurations, but this metadata might not always exist in Android.bp
since test apexes are not necessary to be listed in Android.bp files.

To overcome this, the select statements will be created per api domain
instead. This CL uses a naming convention to infer the api domain of
apexes.

Test: go test ./bp2build
Change-Id: Iad2b45f736bc98a24d2ce1cf2f69aad67973092d
This commit is contained in:
Spandan Das 2023-05-04 17:15:44 +00:00
parent 921af32310
commit 9cad90f966
3 changed files with 41 additions and 14 deletions

View file

@ -1434,4 +1434,6 @@ type StringMapAttribute map[string]string
type ConfigSettingAttributes struct {
// Each key in Flag_values is a label to a custom string_setting
Flag_values StringMapAttribute
// Each element in Constraint_values is a label to a constraint_value
Constraint_values LabelListAttribute
}

View file

@ -4473,11 +4473,12 @@ cc_library {
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions(
"config_setting",
"android-in_myapex",
"myapex",
AttrNameToString{
"flag_values": `{
"//build/bazel/rules/apex:apex_name": "myapex",
"//build/bazel/rules/apex:api_domain": "myapex",
}`,
"constraint_values": `["//build/bazel/platforms/os:android"]`,
},
),
},

View file

@ -1194,16 +1194,30 @@ func availableToSameApexes(a, b []string) bool {
}
var (
apexConfigSettingKey = android.NewOnceKey("apexConfigSetting")
apexConfigSettingLock sync.Mutex
apiDomainConfigSettingKey = android.NewOnceKey("apiDomainConfigSettingKey")
apiDomainConfigSettingLock sync.Mutex
)
func getApexConfigSettingMap(config android.Config) *map[string]bool {
return config.Once(apexConfigSettingKey, func() interface{} {
func getApiDomainConfigSettingMap(config android.Config) *map[string]bool {
return config.Once(apiDomainConfigSettingKey, func() interface{} {
return &map[string]bool{}
}).(*map[string]bool)
}
var (
testApexNameToApiDomain = map[string]string{
"test_broken_com.android.art": "com.android.art",
}
)
func getApiDomain(apexName string) string {
if apiDomain, exists := testApexNameToApiDomain[apexName]; exists {
return apiDomain
}
// Remove `test_` prefix
return strings.TrimPrefix(apexName, "test_")
}
// Create a config setting for this apex in build/bazel/rules/apex
// The use case for this is stub/impl selection in cc libraries
// Long term, these config_setting(s) should be colocated with the respective apex definitions.
@ -1215,23 +1229,32 @@ func createInApexConfigSetting(ctx android.TopDownMutatorContext, apexName strin
// These correspond to android-non_apex and android-in_apex
return
}
apexConfigSettingLock.Lock()
defer apexConfigSettingLock.Unlock()
apiDomainConfigSettingLock.Lock()
defer apiDomainConfigSettingLock.Unlock()
// Return if a config_setting has already been created
acsm := getApexConfigSettingMap(ctx.Config())
if _, exists := (*acsm)[apexName]; exists {
apiDomain := getApiDomain(apexName)
acsm := getApiDomainConfigSettingMap(ctx.Config())
if _, exists := (*acsm)[apiDomain]; exists {
return
}
(*acsm)[apexName] = true
(*acsm)[apiDomain] = true
csa := bazel.ConfigSettingAttributes{
Flag_values: bazel.StringMapAttribute{
"//build/bazel/rules/apex:apex_name": apexName,
"//build/bazel/rules/apex:api_domain": apiDomain,
},
// Constraint this to android
Constraint_values: bazel.MakeLabelListAttribute(
bazel.MakeLabelList(
[]bazel.Label{
bazel.Label{Label: "//build/bazel/platforms/os:android"},
},
),
),
}
ca := android.CommonAttributes{
Name: "android-in_" + apexName,
Name: apiDomain,
}
ctx.CreateBazelConfigSetting(
csa,
@ -1247,7 +1270,8 @@ func inApexConfigSetting(apexAvailable string) string {
if apexAvailable == android.AvailableToAnyApex {
return bazel.AndroidAndInApex
}
return "//build/bazel/rules/apex:android-in_" + apexAvailable
apiDomain := getApiDomain(apexAvailable)
return "//build/bazel/rules/apex:" + apiDomain
}
func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,