Add os/target configurable selects for label list attributes.

This CL is pretty large, so I recommend starting with reading the newly
added tests for the expected behavior.

This change works in conjunction with the linked CLs in the Gerrit topic.
Those CLs add support for new platform() definitions for OS targets
specified in Soong's arch.go, which are configurable through
Android.bp's `target {}` property. It works similary to previous CLs
adding support for the `arch {}` property.

These configurable props are keyed by the OS: android, linux_bionic,
windows, and so on. They map to `select` statements in label list
attributes, which this CL enables for cc_library_headers' header_libs
and export_header_lib_headers props.

This enables //bionic/libc:libc_headers to be generated correctly, from:

    cc_library_headers {
        name: "libc_headers",
        target: {
            android: {
                header_libs: ["libc_headers_arch"],
                export_header_lib_headers: ["libc_headers_arch"],
            },
            linux_bionic: {
                header_libs: ["libc_headers_arch"],
                export_header_lib_headers: ["libc_headers_arch"],
            },
        },
        // omitted props
    }

to:

    cc_library_headers(
        name = "libc_headers",
        deps = [] + select({
            "//build/bazel/platforms/os:android": [
                ":libc_headers_arch",
            ],
            "//build/bazel/platforms/os:linux_bionic": [
                ":libc_headers_arch",
            ],
            "//conditions:default": [],
        }),
    )

Test: TH
Test: Verify generated //bionic/libc:libc_headers
Fixes: 183597786

Change-Id: I01016cc2cc9a71449f02300d747f01decebf3f6e
This commit is contained in:
Jingwen Chen
2021-03-24 02:18:33 -04:00
parent 252831b03a
commit 91220d7334
13 changed files with 580 additions and 170 deletions

View File

