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
This commit is contained in:
Liz Kammer
2021-05-21 08:37:59 -04:00
parent 37b3626f2c
commit 9abd62d133
12 changed files with 721 additions and 1207 deletions

View File

@@ -15,6 +15,7 @@
package android package android
import ( import (
"android/soong/bazel"
"encoding" "encoding"
"fmt" "fmt"
"reflect" "reflect"
@@ -897,7 +898,7 @@ func createArchPropTypeDesc(props reflect.Type) []archPropTypeDesc {
// Add the OS/Arch combinations, e.g. "android_arm64". // Add the OS/Arch combinations, e.g. "android_arm64".
for _, archType := range osArchTypeMap[os] { for _, archType := range osArchTypeMap[os] {
targets = append(targets, GetCompoundTargetName(os, archType)) targets = append(targets, GetCompoundTargetField(os, archType))
// Also add the special "linux_<arch>" and "bionic_<arch>" property structs. // Also add the special "linux_<arch>" and "bionic_<arch>" property structs.
if os.Linux() { if os.Linux() {
@@ -1217,7 +1218,7 @@ func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archT
return getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib) 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 return os.Field + "_" + arch.Name
} }
@@ -1327,7 +1328,7 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch
// key: value, // key: value,
// }, // },
// }, // },
field := GetCompoundTargetName(os, archType) field := GetCompoundTargetField(os, archType)
userFriendlyField := "target." + os.Name + "_" + archType.Name userFriendlyField := "target." + os.Name + "_" + archType.Name
if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
result = append(result, osArchProperties) result = append(result, osArchProperties)
@@ -1882,27 +1883,38 @@ type ArchVariantContext interface {
PropertyErrorf(property, fmt string, args ...interface{}) PropertyErrorf(property, fmt string, args ...interface{})
} }
// GetArchProperties returns a map of architectures to the values of the // ArchVariantProperties represents a map of arch-variant config strings to a property interface{}.
// properties of the 'propertySet' struct that are specific to that architecture. 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 // For example, passing a struct { Foo bool, Bar string } will return an interface{} that can be
// interface{} that can be type asserted back into the same struct, containing // type asserted back into the same struct, containing the config-specific property value specified
// the arch specific property value specified by the module if defined. // by the module if defined.
// //
// Arch-specific properties may come from an arch stanza or a multilib stanza; properties // Arch-specific properties may come from an arch stanza or a multilib stanza; properties
// in these stanzas are combined. // in these stanzas are combined.
// For example: `arch: { x86: { Foo: ["bar"] } }, multilib: { lib32: {` Foo: ["baz"] } }` // For example: `arch: { x86: { Foo: ["bar"] } }, multilib: { lib32: {` Foo: ["baz"] } }`
// will result in `Foo: ["bar", "baz"]` being returned for architecture x86, if the given // will result in `Foo: ["bar", "baz"]` being returned for architecture x86, if the given
// propertyset contains `Foo []string`. // propertyset contains `Foo []string`.
// func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySet interface{}) ConfigurationAxisToArchVariantProperties {
// Implemented in a way very similar to GetTargetProperties().
func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet interface{}) map[ArchType]interface{} {
// Return value of the arch types to the prop values for that arch. // 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. // Nothing to do for non-arch-specific modules.
if !m.ArchSpecific() { if !m.ArchSpecific() {
return archToProp return axisToProps
} }
dstType := reflect.ValueOf(propertySet).Type() dstType := reflect.ValueOf(propertySet).Type()
@@ -1920,9 +1932,10 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter
if archProperties == nil { if archProperties == nil {
// This module does not have the property set requested // This module does not have the property set requested
return archToProp return axisToProps
} }
archToProp := ArchVariantProperties{}
// For each arch type (x86, arm64, etc.) // For each arch type (x86, arm64, etc.)
for _, arch := range ArchTypeList() { for _, arch := range ArchTypeList() {
// Arch properties are sometimes sharded (see createArchPropTypeDesc() ). // Arch properties are sometimes sharded (see createArchPropTypeDesc() ).
@@ -1948,10 +1961,30 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter
mergePropertyStruct(ctx, value, propertyStruct) 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 // 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 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
}

View File

@@ -479,18 +479,11 @@ func ProductVariableProperties(ctx BaseMutatorContext) ProductConfigProperties {
productVariableValues(moduleBase.variableProperties, "", &productConfigProperties) productVariableValues(moduleBase.variableProperties, "", &productConfigProperties)
for arch, targetProps := range moduleBase.GetArchProperties(ctx, moduleBase.variableProperties) { for _, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) {
// GetArchProperties is creating an instance of the requested type for config, props := range configToProps {
// and productVariablesValues expects an interface, so no need to cast // GetArchVariantProperties is creating an instance of the requested type
productVariableValues(targetProps, arch.Name, &productConfigProperties) // and productVariablesValues expects an interface, so no need to cast
} productVariableValues(props, config, &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)
} }
} }

View File

@@ -7,6 +7,7 @@ bootstrap_go_package {
pkgPath: "android/soong/bazel", pkgPath: "android/soong/bazel",
srcs: [ srcs: [
"aquery.go", "aquery.go",
"configurability.go",
"constants.go", "constants.go",
"properties.go", "properties.go",
], ],

213
bazel/configurability.go Normal file
View File

@@ -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
}

File diff suppressed because it is too large Load Diff

View File

@@ -122,7 +122,7 @@ func TestSubtractBazelLabelList(t *testing.T) {
} }
} }
} }
func TestUniqueBazelLabelList(t *testing.T) { func TestFirstUniqueBazelLabelList(t *testing.T) {
testCases := []struct { testCases := []struct {
originalLabelList LabelList originalLabelList LabelList
expectedUniqueLabelList LabelList expectedUniqueLabelList LabelList
@@ -157,7 +157,49 @@ func TestUniqueBazelLabelList(t *testing.T) {
}, },
} }
for _, tc := range testCases { 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) { if !reflect.DeepEqual(tc.expectedUniqueLabelList, actualUniqueLabelList) {
t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList) t.Fatalf("Expected %v, got %v", tc.expectedUniqueLabelList, actualUniqueLabelList)
} }

