From 9abd62d13348fd8beba87e953551913a70bbb730 Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Fri, 21 May 2021 08:37:59 -0400 Subject: [PATCH] Use maps in bazel *attribute types This is to simplify the process of resolving label + exclude labels across the various configuration axes we have and across the various properties/modules that use this behavior. Test: ci/bp2build.sh && ci/mixed_droid.sh Change-Id: I8efae3e75ddb365384f5caaf5bb504a5206618d3 --- android/arch.go | 131 +-- android/variable.go | 17 +- bazel/Android.bp | 1 + bazel/configurability.go | 213 ++++ bazel/properties.go | 994 +++++------------- bazel/properties_test.go | 46 +- bp2build/build_conversion_test.go | 8 +- bp2build/cc_library_static_conversion_test.go | 2 - bp2build/configurability.go | 150 +-- bp2build/testing.go | 8 +- cc/bp2build.go | 355 ++----- cc/library.go | 3 +- 12 files changed, 721 insertions(+), 1207 deletions(-) create mode 100644 bazel/configurability.go diff --git a/android/arch.go b/android/arch.go index 9ff439ccc..2e4a30818 100644 --- a/android/arch.go +++ b/android/arch.go @@ -15,6 +15,7 @@ package android import ( + "android/soong/bazel" "encoding" "fmt" "reflect" @@ -897,7 +898,7 @@ func createArchPropTypeDesc(props reflect.Type) []archPropTypeDesc { // Add the OS/Arch combinations, e.g. "android_arm64". for _, archType := range osArchTypeMap[os] { - targets = append(targets, GetCompoundTargetName(os, archType)) + targets = append(targets, GetCompoundTargetField(os, archType)) // Also add the special "linux_" and "bionic_" property structs. if os.Linux() { @@ -1217,7 +1218,7 @@ func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archT return getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib) } -func GetCompoundTargetName(os OsType, arch ArchType) string { +func GetCompoundTargetField(os OsType, arch ArchType) string { return os.Field + "_" + arch.Name } @@ -1327,7 +1328,7 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch // key: value, // }, // }, - field := GetCompoundTargetName(os, archType) + field := GetCompoundTargetField(os, archType) userFriendlyField := "target." + os.Name + "_" + archType.Name if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, osArchProperties) @@ -1882,27 +1883,38 @@ type ArchVariantContext interface { PropertyErrorf(property, fmt string, args ...interface{}) } -// GetArchProperties returns a map of architectures to the values of the -// properties of the 'propertySet' struct that are specific to that architecture. +// ArchVariantProperties represents a map of arch-variant config strings to a property interface{}. +type ArchVariantProperties map[string]interface{} + +// ConfigurationAxisToArchVariantProperties represents a map of bazel.ConfigurationAxis to +// ArchVariantProperties, such that each independent arch-variant axis maps to the +// configs/properties for that axis. +type ConfigurationAxisToArchVariantProperties map[bazel.ConfigurationAxis]ArchVariantProperties + +// GetArchVariantProperties returns a ConfigurationAxisToArchVariantProperties where the +// arch-variant properties correspond to the values of the properties of the 'propertySet' struct +// that are specific to that axis/configuration. Each axis is independent, containing +// non-overlapping configs that correspond to the various "arch-variant" support, at this time: +// arches (including multilib) +// oses +// arch+os combinations // -// For example, passing a struct { Foo bool, Bar string } will return an -// interface{} that can be type asserted back into the same struct, containing -// the arch specific property value specified by the module if defined. +// For example, passing a struct { Foo bool, Bar string } will return an interface{} that can be +// type asserted back into the same struct, containing the config-specific property value specified +// by the module if defined. // // Arch-specific properties may come from an arch stanza or a multilib stanza; properties // in these stanzas are combined. // For example: `arch: { x86: { Foo: ["bar"] } }, multilib: { lib32: {` Foo: ["baz"] } }` // will result in `Foo: ["bar", "baz"]` being returned for architecture x86, if the given // propertyset contains `Foo []string`. -// -// Implemented in a way very similar to GetTargetProperties(). -func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet interface{}) map[ArchType]interface{} { +func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySet interface{}) ConfigurationAxisToArchVariantProperties { // Return value of the arch types to the prop values for that arch. - archToProp := map[ArchType]interface{}{} + axisToProps := ConfigurationAxisToArchVariantProperties{} // Nothing to do for non-arch-specific modules. if !m.ArchSpecific() { - return archToProp + return axisToProps } dstType := reflect.ValueOf(propertySet).Type() @@ -1920,9 +1932,10 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter if archProperties == nil { // This module does not have the property set requested - return archToProp + return axisToProps } + archToProp := ArchVariantProperties{} // For each arch type (x86, arm64, etc.) for _, arch := range ArchTypeList() { // Arch properties are sometimes sharded (see createArchPropTypeDesc() ). @@ -1948,10 +1961,30 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter mergePropertyStruct(ctx, value, propertyStruct) } - archToProp[arch] = value + archToProp[arch.Name] = value } + axisToProps[bazel.ArchConfigurationAxis] = archToProp - return archToProp + osToProp := ArchVariantProperties{} + archOsToProp := ArchVariantProperties{} + // For android, linux, ... + for _, os := range osTypeList { + if os == CommonOS { + // It looks like this OS value is not used in Blueprint files + continue + } + osToProp[os.Name] = getTargetStruct(ctx, propertySet, archProperties, os.Field) + // For arm, x86, ... + for _, arch := range osArchTypeMap[os] { + targetField := GetCompoundTargetField(os, arch) + targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name) + archOsToProp[targetName] = getTargetStruct(ctx, propertySet, archProperties, targetField) + } + } + axisToProps[bazel.OsConfigurationAxis] = osToProp + axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp + + return axisToProps } // Returns a struct matching the propertySet interface, containing properties specific to the targetName @@ -1989,69 +2022,3 @@ func getTargetStruct(ctx ArchVariantContext, propertySet interface{}, archProper return value } - -// Properties corresponds to e.g. Target: android: {...} -// ArchProperties corresponds to e.g. Target: android_arm: {...}, android_arm64: {...}, ... -type TargetProperties struct { - Properties interface{} - ArchProperties map[ArchType]interface{} -} - -// GetTargetProperties returns a map of OS target (e.g. android, windows) to the -// values of the properties of the 'propertySet' struct that are specific to -// that OS target. -// -// For example, passing a struct { Foo bool, Bar string } will return an -// interface{} that can be type asserted back into the same struct, containing -// the os-specific property value specified by the module if defined. -// -// Implemented in a way very similar to GetArchProperties(). -// -// NOTE: "Target" == OS -func (m *ModuleBase) GetTargetProperties(ctx ArchVariantContext, propertySet interface{}) map[OsType]TargetProperties { - // Return value of the target types to the prop values for that target. - targetToProp := map[OsType]TargetProperties{} - - // Nothing to do for non-target-specific modules. - if !m.ArchSpecific() { - return targetToProp - } - - dstType := reflect.ValueOf(propertySet).Type() - var archProperties []interface{} - - // First find the property set in the module that corresponds to the requested - // one. m.archProperties[i] corresponds to m.generalProperties[i]. - for i, generalProp := range m.generalProperties { - srcType := reflect.ValueOf(generalProp).Type() - if srcType == dstType { - archProperties = m.archProperties[i] - break - } - } - - if archProperties == nil { - // This module does not have the property set requested - return targetToProp - } - - // For android, linux, ... - for _, os := range osTypeList { - if os == CommonOS { - // It looks like this OS value is not used in Blueprint files - continue - } - targetProperties := TargetProperties{ - Properties: getTargetStruct(ctx, propertySet, archProperties, os.Field), - ArchProperties: make(map[ArchType]interface{}), - } - // For arm, x86, ... - for _, arch := range osArchTypeMap[os] { - targetName := GetCompoundTargetName(os, arch) - targetProperties.ArchProperties[arch] = getTargetStruct(ctx, propertySet, archProperties, targetName) - } - targetToProp[os] = targetProperties - } - - return targetToProp -} diff --git a/android/variable.go b/android/variable.go index 7658cdd4a..6d235d610 100644 --- a/android/variable.go +++ b/android/variable.go @@ -479,18 +479,11 @@ func ProductVariableProperties(ctx BaseMutatorContext) ProductConfigProperties { productVariableValues(moduleBase.variableProperties, "", &productConfigProperties) - for arch, targetProps := range moduleBase.GetArchProperties(ctx, moduleBase.variableProperties) { - // GetArchProperties is creating an instance of the requested type - // and productVariablesValues expects an interface, so no need to cast - productVariableValues(targetProps, arch.Name, &productConfigProperties) - } - - for os, targetProps := range moduleBase.GetTargetProperties(ctx, moduleBase.variableProperties) { - // GetTargetProperties is creating an instance of the requested type - // and productVariablesValues expects an interface, so no need to cast - productVariableValues(targetProps.Properties, os.Name, &productConfigProperties) - for arch, archProperties := range targetProps.ArchProperties { - productVariableValues(archProperties, os.Name+"_"+arch.Name, &productConfigProperties) + for _, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) { + for config, props := range configToProps { + // GetArchVariantProperties is creating an instance of the requested type + // and productVariablesValues expects an interface, so no need to cast + productVariableValues(props, config, &productConfigProperties) } } diff --git a/bazel/Android.bp b/bazel/Android.bp index b7c185a61..b68d65bd5 100644 --- a/bazel/Android.bp +++ b/bazel/Android.bp @@ -7,6 +7,7 @@ bootstrap_go_package { pkgPath: "android/soong/bazel", srcs: [ "aquery.go", + "configurability.go", "constants.go", "properties.go", ], diff --git a/bazel/configurability.go b/bazel/configurability.go new file mode 100644 index 000000000..df9c9bfbd --- /dev/null +++ b/bazel/configurability.go @@ -0,0 +1,213 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bazel + +import ( + "fmt" + "strings" +) + +const ( + // ArchType names in arch.go + archArm = "arm" + archArm64 = "arm64" + archX86 = "x86" + archX86_64 = "x86_64" + + // OsType names in arch.go + osAndroid = "android" + osDarwin = "darwin" + osFuchsia = "fuchsia" + osLinux = "linux_glibc" + osLinuxBionic = "linux_bionic" + osWindows = "windows" + + // Targets in arch.go + osArchAndroidArm = "android_arm" + osArchAndroidArm64 = "android_arm64" + osArchAndroidX86 = "android_x86" + osArchAndroidX86_64 = "android_x86_64" + osArchDarwinX86_64 = "darwin_x86_64" + osArchFuchsiaArm64 = "fuchsia_arm64" + osArchFuchsiaX86_64 = "fuchsia_x86_64" + osArchLinuxX86 = "linux_glibc_x86" + osArchLinuxX86_64 = "linux_glibc_x86_64" + osArchLinuxBionicArm64 = "linux_bionic_arm64" + osArchLinuxBionicX86_64 = "linux_bionic_x86_64" + osArchWindowsX86 = "windows_x86" + osArchWindowsX86_64 = "windows_x86_64" + + // This is the string representation of the default condition wherever a + // configurable attribute is used in a select statement, i.e. + // //conditions:default for Bazel. + // + // This is consistently named "conditions_default" to mirror the Soong + // config variable default key in an Android.bp file, although there's no + // integration with Soong config variables (yet). + ConditionsDefault = "conditions_default" + + ConditionsDefaultSelectKey = "//conditions:default" + + productVariableBazelPackage = "//build/bazel/product_variables" +) + +var ( + // These are the list of OSes and architectures with a Bazel config_setting + // and constraint value equivalent. These exist in arch.go, but the android + // package depends on the bazel package, so a cyclic dependency prevents + // using those variables here. + + // A map of architectures to the Bazel label of the constraint_value + // for the @platforms//cpu:cpu constraint_setting + platformArchMap = map[string]string{ + archArm: "//build/bazel/platforms/arch:arm", + archArm64: "//build/bazel/platforms/arch:arm64", + archX86: "//build/bazel/platforms/arch:x86", + archX86_64: "//build/bazel/platforms/arch:x86_64", + ConditionsDefault: ConditionsDefaultSelectKey, // The default condition of as arch select map. + } + + // 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{ + osAndroid: "//build/bazel/platforms/os:android", + osDarwin: "//build/bazel/platforms/os:darwin", + osFuchsia: "//build/bazel/platforms/os:fuchsia", + osLinux: "//build/bazel/platforms/os:linux", + osLinuxBionic: "//build/bazel/platforms/os:linux_bionic", + osWindows: "//build/bazel/platforms/os:windows", + ConditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. + } + + platformOsArchMap = map[string]string{ + osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm", + osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64", + osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86", + osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64", + osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64", + osArchFuchsiaArm64: "//build/bazel/platforms/os_arch:fuchsia_arm64", + osArchFuchsiaX86_64: "//build/bazel/platforms/os_arch:fuchsia_x86_64", + osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86", + osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64", + osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64", + osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64", + osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86", + osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64", + ConditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. + } +) + +// basic configuration types +type configurationType int + +const ( + noConfig configurationType = iota + arch + os + osArch + productVariables +) + +func (ct configurationType) String() string { + return map[configurationType]string{ + noConfig: "no_config", + arch: "arch", + os: "os", + osArch: "arch_os", + productVariables: "product_variables", + }[ct] +} + +func (ct configurationType) validateConfig(config string) { + switch ct { + case noConfig: + if config != "" { + panic(fmt.Errorf("Cannot specify config with %s, but got %s", ct, config)) + } + case arch: + if _, ok := platformArchMap[config]; !ok { + panic(fmt.Errorf("Unknown arch: %s", config)) + } + case os: + if _, ok := platformOsMap[config]; !ok { + panic(fmt.Errorf("Unknown os: %s", config)) + } + case osArch: + if _, ok := platformOsArchMap[config]; !ok { + panic(fmt.Errorf("Unknown os+arch: %s", config)) + } + case productVariables: + // do nothing + default: + panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct)) + } +} + +// SelectKey returns the Bazel select key for a given configurationType and config string. +func (ct configurationType) SelectKey(config string) string { + ct.validateConfig(config) + switch ct { + case noConfig: + panic(fmt.Errorf("SelectKey is unnecessary for noConfig ConfigurationType ")) + case arch: + return platformArchMap[config] + case os: + return platformOsMap[config] + case osArch: + return platformOsArchMap[config] + case productVariables: + if config == ConditionsDefault { + return ConditionsDefaultSelectKey + } + return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config)) + default: + panic(fmt.Errorf("Unrecognized ConfigurationType %d", ct)) + } +} + +var ( + // Indicating there is no configuration axis + NoConfigAxis = ConfigurationAxis{configurationType: noConfig} + // An axis for architecture-specific configurations + ArchConfigurationAxis = ConfigurationAxis{configurationType: arch} + // An axis for os-specific configurations + OsConfigurationAxis = ConfigurationAxis{configurationType: os} + // An axis for arch+os-specific configurations + OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch} +) + +// ProductVariableConfigurationAxis returns an axis for the given product variable +func ProductVariableConfigurationAxis(variable string) ConfigurationAxis { + return ConfigurationAxis{ + configurationType: productVariables, + subType: variable, + } +} + +// ConfigurationAxis is an independent axis for configuration, there should be no overlap between +// elements within an axis. +type ConfigurationAxis struct { + configurationType + // some configuration types (e.g. productVariables) have multiple independent axes, subType helps + // distinguish between them without needing to list all 17 product variables. + subType string +} + +func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool { + if ca.configurationType < other.configurationType { + return true + } + return ca.subType < other.subType +} diff --git a/bazel/properties.go b/bazel/properties.go index 951081cc3..c55de9541 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -19,7 +19,6 @@ import ( "path/filepath" "regexp" "sort" - "strings" ) // BazelTargetModuleProperties contain properties and metadata used for @@ -65,6 +64,10 @@ type LabelList struct { Excludes []Label } +func (ll *LabelList) IsNil() bool { + return ll.Includes == nil && ll.Excludes == nil +} + // uniqueParentDirectories returns a list of the unique parent directories for // all files in ll.Includes. func (ll *LabelList) uniqueParentDirectories() []string { @@ -106,7 +109,27 @@ func UniqueSortedBazelLabels(originalLabels []Label) []Label { return uniqueLabels } -func UniqueBazelLabelList(originalLabelList LabelList) LabelList { +func FirstUniqueBazelLabels(originalLabels []Label) []Label { + var labels []Label + found := make(map[Label]bool, len(originalLabels)) + for _, l := range originalLabels { + if _, ok := found[l]; ok { + continue + } + labels = append(labels, l) + found[l] = true + } + return labels +} + +func FirstUniqueBazelLabelList(originalLabelList LabelList) LabelList { + var uniqueLabelList LabelList + uniqueLabelList.Includes = FirstUniqueBazelLabels(originalLabelList.Includes) + uniqueLabelList.Excludes = FirstUniqueBazelLabels(originalLabelList.Excludes) + return uniqueLabelList +} + +func UniqueSortedBazelLabelList(originalLabelList LabelList) LabelList { var uniqueLabelList LabelList uniqueLabelList.Includes = UniqueSortedBazelLabels(originalLabelList.Includes) uniqueLabelList.Excludes = UniqueSortedBazelLabels(originalLabelList.Excludes) @@ -154,16 +177,9 @@ func MapLabelListAttribute(mapOver LabelListAttribute, mapFn func(string) string result.Value = MapLabelList(mapOver.Value, mapFn) - for arch := range PlatformArchMap { - result.SetValueForArch(arch, MapLabelList(mapOver.GetValueForArch(arch), mapFn)) - } - - for os := range PlatformOsMap { - result.SetOsValueForTarget(os, MapLabelList(mapOver.GetOsValueForTarget(os), mapFn)) - - // TODO(b/187530594): Should we handle arch=CONDITIONS_DEFAULT here? (not in ArchValues) - for _, arch := range AllArches { - result.SetOsArchValueForTarget(os, arch, MapLabelList(mapOver.GetOsArchValueForTarget(os, arch), mapFn)) + for axis, configToLabels := range mapOver.ConfigurableValues { + for config, value := range configToLabels { + result.SetSelectValue(axis, config, MapLabelList(value, mapFn)) } } @@ -184,21 +200,14 @@ func FilterLabelList(haystack LabelList, needleFn func(string) bool) LabelList { // Return all needles in a given haystack, where needleFn is true for needles. func FilterLabelListAttribute(haystack LabelListAttribute, needleFn func(string) bool) LabelListAttribute { - var result LabelListAttribute + result := MakeLabelListAttribute(FilterLabelList(haystack.Value, needleFn)) - result.Value = FilterLabelList(haystack.Value, needleFn) - - for arch := range PlatformArchMap { - result.SetValueForArch(arch, FilterLabelList(haystack.GetValueForArch(arch), needleFn)) - } - - for os := range PlatformOsMap { - result.SetOsValueForTarget(os, FilterLabelList(haystack.GetOsValueForTarget(os), needleFn)) - - // TODO(b/187530594): Should we handle arch=CONDITIONS_DEFAULT here? (not in ArchValues) - for _, arch := range AllArches { - result.SetOsArchValueForTarget(os, arch, FilterLabelList(haystack.GetOsArchValueForTarget(os, arch), needleFn)) + for config, selects := range haystack.ConfigurableValues { + newSelects := make(labelListSelectValues, len(selects)) + for k, v := range selects { + newSelects[k] = FilterLabelList(v, needleFn) } + result.ConfigurableValues[config] = newSelects } return result @@ -206,24 +215,18 @@ func FilterLabelListAttribute(haystack LabelListAttribute, needleFn func(string) // Subtract needle from haystack func SubtractBazelLabelListAttribute(haystack LabelListAttribute, needle LabelListAttribute) LabelListAttribute { - var result LabelListAttribute + result := MakeLabelListAttribute(SubtractBazelLabelList(haystack.Value, needle.Value)) - for arch := range PlatformArchMap { - result.SetValueForArch(arch, - SubtractBazelLabelList(haystack.GetValueForArch(arch), needle.GetValueForArch(arch))) - } + for config, selects := range haystack.ConfigurableValues { + newSelects := make(labelListSelectValues, len(selects)) + needleSelects := needle.ConfigurableValues[config] - for os := range PlatformOsMap { - result.SetOsValueForTarget(os, SubtractBazelLabelList(haystack.GetOsValueForTarget(os), needle.GetOsValueForTarget(os))) - - // TODO(b/187530594): Should we handle arch=CONDITIONS_DEFAULT here? (not in ArchValues) - for _, arch := range AllArches { - result.SetOsArchValueForTarget(os, arch, SubtractBazelLabelList(haystack.GetOsArchValueForTarget(os, arch), needle.GetOsArchValueForTarget(os, arch))) + for k, v := range selects { + newSelects[k] = SubtractBazelLabelList(v, needleSelects[k]) } + result.ConfigurableValues[config] = newSelects } - result.Value = SubtractBazelLabelList(haystack.Value, needle.Value) - return result } @@ -268,489 +271,202 @@ func SubtractBazelLabelList(haystack LabelList, needle LabelList) LabelList { return result } -const ( - // 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" - - // Targets in arch.go - TARGET_ANDROID_ARM = "android_arm" - TARGET_ANDROID_ARM64 = "android_arm64" - TARGET_ANDROID_X86 = "android_x86" - TARGET_ANDROID_X86_64 = "android_x86_64" - TARGET_DARWIN_X86_64 = "darwin_x86_64" - TARGET_FUCHSIA_ARM64 = "fuchsia_arm64" - TARGET_FUCHSIA_X86_64 = "fuchsia_x86_64" - TARGET_LINUX_X86 = "linux_glibc_x86" - TARGET_LINUX_x86_64 = "linux_glibc_x86_64" - TARGET_LINUX_BIONIC_ARM64 = "linux_bionic_arm64" - TARGET_LINUX_BIONIC_X86_64 = "linux_bionic_x86_64" - TARGET_WINDOWS_X86 = "windows_x86" - TARGET_WINDOWS_X86_64 = "windows_x86_64" - - // This is the string representation of the default condition wherever a - // configurable attribute is used in a select statement, i.e. - // //conditions:default for Bazel. - // - // This is consistently named "conditions_default" to mirror the Soong - // config variable default key in an Android.bp file, although there's no - // integration with Soong config variables (yet). - CONDITIONS_DEFAULT = "conditions_default" - - ConditionsDefaultSelectKey = "//conditions:default" - - productVariableBazelPackage = "//build/bazel/product_variables" -) - -var ( - // These are the list of OSes and architectures with a Bazel config_setting - // and constraint value equivalent. These exist in arch.go, but the android - // package depends on the bazel package, so a cyclic dependency prevents - // using those variables here. - - // 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", - CONDITIONS_DEFAULT: ConditionsDefaultSelectKey, // The default condition of as arch select map. - } - - // 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", - CONDITIONS_DEFAULT: ConditionsDefaultSelectKey, // The default condition of an os select map. - } - - PlatformTargetMap = map[string]string{ - TARGET_ANDROID_ARM: "//build/bazel/platforms/os_arch:android_arm", - TARGET_ANDROID_ARM64: "//build/bazel/platforms/os_arch:android_arm64", - TARGET_ANDROID_X86: "//build/bazel/platforms/os_arch:android_x86", - TARGET_ANDROID_X86_64: "//build/bazel/platforms/os_arch:android_x86_64", - TARGET_DARWIN_X86_64: "//build/bazel/platforms/os_arch:darwin_x86_64", - TARGET_FUCHSIA_ARM64: "//build/bazel/platforms/os_arch:fuchsia_arm64", - TARGET_FUCHSIA_X86_64: "//build/bazel/platforms/os_arch:fuchsia_x86_64", - TARGET_LINUX_X86: "//build/bazel/platforms/os_arch:linux_glibc_x86", - TARGET_LINUX_x86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64", - TARGET_LINUX_BIONIC_ARM64: "//build/bazel/platforms/os_arch:linux_bionic_arm64", - TARGET_LINUX_BIONIC_X86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64", - TARGET_WINDOWS_X86: "//build/bazel/platforms/os_arch:windows_x86", - TARGET_WINDOWS_X86_64: "//build/bazel/platforms/os_arch:windows_x86_64", - CONDITIONS_DEFAULT: ConditionsDefaultSelectKey, // The default condition of an os select map. - } - - // TODO(b/187530594): Should we add CONDITIONS_DEFAULT here? - AllArches = []string{ARCH_ARM, ARCH_ARM64, ARCH_X86, ARCH_X86_64} -) - type Attribute interface { HasConfigurableValues() bool } -type labelArchValues struct { - X86 Label - X86_64 Label - Arm Label - Arm64 Label +type labelSelectValues map[string]*Label - ConditionsDefault Label -} +type configurableLabels map[ConfigurationAxis]labelSelectValues -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 +func (cl configurableLabels) setValueForAxis(axis ConfigurationAxis, config string, value *Label) { + if cl[axis] == nil { + cl[axis] = make(labelSelectValues) + } + cl[axis][config] = value } // Represents an attribute whose value is a single label type LabelAttribute struct { - Value Label + Value *Label - ArchValues labelArchValues - - TargetValues labelTargetValues + ConfigurableValues configurableLabels } -func (attr *LabelAttribute) GetValueForArch(arch string) Label { - var v *Label - if v = attr.archValuePtrs()[arch]; v == nil { - panic(fmt.Errorf("Unknown arch: %s", arch)) - } - return *v +// HasConfigurableValues returns whether there are configurable values set for this label. +func (la LabelAttribute) HasConfigurableValues() bool { + return len(la.ConfigurableValues) > 0 } -func (attr *LabelAttribute) SetValueForArch(arch string, value Label) { - var v *Label - if v = attr.archValuePtrs()[arch]; v == nil { - panic(fmt.Errorf("Unknown arch: %s", arch)) - } - *v = value +// SetValue sets the base, non-configured value for the Label +func (la *LabelAttribute) SetValue(value Label) { + la.SetSelectValue(NoConfigAxis, "", 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 { - for arch := range PlatformArchMap { - if attr.GetValueForArch(arch).Label != "" { - return true +// SetSelectValue set a value for a bazel select for the given axis, config and value. +func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string, value Label) { + axis.validateConfig(config) + switch axis.configurationType { + case noConfig: + la.Value = &value + case arch, os, osArch, productVariables: + if la.ConfigurableValues == nil { + la.ConfigurableValues = make(configurableLabels) } + la.ConfigurableValues.setValueForAxis(axis, config, &value) + default: + panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) + } +} + +// SelectValue gets a value for a bazel select for the given axis and config. +func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Label { + axis.validateConfig(config) + switch axis.configurationType { + case noConfig: + return *la.Value + case arch, os, osArch, productVariables: + return *la.ConfigurableValues[axis][config] + default: + panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) + } +} + +// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order. +func (la *LabelAttribute) SortedConfigurationAxes() []ConfigurationAxis { + keys := make([]ConfigurationAxis, 0, len(la.ConfigurableValues)) + for k := range la.ConfigurableValues { + keys = append(keys, k) } - for os := range PlatformOsMap { - if attr.GetOsValueForTarget(os).Label != "" { + sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) }) + return keys +} + +// labelListSelectValues supports config-specific label_list typed Bazel attribute values. +type labelListSelectValues map[string]LabelList + +func (ll labelListSelectValues) appendSelects(other labelListSelectValues) { + for k, v := range other { + l := ll[k] + (&l).Append(v) + ll[k] = l + } +} + +// HasConfigurableValues returns whether there are configurable values within this set of selects. +func (ll labelListSelectValues) HasConfigurableValues() bool { + for _, v := range ll { + if len(v.Includes) > 0 { 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 -// to the types of architectures supported for compilation in arch.go. -type labelListArchValues struct { - X86 LabelList - X86_64 LabelList - Arm LabelList - Arm64 LabelList - - ConditionsDefault LabelList -} - -type labelListTargetValue struct { - // E.g. for android - OsValue LabelList - - // E.g. for android_arm, android_arm64, ... - ArchValues labelListArchValues -} - -func (target *labelListTargetValue) Append(other labelListTargetValue) { - target.OsValue.Append(other.OsValue) - target.ArchValues.X86.Append(other.ArchValues.X86) - target.ArchValues.X86_64.Append(other.ArchValues.X86_64) - target.ArchValues.Arm.Append(other.ArchValues.Arm) - target.ArchValues.Arm64.Append(other.ArchValues.Arm64) - target.ArchValues.ConditionsDefault.Append(other.ArchValues.ConditionsDefault) -} - -type labelListTargetValues struct { - Android labelListTargetValue - Darwin labelListTargetValue - Fuchsia labelListTargetValue - Linux labelListTargetValue - LinuxBionic labelListTargetValue - Windows labelListTargetValue - - ConditionsDefault labelListTargetValue -} - // LabelListAttribute is used to represent a list of Bazel labels as an // attribute. type LabelListAttribute struct { - // The non-arch specific attribute label list Value. Required. + // The non-configured attribute label list Value. Required. Value LabelList - // The arch-specific attribute label list values. Optional. If used, these - // are generated in a select statement and appended to the non-arch specific - // label list Value. - ArchValues labelListArchValues + // The configured attribute label list Values. Optional + // a map of independent configurability axes + ConfigurableValues configurableLabelLists +} - // 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. - TargetValues labelListTargetValues +type configurableLabelLists map[ConfigurationAxis]labelListSelectValues + +func (cll configurableLabelLists) setValueForAxis(axis ConfigurationAxis, config string, list LabelList) { + if list.IsNil() { + if _, ok := cll[axis][config]; ok { + delete(cll[axis], config) + } + return + } + if cll[axis] == nil { + cll[axis] = make(labelListSelectValues) + } + + cll[axis][config] = list +} + +func (cll configurableLabelLists) Append(other configurableLabelLists) { + for axis, otherSelects := range other { + selects := cll[axis] + if selects == nil { + selects = make(labelListSelectValues, len(otherSelects)) + } + selects.appendSelects(otherSelects) + cll[axis] = selects + } } // MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value. func MakeLabelListAttribute(value LabelList) LabelListAttribute { - return LabelListAttribute{Value: UniqueBazelLabelList(value)} + return LabelListAttribute{ + Value: value, + ConfigurableValues: make(configurableLabelLists), + } +} + +func (lla *LabelListAttribute) SetValue(list LabelList) { + lla.SetSelectValue(NoConfigAxis, "", list) +} + +// SetSelectValue set a value for a bazel select for the given axis, config and value. +func (lla *LabelListAttribute) SetSelectValue(axis ConfigurationAxis, config string, list LabelList) { + axis.validateConfig(config) + switch axis.configurationType { + case noConfig: + lla.Value = list + case arch, os, osArch, productVariables: + if lla.ConfigurableValues == nil { + lla.ConfigurableValues = make(configurableLabelLists) + } + lla.ConfigurableValues.setValueForAxis(axis, config, list) + default: + panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) + } +} + +// SelectValue gets a value for a bazel select for the given axis and config. +func (lla *LabelListAttribute) SelectValue(axis ConfigurationAxis, config string) LabelList { + axis.validateConfig(config) + switch axis.configurationType { + case noConfig: + return lla.Value + case arch, os, osArch, productVariables: + return lla.ConfigurableValues[axis][config] + default: + panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) + } +} + +// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order. +func (lla *LabelListAttribute) SortedConfigurationAxes() []ConfigurationAxis { + keys := make([]ConfigurationAxis, 0, len(lla.ConfigurableValues)) + for k := range lla.ConfigurableValues { + keys = append(keys, k) + } + + sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) }) + return keys } // Append all values, including os and arch specific ones, from another // LabelListAttribute to this LabelListAttribute. -func (attrs *LabelListAttribute) Append(other LabelListAttribute) { - for arch := range PlatformArchMap { - this := attrs.GetValueForArch(arch) - that := other.GetValueForArch(arch) - this.Append(that) - attrs.SetValueForArch(arch, this) +func (lla *LabelListAttribute) Append(other LabelListAttribute) { + lla.Value.Append(other.Value) + if lla.ConfigurableValues == nil { + lla.ConfigurableValues = make(configurableLabelLists) } - - for os := range PlatformOsMap { - this := attrs.getValueForTarget(os) - that := other.getValueForTarget(os) - this.Append(that) - attrs.setValueForTarget(os, this) - } - - attrs.Value.Append(other.Value) + lla.ConfigurableValues.Append(other.ConfigurableValues) } -// HasArchSpecificValues returns true if the attribute contains -// architecture-specific label_list values. -func (attrs LabelListAttribute) HasConfigurableValues() bool { - for arch := range PlatformArchMap { - if len(attrs.GetValueForArch(arch).Includes) > 0 { - return true - } - } - - for os := range PlatformOsMap { - if len(attrs.GetOsValueForTarget(os).Includes) > 0 { - return true - } - // TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT (not in AllArches) - for _, arch := range AllArches { - if len(attrs.GetOsArchValueForTarget(os, arch).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, - CONDITIONS_DEFAULT: &attrs.ArchValues.ConditionsDefault, - } -} - -// GetValueForArch returns the label_list attribute value for an architecture. -func (attrs *LabelListAttribute) GetValueForArch(arch string) LabelList { - 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) { - var v *LabelList - if v = attrs.archValuePtrs()[arch]; v == nil { - panic(fmt.Errorf("Unknown arch: %s", arch)) - } - *v = value -} - -func (attrs *LabelListAttribute) targetValuePtrs() map[string]*labelListTargetValue { - return map[string]*labelListTargetValue{ - OS_ANDROID: &attrs.TargetValues.Android, - OS_DARWIN: &attrs.TargetValues.Darwin, - OS_FUCHSIA: &attrs.TargetValues.Fuchsia, - OS_LINUX: &attrs.TargetValues.Linux, - OS_LINUX_BIONIC: &attrs.TargetValues.LinuxBionic, - OS_WINDOWS: &attrs.TargetValues.Windows, - CONDITIONS_DEFAULT: &attrs.TargetValues.ConditionsDefault, - } -} - -func (attrs *LabelListAttribute) getValueForTarget(os string) labelListTargetValue { - var v *labelListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - return *v -} - -func (attrs *LabelListAttribute) GetOsValueForTarget(os string) LabelList { - var v *labelListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - return v.OsValue -} - -func (attrs *LabelListAttribute) GetOsArchValueForTarget(os string, arch string) LabelList { - var v *labelListTargetValue - if v = attrs.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 (attrs *LabelListAttribute) setValueForTarget(os string, value labelListTargetValue) { - var v *labelListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - *v = value -} - -func (attrs *LabelListAttribute) SetOsValueForTarget(os string, value LabelList) { - var v *labelListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - v.OsValue = value -} - -func (attrs *LabelListAttribute) SetOsArchValueForTarget(os string, arch string, value LabelList) { - var v *labelListTargetValue - if v = attrs.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)) - } +// HasConfigurableValues returns true if the attribute contains axis-specific label list values. +func (lla LabelListAttribute) HasConfigurableValues() bool { + return len(lla.ConfigurableValues) > 0 } // StringListAttribute corresponds to the string_list Bazel attribute type with @@ -759,256 +475,110 @@ type StringListAttribute struct { // The base value of the string list attribute. Value []string - // The arch-specific attribute string list values. Optional. If used, these - // are generated in a select statement and appended to the non-arch specific - // label list Value. - ArchValues stringListArchValues + // The configured attribute label list Values. Optional + // a map of independent configurability axes + ConfigurableValues configurableStringLists +} - // The os-specific attribute string list values. Optional. If used, these - // are generated in a select statement and appended to the non-os specific - // label list Value. - TargetValues stringListTargetValues +type configurableStringLists map[ConfigurationAxis]stringListSelectValues - // list of product-variable string list values. Optional. if used, each will generate a select - // statement appended to the label list Value. - ProductValues []ProductVariableValues +func (csl configurableStringLists) Append(other configurableStringLists) { + for axis, otherSelects := range other { + selects := csl[axis] + if selects == nil { + selects = make(stringListSelectValues, len(otherSelects)) + } + selects.appendSelects(otherSelects) + csl[axis] = selects + } +} + +func (csl configurableStringLists) setValueForAxis(axis ConfigurationAxis, config string, list []string) { + if csl[axis] == nil { + csl[axis] = make(stringListSelectValues) + } + csl[axis][config] = list +} + +type stringListSelectValues map[string][]string + +func (sl stringListSelectValues) appendSelects(other stringListSelectValues) { + for k, v := range other { + sl[k] = append(sl[k], v...) + } +} + +func (sl stringListSelectValues) hasConfigurableValues(other stringListSelectValues) bool { + for _, val := range sl { + if len(val) > 0 { + return true + } + } + return false } // MakeStringListAttribute initializes a StringListAttribute with the non-arch specific value. func MakeStringListAttribute(value []string) StringListAttribute { // NOTE: These strings are not necessarily unique or sorted. - return StringListAttribute{Value: value} -} - -// Arch-specific string_list typed Bazel attribute values. This should correspond -// to the types of architectures supported for compilation in arch.go. -type stringListArchValues struct { - X86 []string - X86_64 []string - Arm []string - Arm64 []string - - ConditionsDefault []string -} - -type stringListTargetValue struct { - // E.g. for android - OsValue []string - - // E.g. for android_arm, android_arm64, ... - ArchValues stringListArchValues -} - -func (target *stringListTargetValue) Append(other stringListTargetValue) { - target.OsValue = append(target.OsValue, other.OsValue...) - target.ArchValues.X86 = append(target.ArchValues.X86, other.ArchValues.X86...) - target.ArchValues.X86_64 = append(target.ArchValues.X86_64, other.ArchValues.X86_64...) - target.ArchValues.Arm = append(target.ArchValues.Arm, other.ArchValues.Arm...) - target.ArchValues.Arm64 = append(target.ArchValues.Arm64, other.ArchValues.Arm64...) - target.ArchValues.ConditionsDefault = append(target.ArchValues.ConditionsDefault, other.ArchValues.ConditionsDefault...) -} - -type stringListTargetValues struct { - Android stringListTargetValue - Darwin stringListTargetValue - Fuchsia stringListTargetValue - Linux stringListTargetValue - LinuxBionic stringListTargetValue - Windows stringListTargetValue - - ConditionsDefault stringListTargetValue -} - -// Product Variable values for StringListAttribute -type ProductVariableValues struct { - ProductVariable string - - Values []string -} - -// SelectKey returns the appropriate select key for the receiving ProductVariableValues. -func (p ProductVariableValues) SelectKey() string { - return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(p.ProductVariable)) -} - -// HasConfigurableValues returns true if the attribute contains -// architecture-specific string_list values. -func (attrs StringListAttribute) HasConfigurableValues() bool { - for arch := range PlatformArchMap { - if len(attrs.GetValueForArch(arch)) > 0 { - return true - } - } - - for os := range PlatformOsMap { - if len(attrs.GetOsValueForTarget(os)) > 0 { - return true - } - // TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT? (Not in AllArches) - for _, arch := range AllArches { - if len(attrs.GetOsArchValueForTarget(os, arch)) > 0 { - return true - } - - } - } - - return len(attrs.ProductValues) > 0 -} - -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, - CONDITIONS_DEFAULT: &attrs.ArchValues.ConditionsDefault, + return StringListAttribute{ + Value: value, + ConfigurableValues: make(configurableStringLists), } } -// GetValueForArch returns the string_list attribute value for an architecture. -func (attrs *StringListAttribute) GetValueForArch(arch string) []string { - 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) { - var v *[]string - if v = attrs.archValuePtrs()[arch]; v == nil { - panic(fmt.Errorf("Unknown arch: %s", arch)) - } - *v = value -} - -func (attrs *StringListAttribute) targetValuePtrs() map[string]*stringListTargetValue { - return map[string]*stringListTargetValue{ - OS_ANDROID: &attrs.TargetValues.Android, - OS_DARWIN: &attrs.TargetValues.Darwin, - OS_FUCHSIA: &attrs.TargetValues.Fuchsia, - OS_LINUX: &attrs.TargetValues.Linux, - OS_LINUX_BIONIC: &attrs.TargetValues.LinuxBionic, - OS_WINDOWS: &attrs.TargetValues.Windows, - CONDITIONS_DEFAULT: &attrs.TargetValues.ConditionsDefault, - } -} - -func (attrs *StringListAttribute) getValueForTarget(os string) stringListTargetValue { - var v *stringListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - return *v -} - -func (attrs *StringListAttribute) GetOsValueForTarget(os string) []string { - var v *stringListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - return v.OsValue -} - -func (attrs *StringListAttribute) GetOsArchValueForTarget(os string, arch string) []string { - var v *stringListTargetValue - if v = attrs.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 (attrs *StringListAttribute) setValueForTarget(os string, value stringListTargetValue) { - var v *stringListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - *v = value -} - -func (attrs *StringListAttribute) SortedProductVariables() []ProductVariableValues { - vals := attrs.ProductValues[:] - sort.Slice(vals, func(i, j int) bool { return vals[i].ProductVariable < vals[j].ProductVariable }) - return vals -} - -func (attrs *StringListAttribute) SetOsValueForTarget(os string, value []string) { - var v *stringListTargetValue - if v = attrs.targetValuePtrs()[os]; v == nil { - panic(fmt.Errorf("Unknown os: %s", os)) - } - v.OsValue = value -} - -func (attrs *StringListAttribute) SetOsArchValueForTarget(os string, arch string, value []string) { - var v *stringListTargetValue - if v = attrs.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)) - } +// HasConfigurableValues returns true if the attribute contains axis-specific string_list values. +func (sla StringListAttribute) HasConfigurableValues() bool { + return len(sla.ConfigurableValues) > 0 } // Append appends all values, including os and arch specific ones, from another // StringListAttribute to this StringListAttribute -func (attrs *StringListAttribute) Append(other StringListAttribute) { - for arch := range PlatformArchMap { - this := attrs.GetValueForArch(arch) - that := other.GetValueForArch(arch) - this = append(this, that...) - attrs.SetValueForArch(arch, this) +func (sla *StringListAttribute) Append(other StringListAttribute) { + sla.Value = append(sla.Value, other.Value...) + if sla.ConfigurableValues == nil { + sla.ConfigurableValues = make(configurableStringLists) + } + sla.ConfigurableValues.Append(other.ConfigurableValues) +} + +// SetSelectValue set a value for a bazel select for the given axis, config and value. +func (sla *StringListAttribute) SetSelectValue(axis ConfigurationAxis, config string, list []string) { + axis.validateConfig(config) + switch axis.configurationType { + case noConfig: + sla.Value = list + case arch, os, osArch, productVariables: + if sla.ConfigurableValues == nil { + sla.ConfigurableValues = make(configurableStringLists) + } + sla.ConfigurableValues.setValueForAxis(axis, config, list) + default: + panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) + } +} + +// SelectValue gets a value for a bazel select for the given axis and config. +func (sla *StringListAttribute) SelectValue(axis ConfigurationAxis, config string) []string { + axis.validateConfig(config) + switch axis.configurationType { + case noConfig: + return sla.Value + case arch, os, osArch, productVariables: + return sla.ConfigurableValues[axis][config] + default: + panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) + } +} + +// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order. +func (sla *StringListAttribute) SortedConfigurationAxes() []ConfigurationAxis { + keys := make([]ConfigurationAxis, 0, len(sla.ConfigurableValues)) + for k := range sla.ConfigurableValues { + keys = append(keys, k) } - for os := range PlatformOsMap { - this := attrs.getValueForTarget(os) - that := other.getValueForTarget(os) - this.Append(that) - attrs.setValueForTarget(os, this) - } - - productValues := make(map[string][]string, 0) - for _, pv := range attrs.ProductValues { - productValues[pv.ProductVariable] = pv.Values - } - for _, pv := range other.ProductValues { - productValues[pv.ProductVariable] = append(productValues[pv.ProductVariable], pv.Values...) - } - attrs.ProductValues = make([]ProductVariableValues, 0, len(productValues)) - for pv, vals := range productValues { - attrs.ProductValues = append(attrs.ProductValues, ProductVariableValues{ - ProductVariable: pv, - Values: vals, - }) - } - - attrs.Value = append(attrs.Value, other.Value...) + sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) }) + return keys } // TryVariableSubstitution, replace string substitution formatting within each string in slice with diff --git a/bazel/properties_test.go b/bazel/properties_test.go index 229a4aab0..bc556bfd5 100644 --- a/bazel/properties_test.go +++ b/bazel/properties_test.go @@ -122,7 +122,7 @@ func TestSubtractBazelLabelList(t *testing.T) { } } } -func TestUniqueBazelLabelList(t *testing.T) { +func TestFirstUniqueBazelLabelList(t *testing.T) { testCases := []struct { originalLabelList LabelList expectedUniqueLabelList LabelList @@ -157,7 +157,49 @@ func TestUniqueBazelLabelList(t *testing.T) { }, } for _, tc := range testCases { - actualUniqueLabelList := UniqueBazelLabelList(tc.originalLabelList) + actualUniqueLabelList := FirstUniqueBazelLabelList(tc.originalLabelList) + if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) { + t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList) + } + } +} + +func TestUniqueSortedBazelLabelList(t *testing.T) { + testCases := []struct { + originalLabelList LabelList + expectedUniqueLabelList LabelList + }{ + { + originalLabelList: LabelList{ + Includes: []Label{ + {Label: "c"}, + {Label: "a"}, + {Label: "a"}, + {Label: "b"}, + }, + Excludes: []Label{ + {Label: "y"}, + {Label: "z"}, + {Label: "x"}, + {Label: "x"}, + }, + }, + expectedUniqueLabelList: LabelList{ + Includes: []Label{ + {Label: "a"}, + {Label: "b"}, + {Label: "c"}, + }, + Excludes: []Label{ + {Label: "x"}, + {Label: "y"}, + {Label: "z"}, + }, + }, + }, + } + for _, tc := range testCases { + actualUniqueLabelList := UniqueSortedBazelLabelList(tc.originalLabelList) if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) { t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList) } diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index b1c342c69..6d0a9b21a 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -1109,8 +1109,8 @@ genrule { "out", ], srcs = [ - "in1", "srcs-from-3", + "in1", ], )`, description: "genrule applies properties from genrule_defaults transitively", @@ -1535,10 +1535,10 @@ func TestGlobExcludeSrcs(t *testing.T) { expectedBazelTargets: []string{`filegroup( name = "fg_foo", srcs = [ - "//dir:e.txt", - "//dir:f.txt", "a.txt", "b.txt", + "//dir:e.txt", + "//dir:f.txt", ], )`, }, @@ -1575,9 +1575,9 @@ func TestGlobExcludeSrcs(t *testing.T) { expectedBazelTargets: []string{`filegroup( name = "fg_foo", srcs = [ + "a.txt", "//dir/subdir:e.txt", "//dir/subdir:f.txt", - "a.txt", ], )`, }, diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index da38adbb6..40edec80b 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1286,8 +1286,6 @@ cc_library_static { "//build/bazel/platforms/os_arch:android_arm64": ["android_arm64_src.c"], "//build/bazel/platforms/os_arch:android_x86": ["android_x86_src.c"], "//build/bazel/platforms/os_arch:android_x86_64": ["android_x86_64_src.c"], - "//conditions:default": [], - }) + select({ "//build/bazel/platforms/os_arch:linux_bionic_arm64": ["linux_bionic_arm64_src.c"], "//build/bazel/platforms/os_arch:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"], "//conditions:default": [], diff --git a/bp2build/configurability.go b/bp2build/configurability.go index 7e1a2989d..60f6330e3 100644 --- a/bp2build/configurability.go +++ b/bp2build/configurability.go @@ -17,46 +17,20 @@ func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selec return value, []selects{} } - selectValues := make([]selects, 0) - archSelects := map[string]reflect.Value{} - for arch, selectKey := range bazel.PlatformArchMap { - archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch)) - } - if len(archSelects) > 0 { - selectValues = append(selectValues, archSelects) - } - - osSelects := map[string]reflect.Value{} - osArchSelects := make([]selects, 0) - for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) { - selectKey := bazel.PlatformOsMap[os] - osSelects[selectKey] = reflect.ValueOf(list.GetOsValueForTarget(os)) - 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(list.GetOsArchValueForTarget(os, arch)) + var ret []selects + for _, axis := range list.SortedConfigurationAxes() { + configToLists := list.ConfigurableValues[axis] + archSelects := map[string]reflect.Value{} + for config, labels := range configToLists { + selectKey := axis.SelectKey(config) + archSelects[selectKey] = reflect.ValueOf(labels) } - osArchSelects = append(osArchSelects, archSelects) - } - if len(osSelects) > 0 { - selectValues = append(selectValues, osSelects) - } - if len(osArchSelects) > 0 { - selectValues = append(selectValues, osArchSelects...) - } - - for _, pv := range list.SortedProductVariables() { - s := make(selects) - if len(pv.Values) > 0 { - s[pv.SelectKey()] = reflect.ValueOf(pv.Values) - s[bazel.ConditionsDefaultSelectKey] = reflect.ValueOf([]string{}) - selectValues = append(selectValues, s) + if len(archSelects) > 0 { + ret = append(ret, archSelects) } } - return value, selectValues + return value, ret } func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) { @@ -65,105 +39,37 @@ func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) { return value, []selects{} } - // 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 + ret := selects{} + for _, axis := range label.SortedConfigurationAxes() { + configToLabels := label.ConfigurableValues[axis] + for config, labels := range configToLabels { + selectKey := axis.SelectKey(config) + ret[selectKey] = reflect.ValueOf(labels) } } - 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} + return value, []selects{ret} } func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) { value := reflect.ValueOf(list.Value.Includes) - if !list.HasConfigurableValues() { - return value, []selects{} - } var ret []selects - - archSelects := map[string]reflect.Value{} - for arch, selectKey := range bazel.PlatformArchMap { - if use, value := labelListSelectValue(selectKey, list.GetValueForArch(arch)); use { - archSelects[selectKey] = value + for _, axis := range list.SortedConfigurationAxes() { + configToLabels := list.ConfigurableValues[axis] + if !configToLabels.HasConfigurableValues() { + continue } - } - if len(archSelects) > 0 { - ret = append(ret, archSelects) - } - - osSelects := map[string]reflect.Value{} - osArchSelects := []selects{} - for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) { - selectKey := bazel.PlatformOsMap[os] - if use, value := labelListSelectValue(selectKey, list.GetOsValueForTarget(os)); use { - osSelects[selectKey] = value - } - selects := make(map[string]reflect.Value) - // TODO(b/187530594): Should we also check arch=CONDITIOSN_DEFAULT? (not in AllArches) - for _, arch := range bazel.AllArches { - target := os + "_" + arch - selectKey := bazel.PlatformTargetMap[target] - if use, value := labelListSelectValue(selectKey, list.GetOsArchValueForTarget(os, arch)); use { - selects[selectKey] = value + archSelects := map[string]reflect.Value{} + for config, labels := range configToLabels { + selectKey := axis.SelectKey(config) + if use, value := labelListSelectValue(selectKey, labels); use { + archSelects[selectKey] = value } } - if len(selects) > 0 { - osArchSelects = append(osArchSelects, selects) + if len(archSelects) > 0 { + ret = append(ret, archSelects) } } - if len(osSelects) > 0 { - ret = append(ret, osSelects) - } - ret = append(ret, osArchSelects...) return value, ret } diff --git a/bp2build/testing.go b/bp2build/testing.go index e575bc6ff..861f7d25f 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -157,9 +157,11 @@ func customBp2BuildMutator(ctx android.TopDownMutatorContext) { paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths)) - for arch, props := range m.GetArchProperties(ctx, &customProps{}) { - if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil { - paths.SetValueForArch(arch.Name, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths)) + for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) { + for config, props := range configToProps { + if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil { + paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths)) + } } } diff --git a/cc/bp2build.go b/cc/bp2build.go index a156d5444..31e69d8a6 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -53,58 +53,29 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { var allDeps []string - for _, osProps := range module.GetTargetProperties(ctx, &BaseCompilerProperties{}) { - // os base compiler props - if baseCompilerProps, ok := osProps.Properties.(*BaseCompilerProperties); ok { - allDeps = append(allDeps, baseCompilerProps.Generated_headers...) - allDeps = append(allDeps, baseCompilerProps.Generated_sources...) - } - // os + arch base compiler props - for _, archProps := range osProps.ArchProperties { - if baseCompilerProps, ok := archProps.(*BaseCompilerProperties); ok { + for _, configToProps := range module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) { + for _, props := range configToProps { + if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { allDeps = append(allDeps, baseCompilerProps.Generated_headers...) allDeps = append(allDeps, baseCompilerProps.Generated_sources...) } } } - for _, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { - // arch specific compiler props - if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { - allDeps = append(allDeps, baseCompilerProps.Generated_headers...) - allDeps = append(allDeps, baseCompilerProps.Generated_sources...) - } - } - - for _, osProps := range module.GetTargetProperties(ctx, &BaseLinkerProperties{}) { - // os specific linker props - if baseLinkerProps, ok := osProps.Properties.(*BaseLinkerProperties); ok { - allDeps = append(allDeps, baseLinkerProps.Header_libs...) - allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...) - allDeps = append(allDeps, baseLinkerProps.Static_libs...) - allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...) - } - // os + arch base compiler props - for _, archProps := range osProps.ArchProperties { - if baseLinkerProps, ok := archProps.(*BaseLinkerProperties); ok { + for _, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) { + for _, props := range configToProps { + if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok { allDeps = append(allDeps, baseLinkerProps.Header_libs...) allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...) allDeps = append(allDeps, baseLinkerProps.Static_libs...) + allDeps = append(allDeps, baseLinkerProps.Exclude_static_libs...) allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...) + allDeps = append(allDeps, baseLinkerProps.Shared_libs...) + allDeps = append(allDeps, baseLinkerProps.Exclude_shared_libs...) } } } - for _, props := range module.GetArchProperties(ctx, &BaseLinkerProperties{}) { - // arch specific linker props - if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok { - allDeps = append(allDeps, baseLinkerProps.Header_libs...) - allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...) - allDeps = append(allDeps, baseLinkerProps.Static_libs...) - allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...) - } - } - // Deps in the static: { .. } and shared: { .. } props of a cc_library. if lib, ok := module.compiler.(*libraryDecorator); ok { appendDeps := func(deps []string, p StaticOrSharedProperties) []string { @@ -124,39 +95,21 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { // Deps in the target/arch nested static: { .. } and shared: { .. } props of a cc_library. // target: { : shared: { ... } } - for _, targetProps := range module.GetTargetProperties(ctx, &SharedProperties{}) { - if p, ok := targetProps.Properties.(*SharedProperties); ok { - allDeps = appendDeps(allDeps, p.Shared) - } - for _, archProperties := range targetProps.ArchProperties { - if p, ok := archProperties.(*SharedProperties); ok { + for _, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) { + for _, props := range configToProps { + if p, ok := props.(*SharedProperties); ok { allDeps = appendDeps(allDeps, p.Shared) } } } - // target: { : static: { ... } } - for _, targetProps := range module.GetTargetProperties(ctx, &StaticProperties{}) { - if p, ok := targetProps.Properties.(*StaticProperties); ok { - allDeps = appendDeps(allDeps, p.Static) - } - for _, archProperties := range targetProps.ArchProperties { - if p, ok := archProperties.(*StaticProperties); ok { + + for _, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) { + for _, props := range configToProps { + if p, ok := props.(*StaticProperties); ok { allDeps = appendDeps(allDeps, p.Static) } } } - // arch: { : shared: { ... } } - for _, properties := range module.GetArchProperties(ctx, &SharedProperties{}) { - if p, ok := properties.(*SharedProperties); ok { - allDeps = appendDeps(allDeps, p.Shared) - } - } - // arch: { : static: { ... } } - for _, properties := range module.GetArchProperties(ctx, &StaticProperties{}) { - if p, ok := properties.(*StaticProperties); ok { - allDeps = appendDeps(allDeps, p.Static) - } - } } ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...) @@ -275,65 +228,33 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module attrs := staticOrSharedAttributes{ copts: bazel.StringListAttribute{Value: props.Cflags}, - srcs: bazel.LabelListAttribute{Value: android.BazelLabelForModuleSrc(ctx, props.Srcs)}, - staticDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Static_libs)}, - dynamicDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Shared_libs)}, - wholeArchiveDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)}, + srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)), + staticDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)), + dynamicDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)), + wholeArchiveDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)), } - setArchAttrs := func(arch string, props StaticOrSharedProperties) { - attrs.copts.SetValueForArch(arch, props.Cflags) - attrs.srcs.SetValueForArch(arch, android.BazelLabelForModuleSrc(ctx, props.Srcs)) - attrs.staticDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) - attrs.dynamicDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) - attrs.wholeArchiveDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)) - } - - setTargetAttrs := func(target string, props StaticOrSharedProperties) { - attrs.copts.SetOsValueForTarget(target, props.Cflags) - attrs.srcs.SetOsValueForTarget(target, android.BazelLabelForModuleSrc(ctx, props.Srcs)) - attrs.staticDeps.SetOsValueForTarget(target, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) - attrs.dynamicDeps.SetOsValueForTarget(target, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) - attrs.wholeArchiveDeps.SetOsValueForTarget(target, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)) - } - - setTargetArchAttrs := func(target, arch string, props StaticOrSharedProperties) { - attrs.copts.SetOsArchValueForTarget(target, arch, props.Cflags) - attrs.srcs.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleSrc(ctx, props.Srcs)) - attrs.staticDeps.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) - attrs.dynamicDeps.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) - attrs.wholeArchiveDeps.SetOsArchValueForTarget(target, arch, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)) + setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) { + attrs.copts.SetSelectValue(axis, config, props.Cflags) + attrs.srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs)) + attrs.staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) + attrs.dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) + attrs.wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)) } if isStatic { - for arch, properties := range module.GetArchProperties(ctx, &StaticProperties{}) { - if staticOrSharedProps, ok := properties.(*StaticProperties); ok { - setArchAttrs(arch.Name, staticOrSharedProps.Static) - } - } - for target, p := range module.GetTargetProperties(ctx, &StaticProperties{}) { - if staticOrSharedProps, ok := p.Properties.(*StaticProperties); ok { - setTargetAttrs(target.Name, staticOrSharedProps.Static) - } - for arch, archProperties := range p.ArchProperties { - if staticOrSharedProps, ok := archProperties.(*StaticProperties); ok { - setTargetArchAttrs(target.Name, arch.Name, staticOrSharedProps.Static) + for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) { + for config, props := range configToProps { + if staticOrSharedProps, ok := props.(*StaticProperties); ok { + setAttrs(axis, config, staticOrSharedProps.Static) } } } } else { - for arch, p := range module.GetArchProperties(ctx, &SharedProperties{}) { - if staticOrSharedProps, ok := p.(*SharedProperties); ok { - setArchAttrs(arch.Name, staticOrSharedProps.Shared) - } - } - for target, p := range module.GetTargetProperties(ctx, &SharedProperties{}) { - if staticOrSharedProps, ok := p.Properties.(*SharedProperties); ok { - setTargetAttrs(target.Name, staticOrSharedProps.Shared) - } - for arch, archProperties := range p.ArchProperties { - if staticOrSharedProps, ok := archProperties.(*SharedProperties); ok { - setTargetArchAttrs(target.Name, arch.Name, staticOrSharedProps.Shared) + for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) { + for config, props := range configToProps { + if staticOrSharedProps, ok := props.(*SharedProperties); ok { + setAttrs(axis, config, staticOrSharedProps.Shared) } } } @@ -363,45 +284,23 @@ func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module } if len(prebuiltLinker.properties.Srcs) == 1 { - srcLabelAttribute.Value = android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]) - for arch, props := range module.GetArchProperties(ctx, &prebuiltLinkerProperties{}) { + srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0])) + } + for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) { + for config, props := range configToProps { if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok { if len(prebuiltLinkerProperties.Srcs) > 1 { - ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for arch %s\n", arch.Name) - } - if len(prebuiltLinkerProperties.Srcs) == 1 { - srcLabelAttribute.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])) + ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config) + continue + } else if len(prebuiltLinkerProperties.Srcs) == 0 { + continue } + src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0]) + srcLabelAttribute.SetSelectValue(axis, config, src) } } } - for os, targetProperties := range module.GetTargetProperties(ctx, &prebuiltLinkerProperties{}) { - if prebuiltLinkerProperties, ok := targetProperties.Properties.(*prebuiltLinkerProperties); ok { - if len(prebuiltLinkerProperties.Srcs) > 1 { - ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for os %s\n", os.Name) - - } - - if len(prebuiltLinkerProperties.Srcs) == 1 { - srcLabelAttribute.SetOsValueForTarget(os.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])) - } - } - for arch, archProperties := range targetProperties.ArchProperties { - if prebuiltLinkerProperties, ok := archProperties.(*prebuiltLinkerProperties); ok { - if len(prebuiltLinkerProperties.Srcs) > 1 { - ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for os_arch %s_%s\n", os.Name, arch.Name) - - } - - if len(prebuiltLinkerProperties.Srcs) == 1 { - srcLabelAttribute.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])) - } - } - - } - } - return prebuiltAttributes{ Src: srcLabelAttribute, } @@ -501,7 +400,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul for _, props := range module.compiler.compilerProps() { if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { - srcs.Value = parseSrcs(baseCompilerProps) + srcs.SetValue(parseSrcs(baseCompilerProps)) copts.Value = parseCopts(baseCompilerProps) asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags) conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags) @@ -524,65 +423,45 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul copts.Value = append(copts.Value, includeFlags(".")...) } - for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { - if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { - // If there's arch specific srcs or exclude_srcs, generate a select entry for it. - // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too. - if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { - srcsList := parseSrcs(baseCompilerProps) - srcs.SetValueForArch(arch.Name, srcsList) - // The base srcs value should not contain any arch-specific excludes. - srcs.Value = bazel.SubtractBazelLabelList(srcs.Value, bazel.LabelList{Includes: srcsList.Excludes}) - } + archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) - copts.SetValueForArch(arch.Name, parseCopts(baseCompilerProps)) - asFlags.SetValueForArch(arch.Name, parseCommandLineFlags(baseCompilerProps.Asflags)) - conlyFlags.SetValueForArch(arch.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags)) - cppFlags.SetValueForArch(arch.Name, parseCommandLineFlags(baseCompilerProps.Cppflags)) + for axis, configToProps := range archVariantCompilerProps { + for config, props := range configToProps { + if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { + // If there's arch specific srcs or exclude_srcs, generate a select entry for it. + // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too. + if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { + srcsList := parseSrcs(baseCompilerProps) + srcs.SetSelectValue(axis, config, srcsList) + // The base srcs value should not contain any arch-specific excludes. + srcs.SetValue(bazel.SubtractBazelLabelList(srcs.Value, bazel.LabelList{Includes: srcsList.Excludes})) + } + + copts.SetSelectValue(axis, config, parseCopts(baseCompilerProps)) + asFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Asflags)) + conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags)) + cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags)) + } } } // After going through all archs, delete the duplicate files in the arch // values that are already in the base srcs.Value. - for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { - if _, ok := props.(*BaseCompilerProperties); ok { - srcs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(srcs.GetValueForArch(arch.Name), srcs.Value)) + for axis, configToProps := range archVariantCompilerProps { + for config, props := range configToProps { + if _, ok := props.(*BaseCompilerProperties); ok { + // TODO: handle non-arch + srcs.SetSelectValue(axis, config, bazel.SubtractBazelLabelList(srcs.SelectValue(axis, config), srcs.Value)) + } } } // Now that the srcs.Value list is finalized, compare it with the original // list, and put the difference into the default condition for the arch // select. - defaultsSrcs := bazel.SubtractBazelLabelList(baseSrcsLabelList, srcs.Value) - // TODO(b/186153868): handle the case with multiple variant types, e.g. when arch and os are both used. - srcs.SetValueForArch(bazel.CONDITIONS_DEFAULT, defaultsSrcs) - - // Handle target specific properties. - for os, osProps := range module.GetTargetProperties(ctx, &BaseCompilerProperties{}) { - if baseCompilerProps, ok := osProps.Properties.(*BaseCompilerProperties); ok { - srcsList := parseSrcs(baseCompilerProps) - // TODO(b/186153868): add support for os-specific srcs and exclude_srcs - if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { - srcs.SetOsValueForTarget(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList)) - } - copts.SetOsValueForTarget(os.Name, parseCopts(baseCompilerProps)) - asFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Asflags)) - conlyFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags)) - cppFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Cppflags)) - } - for arch, archProps := range osProps.ArchProperties { - if baseCompilerProps, ok := archProps.(*BaseCompilerProperties); ok { - srcsList := parseSrcs(baseCompilerProps) - // TODO(b/186153868): add support for os-specific srcs and exclude_srcs - if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 { - srcs.SetOsArchValueForTarget(os.Name, arch.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList)) - } - copts.SetOsArchValueForTarget(os.Name, arch.Name, parseCopts(baseCompilerProps)) - asFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Asflags)) - conlyFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags)) - cppFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Cppflags)) - } - } + for axis := range archVariantCompilerProps { + defaultsSrcs := bazel.SubtractBazelLabelList(baseSrcsLabelList, srcs.Value) + srcs.SetSelectValue(axis, bazel.ConditionsDefault, defaultsSrcs) } productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{ @@ -599,10 +478,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName)) } newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable) - attr.ProductValues = append(attr.ProductValues, bazel.ProductVariableValues{ - ProductVariable: prop.ProductConfigVariable, - Values: newFlags, - }) + attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.ProductConfigVariable), prop.ProductConfigVariable, newFlags) } } } @@ -667,7 +543,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) if baseLinkerProps.Version_script != nil { - versionScript.Value = android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script) + versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) } sharedLibs := baseLinkerProps.Shared_libs @@ -677,61 +553,23 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) } } - for arch, props := range module.GetArchProperties(ctx, &BaseLinkerProperties{}) { - if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok { - libs := getLibs(baseLinkerProps) - exportedLibs := baseLinkerProps.Export_header_lib_headers - wholeArchiveLibs := baseLinkerProps.Whole_static_libs - deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs)) - exportedDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, exportedLibs)) - linkopts.SetValueForArch(arch.Name, getBp2BuildLinkerFlags(baseLinkerProps)) - wholeArchiveDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) - - if baseLinkerProps.Version_script != nil { - versionScript.SetValueForArch(arch.Name, - android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) - } - - sharedLibs := baseLinkerProps.Shared_libs - dynamicDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs)) - } - } - - for os, targetProperties := range module.GetTargetProperties(ctx, &BaseLinkerProperties{}) { - if baseLinkerProps, ok := targetProperties.Properties.(*BaseLinkerProperties); ok { - libs := getLibs(baseLinkerProps) - exportedLibs := baseLinkerProps.Export_header_lib_headers - wholeArchiveLibs := baseLinkerProps.Whole_static_libs - wholeArchiveDeps.SetOsValueForTarget(os.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) - deps.SetOsValueForTarget(os.Name, android.BazelLabelForModuleDeps(ctx, libs)) - exportedDeps.SetOsValueForTarget(os.Name, android.BazelLabelForModuleDeps(ctx, exportedLibs)) - - 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)) - } - for arch, archProperties := range targetProperties.ArchProperties { - if baseLinkerProps, ok := archProperties.(*BaseLinkerProperties); ok { + for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) { + for config, props := range configToProps { + if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok { libs := getLibs(baseLinkerProps) exportedLibs := baseLinkerProps.Export_header_lib_headers wholeArchiveLibs := baseLinkerProps.Whole_static_libs - wholeArchiveDeps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) - deps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, libs)) - exportedDeps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, exportedLibs)) - - linkopts.SetOsArchValueForTarget(os.Name, arch.Name, getBp2BuildLinkerFlags(baseLinkerProps)) + deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, libs)) + exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs)) + linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps)) + wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) if baseLinkerProps.Version_script != nil { - versionScript.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) + versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) } sharedLibs := baseLinkerProps.Shared_libs - dynamicDeps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs)) + dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, sharedLibs)) } } } @@ -800,27 +638,12 @@ func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, modu return variantIncludeDirs } - for arch, props := range module.GetArchProperties(ctx, &FlagExporterProperties{}) { - if flagExporterProperties, ok := props.(*FlagExporterProperties); ok { - archIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties) - if len(archIncludeDirs) > 0 { - includeDirsAttribute.SetValueForArch(arch.Name, archIncludeDirs) - } - } - } - - for os, targetProperties := range module.GetTargetProperties(ctx, &FlagExporterProperties{}) { - if flagExporterProperties, ok := targetProperties.Properties.(*FlagExporterProperties); ok { - targetIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties) - if len(targetIncludeDirs) > 0 { - includeDirsAttribute.SetOsValueForTarget(os.Name, targetIncludeDirs) - } - } - for arch, archProperties := range targetProperties.ArchProperties { - if flagExporterProperties, ok := archProperties.(*FlagExporterProperties); ok { - targetIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties) - if len(targetIncludeDirs) > 0 { - includeDirsAttribute.SetOsArchValueForTarget(os.Name, arch.Name, targetIncludeDirs) + for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) { + for config, props := range configToProps { + if flagExporterProperties, ok := props.(*FlagExporterProperties); ok { + archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties) + if len(archVariantIncludeDirs) > 0 { + includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs) } } } diff --git a/cc/library.go b/cc/library.go index 2b44a91f2..873489db2 100644 --- a/cc/library.go +++ b/cc/library.go @@ -305,8 +305,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { linkerAttrs := bp2BuildParseLinkerProps(ctx, m) exportedIncludes := bp2BuildParseExportedIncludes(ctx, m) - var srcs bazel.LabelListAttribute - srcs.Append(compilerAttrs.srcs) + srcs := compilerAttrs.srcs attrs := &bazelCcLibraryAttributes{ Srcs: srcs,