Create config_setting per apex_name
These are created by bp2build in /build/bazel/rules/apex. Eventually these config_settings should likely be colocated with the source apex definition. Another alternative was to make Bazel's apex a macro that generates a config_setting. I did not pursue this further for now since it requires the apex_available of every allowlisted cc_library to also be allowlisted. This might not always be true (e.g. com.android.runtime) Test: go test ./bp2build Change-Id: Ibbb14b0d9c1491b3c79b7634a18d9d35b03922c1
This commit is contained in:
parent
6a448ec1a3
commit
4242f10462
3 changed files with 100 additions and 4 deletions
|
@ -268,9 +268,8 @@ func (ct configurationType) validateConfig(config string) {
|
|||
case productVariables:
|
||||
// do nothing
|
||||
case osAndInApex:
|
||||
if _, ok := osAndInApexMap[config]; !ok {
|
||||
panic(fmt.Errorf("Unknown os+in_apex config: %s", config))
|
||||
}
|
||||
// do nothing
|
||||
// this axis can contain additional per-apex keys
|
||||
case inApex:
|
||||
if _, ok := inApexMap[config]; !ok {
|
||||
panic(fmt.Errorf("Unknown in_apex config: %s", config))
|
||||
|
@ -299,7 +298,10 @@ func (ca ConfigurationAxis) SelectKey(config string) string {
|
|||
}
|
||||
return fmt.Sprintf("%s:%s", productVariableBazelPackage, config)
|
||||
case osAndInApex:
|
||||
return osAndInApexMap[config]
|
||||
if ret, exists := osAndInApexMap[config]; exists {
|
||||
return ret
|
||||
}
|
||||
return config
|
||||
case inApex:
|
||||
return inApexMap[config]
|
||||
default:
|
||||
|
|
|
@ -4454,3 +4454,32 @@ cc_library {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Test that a config_setting specific to an apex is created by cc_library.
|
||||
func TestCcLibraryCreatesInApexConfigSetting(t *testing.T) {
|
||||
runCcLibraryTestCase(t, Bp2buildTestCase{
|
||||
Description: "cc_library creates a config_setting for each apex in apex_available",
|
||||
ModuleTypeUnderTest: "cc_library",
|
||||
ModuleTypeUnderTestFactory: cc.LibraryFactory,
|
||||
Dir: "build/bazel/rules/apex",
|
||||
Blueprint: `
|
||||
cc_library {
|
||||
name: "foo",
|
||||
apex_available: [
|
||||
"//apex_available:platform", // This will be skipped, since it is equivalent to //build/bazel/rules/apex:android-non_apex
|
||||
"myapex"
|
||||
],
|
||||
}`,
|
||||
ExpectedBazelTargets: []string{
|
||||
MakeBazelTargetNoRestrictions(
|
||||
"config_setting",
|
||||
"android-in_myapex",
|
||||
AttrNameToString{
|
||||
"flag_values": `{
|
||||
"//build/bazel/rules/apex:apex_name": "myapex",
|
||||
}`,
|
||||
},
|
||||
),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/bazel"
|
||||
|
@ -1196,6 +1197,63 @@ func availableToSameApexes(a, b []string) bool {
|
|||
return !differ
|
||||
}
|
||||
|
||||
var (
|
||||
apexConfigSettingKey = android.NewOnceKey("apexConfigSetting")
|
||||
apexConfigSettingLock sync.Mutex
|
||||
)
|
||||
|
||||
func getApexConfigSettingMap(config android.Config) *map[string]bool {
|
||||
return config.Once(apexConfigSettingKey, func() interface{} {
|
||||
return &map[string]bool{}
|
||||
}).(*map[string]bool)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Note that this is an anti-pattern: The config_setting should be created from the apex definition
|
||||
// and not from a cc_library.
|
||||
// This anti-pattern is needed today since not all apexes have been allowlisted.
|
||||
func createInApexConfigSetting(ctx android.TopDownMutatorContext, apexName string) {
|
||||
if apexName == android.AvailableToPlatform || apexName == android.AvailableToAnyApex {
|
||||
// These correspond to android-non_apex and android-in_apex
|
||||
return
|
||||
}
|
||||
apexConfigSettingLock.Lock()
|
||||
defer apexConfigSettingLock.Unlock()
|
||||
|
||||
// Return if a config_setting has already been created
|
||||
acsm := getApexConfigSettingMap(ctx.Config())
|
||||
if _, exists := (*acsm)[apexName]; exists {
|
||||
return
|
||||
}
|
||||
(*acsm)[apexName] = true
|
||||
|
||||
csa := bazel.ConfigSettingAttributes{
|
||||
Flag_values: bazel.StringMapAttribute{
|
||||
"//build/bazel/rules/apex:apex_name": apexName,
|
||||
},
|
||||
}
|
||||
ca := android.CommonAttributes{
|
||||
Name: "android-in_" + apexName,
|
||||
}
|
||||
ctx.CreateBazelConfigSetting(
|
||||
csa,
|
||||
ca,
|
||||
"build/bazel/rules/apex",
|
||||
)
|
||||
}
|
||||
|
||||
func inApexConfigSetting(apexAvailable string) string {
|
||||
if apexAvailable == android.AvailableToPlatform {
|
||||
return bazel.AndroidAndNonApex
|
||||
}
|
||||
if apexAvailable == android.AvailableToAnyApex {
|
||||
return bazel.AndroidAndInApex
|
||||
}
|
||||
return "//build/bazel/rules/apex:android-in_" + apexAvailable
|
||||
}
|
||||
|
||||
func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,
|
||||
config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int, buildNonApexWithStubs bool) {
|
||||
|
||||
|
@ -1241,6 +1299,13 @@ func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.C
|
|||
dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
|
||||
}
|
||||
}
|
||||
|
||||
// Create a config_setting for each apex_available.
|
||||
// This will be used to select impl of a dep if dep is available to the same apex.
|
||||
for _, aa := range apexAvailable {
|
||||
createInApexConfigSetting(ctx.(android.TopDownMutatorContext), aa)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) {
|
||||
|
|
Loading…
Reference in a new issue