View File

@@ -1109,8 +1109,8 @@ genrule {
"out", "out",
], ],
srcs = [ srcs = [
"in1",
"srcs-from-3", "srcs-from-3",
"in1",
], ],
)`, )`,
description: "genrule applies properties from genrule_defaults transitively", description: "genrule applies properties from genrule_defaults transitively",
@@ -1535,10 +1535,10 @@ func TestGlobExcludeSrcs(t *testing.T) {
expectedBazelTargets: []string{`filegroup( expectedBazelTargets: []string{`filegroup(
name = "fg_foo", name = "fg_foo",
srcs = [ srcs = [
"//dir:e.txt",
"//dir:f.txt",
"a.txt", "a.txt",
"b.txt", "b.txt",
"//dir:e.txt",
"//dir:f.txt",
], ],
)`, )`,
}, },
@@ -1575,9 +1575,9 @@ func TestGlobExcludeSrcs(t *testing.T) {
expectedBazelTargets: []string{`filegroup( expectedBazelTargets: []string{`filegroup(
name = "fg_foo", name = "fg_foo",
srcs = [ srcs = [
"a.txt",
"//dir/subdir:e.txt", "//dir/subdir:e.txt",
"//dir/subdir:f.txt", "//dir/subdir:f.txt",
"a.txt",
], ],
)`, )`,
}, },

View File