@@ -80,10 +80,19 @@ func UniqueBazelLabelList(originalLabelList LabelList) LabelList {
}
const (
ARCH_X86 = "x86"
ARCH_X86_64 = "x86_64"
// ArchType names in arch.go
ARCH_ARM = "arm"
ARCH_ARM64 = "arm64"
ARCH_X86 = "x86"
ARCH_X86_64 = "x86_64"
// OsType names in arch.go
OS_ANDROID = "android"
OS_DARWIN = "darwin"
OS_FUCHSIA = "fuchsia"
OS_LINUX = "linux_glibc"
OS_LINUX_BIONIC = "linux_bionic"
OS_WINDOWS = "windows"
)
var (
@@ -92,6 +101,36 @@ var (
// android package depends on the bazel package, so a cyclic dependency
// prevents using that here.
selectableArchs = []string{ARCH_X86, ARCH_X86_64, ARCH_ARM, ARCH_ARM64}
// Likewise, this is the list of target operating systems.
selectableTargetOs = []string{
OS_ANDROID,
OS_DARWIN,
OS_FUCHSIA,
OS_LINUX,
OS_LINUX_BIONIC,
OS_WINDOWS,
}
// A map of architectures to the Bazel label of the constraint_value
// for the @platforms//cpu:cpu constraint_setting
PlatformArchMap = map[string]string{
ARCH_ARM: "//build/bazel/platforms/arch:arm",
ARCH_ARM64: "//build/bazel/platforms/arch:arm64",
ARCH_X86: "//build/bazel/platforms/arch:x86",
ARCH_X86_64: "//build/bazel/platforms/arch:x86_64",
}
// A map of target operating systems to the Bazel label of the
// constraint_value for the @platforms//os:os constraint_setting
PlatformOsMap = map[string]string{
OS_ANDROID: "//build/bazel/platforms/os:android",
OS_DARWIN: "//build/bazel/platforms/os:darwin",
OS_FUCHSIA: "//build/bazel/platforms/os:fuchsia",
OS_LINUX: "//build/bazel/platforms/os:linux",
OS_LINUX_BIONIC: "//build/bazel/platforms/os:linux_bionic",
OS_WINDOWS: "//build/bazel/platforms/os:windows",
}
)
// Arch-specific label_list typed Bazel attribute values. This should correspond
@@ -101,8 +140,16 @@ type labelListArchValues struct {
X86_64 LabelList
Arm LabelList
Arm64 LabelList
// TODO(b/181299724): this is currently missing the "common" arch, which
// doesn't have an equivalent platform() definition yet.
Common LabelList
}
type labelListOsValues struct {
Android LabelList
Darwin LabelList
Fuchsia LabelList
Linux LabelList
LinuxBionic LabelList
Windows LabelList
}
// LabelListAttribute is used to represent a list of Bazel labels as an
@@ -115,6 +162,11 @@ type LabelListAttribute struct {
// are generated in a select statement and appended to the non-arch specific
// label list Value.
ArchValues labelListArchValues
// The os-specific attribute label list values. Optional. If used, these
// are generated in a select statement and appended to the non-os specific
// label list Value.
OsValues labelListOsValues
}
// MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
@@ -124,45 +176,75 @@ func MakeLabelListAttribute(value LabelList) LabelListAttribute {
// HasArchSpecificValues returns true if the attribute contains
// architecture-specific label_list values.
func (attrs *LabelListAttribute) HasArchSpecificValues() bool {
func (attrs *LabelListAttribute) HasConfigurableValues() bool {
for _, arch := range selectableArchs {
if len(attrs.GetValueForArch(arch).Includes) > 0 || len(attrs.GetValueForArch(arch).Excludes) > 0 {
if len(attrs.GetValueForArch(arch).Includes) > 0 {
return true
}
}
for _, os := range selectableTargetOs {
if len(attrs.GetValueForOS(os).Includes) > 0 {
return true
}
}
return false
}
func (attrs *LabelListAttribute) archValuePtrs() map[string]*LabelList {
return map[string]*LabelList{
ARCH_X86: &attrs.ArchValues.X86,
ARCH_X86_64: &attrs.ArchValues.X86_64,
ARCH_ARM: &attrs.ArchValues.Arm,
ARCH_ARM64: &attrs.ArchValues.Arm64,
}
}
// GetValueForArch returns the label_list attribute value for an architecture.
func (attrs *LabelListAttribute) GetValueForArch(arch string) LabelList {
switch arch {
case ARCH_X86:
return attrs.ArchValues.X86
case ARCH_X86_64:
return attrs.ArchValues.X86_64
case ARCH_ARM:
return attrs.ArchValues.Arm
case ARCH_ARM64:
return attrs.ArchValues.Arm64
default:
var v *LabelList
if v = attrs.archValuePtrs()[arch]; v == nil {
panic(fmt.Errorf("Unknown arch: %s", arch))
}
return *v
}
// SetValueForArch sets the label_list attribute value for an architecture.
func (attrs *LabelListAttribute) SetValueForArch(arch string, value LabelList) {
switch arch {
case "x86":
attrs.ArchValues.X86 = value
case "x86_64":
attrs.ArchValues.X86_64 = value
case "arm":
attrs.ArchValues.Arm = value
case "arm64":
attrs.ArchValues.Arm64 = value
default:
var v *LabelList
if v = attrs.archValuePtrs()[arch]; v == nil {
panic(fmt.Errorf("Unknown arch: %s", arch))
}
*v = value
}
func (attrs *LabelListAttribute) osValuePtrs() map[string]*LabelList {
return map[string]*LabelList{
OS_ANDROID: &attrs.OsValues.Android,
OS_DARWIN: &attrs.OsValues.Darwin,
OS_FUCHSIA: &attrs.OsValues.Fuchsia,
OS_LINUX: &attrs.OsValues.Linux,
OS_LINUX_BIONIC: &attrs.OsValues.LinuxBionic,
OS_WINDOWS: &attrs.OsValues.Windows,
}
}
// GetValueForOS returns the label_list attribute value for an OS target.
func (attrs *LabelListAttribute) GetValueForOS(os string) LabelList {
var v *LabelList
if v = attrs.osValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
return *v
}
// SetValueForArch sets the label_list attribute value for an OS target.
func (attrs *LabelListAttribute) SetValueForOS(os string, value LabelList) {
var v *LabelList
if v = attrs.osValuePtrs()[os]; v == nil {
panic(fmt.Errorf("Unknown os: %s", os))
}
*v = value
}
// StringListAttribute corresponds to the string_list Bazel attribute type with
@@ -182,13 +264,12 @@ type stringListArchValues struct {
X86_64 []string
Arm []string
Arm64 []string
// TODO(b/181299724): this is currently missing the "common" arch, which
// doesn't have an equivalent platform() definition yet.
Common []string
}
// HasArchSpecificValues returns true if the attribute contains
// HasConfigurableValues returns true if the attribute contains
// architecture-specific string_list values.
func (attrs *StringListAttribute) HasArchSpecificValues() bool {
func (attrs *StringListAttribute) HasConfigurableValues() bool {
for _, arch := range selectableArchs {
if len(attrs.GetValueForArch(arch)) > 0 {
return true
@@ -197,36 +278,31 @@ func (attrs *StringListAttribute) HasArchSpecificValues() bool {
return false
}
func (attrs *StringListAttribute) archValuePtrs() map[string]*[]string {
return map[string]*[]string{
ARCH_X86: &attrs.ArchValues.X86,
ARCH_X86_64: &attrs.ArchValues.X86_64,
ARCH_ARM: &attrs.ArchValues.Arm,
ARCH_ARM64: &attrs.ArchValues.Arm64,
}
}
// GetValueForArch returns the string_list attribute value for an architecture.
func (attrs *StringListAttribute) GetValueForArch(arch string) []string {
switch arch {
case ARCH_X86:
return attrs.ArchValues.X86
case ARCH_X86_64:
return attrs.ArchValues.X86_64
case ARCH_ARM:
return attrs.ArchValues.Arm
case ARCH_ARM64:
return attrs.ArchValues.Arm64
default:
var v *[]string
if v = attrs.archValuePtrs()[arch]; v == nil {
panic(fmt.Errorf("Unknown arch: %s", arch))
}
return *v
}
// SetValueForArch sets the string_list attribute value for an architecture.
func (attrs *StringListAttribute) SetValueForArch(arch string, value []string) {
switch arch {
case ARCH_X86:
attrs.ArchValues.X86 = value
case ARCH_X86_64:
attrs.ArchValues.X86_64 = value
case ARCH_ARM:
attrs.ArchValues.Arm = value
case ARCH_ARM64:
attrs.ArchValues.Arm64 = value
default:
var v *[]string
if v = attrs.archValuePtrs()[arch]; v == nil {
panic(fmt.Errorf("Unknown arch: %s", arch))
}
*v = value
}
// TryVariableSubstitution, replace string substitution formatting within each string in slice with