Merge "Add e.g. Target: { Android_arm: { ...} } support to LabelAttribute."

This commit is contained in:
Rupert Shuttleworth 2021-05-27 09:30:39 +00:00 committed by Gerrit Code Review
commit 1b1ab6d7ab
4 changed files with 263 additions and 39 deletions

View file

@ -332,49 +332,174 @@ type Attribute interface {
HasConfigurableValues() bool
}
// Represents an attribute whose value is a single label
type LabelAttribute struct {
Value Label
type labelArchValues struct {
X86 Label
X86_64 Label
Arm Label
Arm64 Label
ConditionsDefault Label
}
type labelTargetValue struct {
// E.g. for android
OsValue Label
// E.g. for android_arm, android_arm64, ...
ArchValues labelArchValues
}
type labelTargetValues struct {
Android labelTargetValue
Darwin labelTargetValue
Fuchsia labelTargetValue
Linux labelTargetValue
LinuxBionic labelTargetValue
Windows labelTargetValue
ConditionsDefault labelTargetValue
}
// Represents an attribute whose value is a single label
type LabelAttribute struct {
Value Label
ArchValues labelArchValues
TargetValues labelTargetValues
}
func (attr *LabelAttribute) GetValueForArch(arch string) Label {
switch arch {
case ARCH_ARM:
return attr.Arm
case ARCH_ARM64:
return attr.Arm64
case ARCH_X86:
return attr.X86
case ARCH_X86_64:
return attr.X86_64
case CONDITIONS_DEFAULT:
return attr.Value
default:
panic("Invalid arch type")
var v *Label
if v = attr.archValuePtrs()[arch]; v == nil {
panic(fmt.Errorf("Unknown arch: %s", arch))
}
return *v
}
func (attr *LabelAttribute) SetValueForArch(arch string, value Label) {
switch arch {
case ARCH_ARM:
attr.Arm = value
case ARCH_ARM64:
attr.Arm64 = value
case ARCH_X86:
attr.X86 = value
case ARCH_X86_64:
attr.X86_64 = value
default:
panic("Invalid arch type")
var v *Label
if v = attr.archValuePtrs()[arch]; v == nil {
panic(fmt.Errorf("Unknown arch: %s", arch))
}
*v = value
}
func (attr *LabelAttribute) archValuePtrs() map[string]*Label {
return map[string]*Label{
ARCH_X86: &attr.ArchValues.X86,
ARCH_X86_64: &attr.ArchValues.X86_64,
ARCH_ARM: &attr.ArchValues.Arm,
ARCH_ARM64: &attr.ArchValues.Arm64,
CONDITIONS_DEFAULT: &attr.ArchValues.ConditionsDefault,
}
}
func (attr LabelAttribute) HasConfigurableValues() bool {
return attr.Arm.Label != "" || attr.Arm64.Label != "" || attr.X86.Label != "" || attr.X86_64.Label != ""
for arch := range PlatformArchMap {
if attr.GetValueForArch(arch).Label != "" {
return true
}
}
for os := range PlatformOsMap {
if attr.GetOsValueForTarget(os).Label != "" {
return true
}
// TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT (not in AllArches)
for _, arch := range AllArches {
if attr.GetOsArchValueForTarget(os, arch).Label != "" {
return true
}
}
}
return false
}
func (attr *LabelAttribute) getValueForTarget(os string) labelTargetValue {
var v *labelTargetValue
if v = attr.targetValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
return *v
}
func (attr *LabelAttribute) GetOsValueForTarget(os string) Label {
var v *labelTargetValue
if v = attr.targetValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
return v.OsValue
}
func (attr *LabelAttribute) GetOsArchValueForTarget(os string, arch string) Label {
var v *labelTargetValue
if v = attr.targetValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
switch arch {
case ARCH_X86:
return v.ArchValues.X86
case ARCH_X86_64:
return v.ArchValues.X86_64
case ARCH_ARM:
return v.ArchValues.Arm
case ARCH_ARM64:
return v.ArchValues.Arm64
case CONDITIONS_DEFAULT:
return v.ArchValues.ConditionsDefault
default:
panic(fmt.Errorf("Unknown arch: %s\n", arch))
}
}
func (attr *LabelAttribute) setValueForTarget(os string, value labelTargetValue) {
var v *labelTargetValue
if v = attr.targetValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
*v = value
}
func (attr *LabelAttribute) SetOsValueForTarget(os string, value Label) {
var v *labelTargetValue
if v = attr.targetValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
v.OsValue = value
}
func (attr *LabelAttribute) SetOsArchValueForTarget(os string, arch string, value Label) {
var v *labelTargetValue
if v = attr.targetValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
switch arch {
case ARCH_X86:
v.ArchValues.X86 = value
case ARCH_X86_64:
v.ArchValues.X86_64 = value
case ARCH_ARM:
v.ArchValues.Arm = value
case ARCH_ARM64:
v.ArchValues.Arm64 = value
case CONDITIONS_DEFAULT:
v.ArchValues.ConditionsDefault = value
default:
panic(fmt.Errorf("Unknown arch: %s\n", arch))
}
}
func (attr *LabelAttribute) targetValuePtrs() map[string]*labelTargetValue {
return map[string]*labelTargetValue{
OS_ANDROID: &attr.TargetValues.Android,
OS_DARWIN: &attr.TargetValues.Darwin,
OS_FUCHSIA: &attr.TargetValues.Fuchsia,
OS_LINUX: &attr.TargetValues.Linux,
OS_LINUX_BIONIC: &attr.TargetValues.LinuxBionic,
OS_WINDOWS: &attr.TargetValues.Windows,
CONDITIONS_DEFAULT: &attr.TargetValues.ConditionsDefault,
}
}
// Arch-specific label_list typed Bazel attribute values. This should correspond

View file

@ -808,3 +808,46 @@ func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
)`},
})
}
func TestCcLibraryLabelAttributeGetTargetProperties(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library GetTargetProperties on a LabelAttribute",
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
dir: "foo/bar",
filesystem: map[string]string{
"foo/bar/Android.bp": `
cc_library {
name: "a",
srcs: ["a.cpp"],
target: {
android_arm: {
version_script: "android_arm.map",
},
linux_bionic_arm64: {
version_script: "linux_bionic_arm64.map",
},
},
bazel_module: { bp2build_available: true },
}
`,
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
copts = [
"-Ifoo/bar",
"-I$(BINDIR)/foo/bar",
],
srcs = ["a.cpp"],
version_script = select({
"//build/bazel/platforms:android_arm": "android_arm.map",
"//build/bazel/platforms:linux_bionic_arm64": "linux_bionic_arm64.map",
"//conditions:default": None,
}),
)`},
})
}