@@ -1286,8 +1286,6 @@ cc_library_static {
"//build/bazel/platforms/os_arch:android_arm64": ["android_arm64_src.c"], "//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": ["android_x86_src.c"],
"//build/bazel/platforms/os_arch:android_x86_64": ["android_x86_64_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_arm64": ["linux_bionic_arm64_src.c"],
"//build/bazel/platforms/os_arch:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"], "//build/bazel/platforms/os_arch:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
"//conditions:default": [], "//conditions:default": [],

View File

@@ -17,46 +17,20 @@ func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selec
return value, []selects{} return value, []selects{}
} }
selectValues := make([]selects, 0) var ret []selects
archSelects := map[string]reflect.Value{} for _, axis := range list.SortedConfigurationAxes() {
for arch, selectKey := range bazel.PlatformArchMap { configToLists := list.ConfigurableValues[axis]
archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch)) archSelects := map[string]reflect.Value{}
} for config, labels := range configToLists {
if len(archSelects) > 0 { selectKey := axis.SelectKey(config)
selectValues = append(selectValues, archSelects) archSelects[selectKey] = reflect.ValueOf(labels)
}
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))
} }
osArchSelects = append(osArchSelects, archSelects) if len(archSelects) > 0 {
} ret = append(ret, 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)
} }
} }
return value, selectValues return value, ret
} }
func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) { func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
@@ -65,105 +39,37 @@ func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
return value, []selects{} return value, []selects{}
} }
// Keep track of which arches and oses have been used in case we need to raise a warning ret := selects{}
usedArches := make(map[string]bool) for _, axis := range label.SortedConfigurationAxes() {
usedOses := make(map[string]bool) configToLabels := label.ConfigurableValues[axis]
for config, labels := range configToLabels {
archSelects := map[string]reflect.Value{} selectKey := axis.SelectKey(config)
for arch, selectKey := range bazel.PlatformArchMap { ret[selectKey] = reflect.ValueOf(labels)
archSelects[selectKey] = reflect.ValueOf(label.GetValueForArch(arch))
if archSelects[selectKey].IsValid() && !isZero(archSelects[selectKey]) {
usedArches[arch] = true
} }
} }
osSelects := map[string]reflect.Value{} return value, []selects{ret}
for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
selectKey := bazel.PlatformOsMap[os]
osSelects[selectKey] = reflect.ValueOf(label.GetOsValueForTarget(os))
if osSelects[selectKey].IsValid() && !isZero(osSelects[selectKey]) {
usedOses[os] = true
}
}
osArchSelects := make([]selects, 0)
for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
archSelects := make(map[string]reflect.Value)
// TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT? (not in AllArches)
for _, arch := range bazel.AllArches {
target := os + "_" + arch
selectKey := bazel.PlatformTargetMap[target]
archSelects[selectKey] = reflect.ValueOf(label.GetOsArchValueForTarget(os, arch))
if archSelects[selectKey].IsValid() && !isZero(archSelects[selectKey]) {
if _, ok := usedArches[arch]; ok {
fmt.Printf("WARNING: Same arch used twice in LabelAttribute select: arch '%s'\n", arch)
}
if _, ok := usedOses[os]; ok {
fmt.Printf("WARNING: Same os used twice in LabelAttribute select: os '%s'\n", os)
}
}
}
osArchSelects = append(osArchSelects, archSelects)
}
// Because we have to return a single Label, we can only use one select statement
combinedSelects := map[string]reflect.Value{}
for k, v := range archSelects {
combinedSelects[k] = v
}
for k, v := range osSelects {
combinedSelects[k] = v
}
for _, osArchSelect := range osArchSelects {
for k, v := range osArchSelect {
combinedSelects[k] = v
}
}
return value, []selects{combinedSelects}
} }
func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) { func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value.Includes) value := reflect.ValueOf(list.Value.Includes)
if !list.HasConfigurableValues() {
return value, []selects{}
}
var ret []selects var ret []selects
for _, axis := range list.SortedConfigurationAxes() {
archSelects := map[string]reflect.Value{} configToLabels := list.ConfigurableValues[axis]
for arch, selectKey := range bazel.PlatformArchMap { if !configToLabels.HasConfigurableValues() {
if use, value := labelListSelectValue(selectKey, list.GetValueForArch(arch)); use { continue
archSelects[selectKey] = value
} }
} archSelects := map[string]reflect.Value{}
if len(archSelects) > 0 { for config, labels := range configToLabels {
ret = append(ret, archSelects) selectKey := axis.SelectKey(config)
} if use, value := labelListSelectValue(selectKey, labels); use {
archSelects[selectKey] = value
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
} }
} }
if len(selects) > 0 { if len(archSelects) > 0 {
osArchSelects = append(osArchSelects, selects) ret = append(ret, archSelects)
} }
} }
if len(osSelects) > 0 {
ret = append(ret, osSelects)
}
ret = append(ret, osArchSelects...)
return value, ret return value, ret
} }