View file

@ -60,19 +60,67 @@ func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selec
}
func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
var value reflect.Value
var archSelects selects
if label.HasConfigurableValues() {
archSelects = map[string]reflect.Value{}
for arch, selectKey := range bazel.PlatformArchMap {
archSelects[selectKey] = reflect.ValueOf(label.GetValueForArch(arch))
}
} else {
value = reflect.ValueOf(label.Value)
value := reflect.ValueOf(label.Value)
if !label.HasConfigurableValues() {
return value, []selects{}
}
return value, []selects{archSelects}
// Keep track of which arches and oses have been used in case we need to raise a warning
usedArches := make(map[string]bool)
usedOses := make(map[string]bool)
archSelects := map[string]reflect.Value{}
for arch, selectKey := range bazel.PlatformArchMap {
archSelects[selectKey] = reflect.ValueOf(label.GetValueForArch(arch))
if archSelects[selectKey].IsValid() && !isZero(archSelects[selectKey]) {
usedArches[arch] = true
}
}
osSelects := map[string]reflect.Value{}
for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
selectKey := bazel.PlatformOsMap[os]
osSelects[selectKey] = reflect.ValueOf(label.GetOsValueForTarget(os))
if osSelects[selectKey].IsValid() && !isZero(osSelects[selectKey]) {
usedOses[os] = true
}
}
osArchSelects := make([]selects, 0)
for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
archSelects := make(map[string]reflect.Value)
// TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT? (not in AllArches)
for _, arch := range bazel.AllArches {
target := os + "_" + arch
selectKey := bazel.PlatformTargetMap[target]
archSelects[selectKey] = reflect.ValueOf(label.GetOsArchValueForTarget(os, arch))
if archSelects[selectKey].IsValid() && !isZero(archSelects[selectKey]) {
if _, ok := usedArches[arch]; ok {
fmt.Printf("WARNING: Same arch used twice in LabelAttribute select: arch '%s'\n", arch)
}
if _, ok := usedOses[os]; ok {
fmt.Printf("WARNING: Same os used twice in LabelAttribute select: os '%s'\n", os)
}
}
}
osArchSelects = append(osArchSelects, archSelects)
}
// Because we have to return a single Label, we can only use one select statement
combinedSelects := map[string]reflect.Value{}
for k, v := range archSelects {
combinedSelects[k] = v
}
for k, v := range osSelects {
combinedSelects[k] = v
}
for _, osArchSelect := range osArchSelects {
for k, v := range osArchSelect {
combinedSelects[k] = v
}
}
return value, []selects{combinedSelects}
}
func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {

View file

@ -568,6 +568,10 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
linkopts.SetOsValueForTarget(os.Name, getBp2BuildLinkerFlags(baseLinkerProps))
if baseLinkerProps.Version_script != nil {
versionScript.SetOsValueForTarget(os.Name, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
}
sharedLibs := baseLinkerProps.Shared_libs
dynamicDeps.SetOsValueForTarget(os.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
}
@ -582,6 +586,10 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
linkopts.SetOsArchValueForTarget(os.Name, arch.Name, getBp2BuildLinkerFlags(baseLinkerProps))
if baseLinkerProps.Version_script != nil {
versionScript.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
}
sharedLibs := baseLinkerProps.Shared_libs
dynamicDeps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
}