View File

@@ -157,9 +157,11 @@ func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths)) paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths))
for arch, props := range m.GetArchProperties(ctx, &customProps{}) { for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil { for config, props := range configToProps {
paths.SetValueForArch(arch.Name, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths)) if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths))
}
} }
} }

View File

@@ -53,58 +53,29 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) {
var allDeps []string var allDeps []string
for _, osProps := range module.GetTargetProperties(ctx, &BaseCompilerProperties{}) { for _, configToProps := range module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) {
// os base compiler props for _, props := range configToProps {
if baseCompilerProps, ok := osProps.Properties.(*BaseCompilerProperties); ok { if baseCompilerProps, ok := props.(*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 {
allDeps = append(allDeps, baseCompilerProps.Generated_headers...) allDeps = append(allDeps, baseCompilerProps.Generated_headers...)
allDeps = append(allDeps, baseCompilerProps.Generated_sources...) allDeps = append(allDeps, baseCompilerProps.Generated_sources...)
} }
} }
} }
for _, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { for _, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
// arch specific compiler props for _, props := range configToProps {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { if baseLinkerProps, ok := props.(*BaseLinkerProperties); 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 {
allDeps = append(allDeps, baseLinkerProps.Header_libs...) allDeps = append(allDeps, baseLinkerProps.Header_libs...)
allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...) allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...)
allDeps = append(allDeps, baseLinkerProps.Static_libs...) allDeps = append(allDeps, baseLinkerProps.Static_libs...)
allDeps = append(allDeps, baseLinkerProps.Exclude_static_libs...)
allDeps = append(allDeps, baseLinkerProps.Whole_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. // Deps in the static: { .. } and shared: { .. } props of a cc_library.
if lib, ok := module.compiler.(*libraryDecorator); ok { if lib, ok := module.compiler.(*libraryDecorator); ok {
appendDeps := func(deps []string, p StaticOrSharedProperties) []string { 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. // Deps in the target/arch nested static: { .. } and shared: { .. } props of a cc_library.
// target: { <target>: shared: { ... } } // target: { <target>: shared: { ... } }
for _, targetProps := range module.GetTargetProperties(ctx, &SharedProperties{}) { for _, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
if p, ok := targetProps.Properties.(*SharedProperties); ok { for _, props := range configToProps {
allDeps = appendDeps(allDeps, p.Shared) if p, ok := props.(*SharedProperties); ok {
}
for _, archProperties := range targetProps.ArchProperties {
if p, ok := archProperties.(*SharedProperties); ok {
allDeps = appendDeps(allDeps, p.Shared) allDeps = appendDeps(allDeps, p.Shared)
} }
} }
} }
// target: { <target>: static: { ... } }
for _, targetProps := range module.GetTargetProperties(ctx, &StaticProperties{}) { for _, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
if p, ok := targetProps.Properties.(*StaticProperties); ok { for _, props := range configToProps {
allDeps = appendDeps(allDeps, p.Static) if p, ok := props.(*StaticProperties); ok {
}
for _, archProperties := range targetProps.ArchProperties {
if p, ok := archProperties.(*StaticProperties); ok {
allDeps = appendDeps(allDeps, p.Static) allDeps = appendDeps(allDeps, p.Static)
} }
} }
} }
// arch: { <arch>: shared: { ... } }
for _, properties := range module.GetArchProperties(ctx, &SharedProperties{}) {
if p, ok := properties.(*SharedProperties); ok {
allDeps = appendDeps(allDeps, p.Shared)
}
}
// arch: { <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)...) ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
@@ -275,65 +228,33 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module
attrs := staticOrSharedAttributes{ attrs := staticOrSharedAttributes{
copts: bazel.StringListAttribute{Value: props.Cflags}, copts: bazel.StringListAttribute{Value: props.Cflags},
srcs: bazel.LabelListAttribute{Value: android.BazelLabelForModuleSrc(ctx, props.Srcs)}, srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
staticDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Static_libs)}, staticDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
dynamicDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Shared_libs)}, dynamicDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)),
wholeArchiveDeps: bazel.LabelListAttribute{Value: android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)}, wholeArchiveDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)),
} }
setArchAttrs := func(arch string, props StaticOrSharedProperties) { setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
attrs.copts.SetValueForArch(arch, props.Cflags) attrs.copts.SetSelectValue(axis, config, props.Cflags)
attrs.srcs.SetValueForArch(arch, android.BazelLabelForModuleSrc(ctx, props.Srcs)) attrs.srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
attrs.staticDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) attrs.staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
attrs.dynamicDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) attrs.dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
attrs.wholeArchiveDeps.SetValueForArch(arch, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)) attrs.wholeArchiveDeps.SetSelectValue(axis, config, 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))
} }
if isStatic { if isStatic {
for arch, properties := range module.GetArchProperties(ctx, &StaticProperties{}) { for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
if staticOrSharedProps, ok := properties.(*StaticProperties); ok { for config, props := range configToProps {
setArchAttrs(arch.Name, staticOrSharedProps.Static) if staticOrSharedProps, ok := props.(*StaticProperties); ok {
} setAttrs(axis, config, 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)
} }
} }
} }
} else { } else {
for arch, p := range module.GetArchProperties(ctx, &SharedProperties{}) { for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
if staticOrSharedProps, ok := p.(*SharedProperties); ok { for config, props := range configToProps {
setArchAttrs(arch.Name, staticOrSharedProps.Shared) if staticOrSharedProps, ok := props.(*SharedProperties); ok {
} setAttrs(axis, config, 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)
} }
} }
} }
@@ -363,45 +284,23 @@ func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module
} }
if len(prebuiltLinker.properties.Srcs) == 1 { if len(prebuiltLinker.properties.Srcs) == 1 {
srcLabelAttribute.Value = android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]) srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]))
for arch, props := range module.GetArchProperties(ctx, &prebuiltLinkerProperties{}) { }
for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
for config, props := range configToProps {
if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok { if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
if len(prebuiltLinkerProperties.Srcs) > 1 { if len(prebuiltLinkerProperties.Srcs) > 1 {
ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for arch %s\n", arch.Name) ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
} continue
if len(prebuiltLinkerProperties.Srcs) == 1 { } else if len(prebuiltLinkerProperties.Srcs) == 0 {
srcLabelAttribute.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcSingle(ctx, 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{ return prebuiltAttributes{
Src: srcLabelAttribute, Src: srcLabelAttribute,
} }
@@ -501,7 +400,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
for _, props := range module.compiler.compilerProps() { for _, props := range module.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
srcs.Value = parseSrcs(baseCompilerProps) srcs.SetValue(parseSrcs(baseCompilerProps))
copts.Value = parseCopts(baseCompilerProps) copts.Value = parseCopts(baseCompilerProps)
asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags) asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags) conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
@@ -524,65 +423,45 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul
copts.Value = append(copts.Value, includeFlags(".")...) copts.Value = append(copts.Value, includeFlags(".")...)
} }
for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { archVariantCompilerProps := module.GetArchVariantProperties(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})
}
copts.SetValueForArch(arch.Name, parseCopts(baseCompilerProps)) for axis, configToProps := range archVariantCompilerProps {
asFlags.SetValueForArch(arch.Name, parseCommandLineFlags(baseCompilerProps.Asflags)) for config, props := range configToProps {
conlyFlags.SetValueForArch(arch.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags)) if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
cppFlags.SetValueForArch(arch.Name, parseCommandLineFlags(baseCompilerProps.Cppflags)) // 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 // After going through all archs, delete the duplicate files in the arch
// values that are already in the base srcs.Value. // values that are already in the base srcs.Value.
for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { for axis, configToProps := range archVariantCompilerProps {
if _, ok := props.(*BaseCompilerProperties); ok { for config, props := range configToProps {
srcs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(srcs.GetValueForArch(arch.Name), srcs.Value)) 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 // 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 // list, and put the difference into the default condition for the arch
// select. // select.
defaultsSrcs := bazel.SubtractBazelLabelList(baseSrcsLabelList, srcs.Value) for axis := range archVariantCompilerProps {
// TODO(b/186153868): handle the case with multiple variant types, e.g. when arch and os are both used. defaultsSrcs := bazel.SubtractBazelLabelList(baseSrcsLabelList, srcs.Value)
srcs.SetValueForArch(bazel.CONDITIONS_DEFAULT, defaultsSrcs) srcs.SetSelectValue(axis, bazel.ConditionsDefault, 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))
}
}
} }
productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{ 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)) ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
} }
newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable) newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
attr.ProductValues = append(attr.ProductValues, bazel.ProductVariableValues{ attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.ProductConfigVariable), prop.ProductConfigVariable, newFlags)
ProductVariable: prop.ProductConfigVariable,
Values: newFlags,
})
} }
} }
} }
@@ -667,7 +543,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
if baseLinkerProps.Version_script != nil { 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 sharedLibs := baseLinkerProps.Shared_libs
@@ -677,61 +553,23 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
} }
} }
for arch, props := range module.GetArchProperties(ctx, &BaseLinkerProperties{}) { for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok { for config, props := range configToProps {
libs := getLibs(baseLinkerProps) if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
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 {
libs := getLibs(baseLinkerProps) libs := getLibs(baseLinkerProps)
exportedLibs := baseLinkerProps.Export_header_lib_headers exportedLibs := baseLinkerProps.Export_header_lib_headers
wholeArchiveLibs := baseLinkerProps.Whole_static_libs wholeArchiveLibs := baseLinkerProps.Whole_static_libs
wholeArchiveDeps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs)) deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, libs))
deps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, libs)) exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
exportedDeps.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleDeps(ctx, exportedLibs)) linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
linkopts.SetOsArchValueForTarget(os.Name, arch.Name, getBp2BuildLinkerFlags(baseLinkerProps))
if baseLinkerProps.Version_script != nil { 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 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 return variantIncludeDirs
} }
for arch, props := range module.GetArchProperties(ctx, &FlagExporterProperties{}) { for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
if flagExporterProperties, ok := props.(*FlagExporterProperties); ok { for config, props := range configToProps {
archIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties) if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
if len(archIncludeDirs) > 0 { archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
includeDirsAttribute.SetValueForArch(arch.Name, archIncludeDirs) if len(archVariantIncludeDirs) > 0 {
} includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
}
}
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)
} }
} }
} }

View File

@@ -305,8 +305,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) {
linkerAttrs := bp2BuildParseLinkerProps(ctx, m) linkerAttrs := bp2BuildParseLinkerProps(ctx, m)
exportedIncludes := bp2BuildParseExportedIncludes(ctx, m) exportedIncludes := bp2BuildParseExportedIncludes(ctx, m)
var srcs bazel.LabelListAttribute srcs := compilerAttrs.srcs
srcs.Append(compilerAttrs.srcs)
attrs := &bazelCcLibraryAttributes{ attrs := &bazelCcLibraryAttributes{
Srcs: srcs, Srcs: srcs,