product_variables srcs in prebuilt_etc
bp2build conversion handles product_variable srcs bug: 228353067 Test: prebuilt_etc_conversion_test.go Change-Id: I82d3a384ee14d4e981d502dd9eb824c87d5ae2c7
This commit is contained in:
parent
94e2603ab7
commit
bbfd538326
6 changed files with 144 additions and 20 deletions
|
@ -592,6 +592,9 @@ type ProductConfigProperty struct {
|
||||||
// "acme__board__soc_a", "acme__board__soc_b", and
|
// "acme__board__soc_a", "acme__board__soc_b", and
|
||||||
// "acme__board__conditions_default"
|
// "acme__board__conditions_default"
|
||||||
FullConfig string
|
FullConfig string
|
||||||
|
|
||||||
|
// keeps track of whether this product variable is nested under an arch variant
|
||||||
|
OuterAxis bazel.ConfigurationAxis
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProductConfigProperty) AlwaysEmit() bool {
|
func (p *ProductConfigProperty) AlwaysEmit() bool {
|
||||||
|
@ -600,11 +603,11 @@ func (p *ProductConfigProperty) AlwaysEmit() bool {
|
||||||
|
|
||||||
func (p *ProductConfigProperty) ConfigurationAxis() bazel.ConfigurationAxis {
|
func (p *ProductConfigProperty) ConfigurationAxis() bazel.ConfigurationAxis {
|
||||||
if p.Namespace == "" {
|
if p.Namespace == "" {
|
||||||
return bazel.ProductVariableConfigurationAxis(p.FullConfig)
|
return bazel.ProductVariableConfigurationAxis(p.FullConfig, p.OuterAxis)
|
||||||
} else {
|
} else {
|
||||||
// Soong config variables can be uniquely identified by the namespace
|
// Soong config variables can be uniquely identified by the namespace
|
||||||
// (e.g. acme, android) and the product variable name (e.g. board, size)
|
// (e.g. acme, android) and the product variable name (e.g. board, size)
|
||||||
return bazel.ProductVariableConfigurationAxis(p.Namespace + "__" + p.Name)
|
return bazel.ProductVariableConfigurationAxis(p.Namespace+"__"+p.Name, bazel.NoConfigAxis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,9 +666,11 @@ func ProductVariableProperties(ctx BazelConversionPathContext) ProductConfigProp
|
||||||
moduleBase.variableProperties,
|
moduleBase.variableProperties,
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
&productConfigProperties)
|
&productConfigProperties,
|
||||||
|
bazel.ConfigurationAxis{},
|
||||||
|
)
|
||||||
|
|
||||||
for _, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) {
|
for axis, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) {
|
||||||
for config, props := range configToProps {
|
for config, props := range configToProps {
|
||||||
// GetArchVariantProperties is creating an instance of the requested type
|
// GetArchVariantProperties is creating an instance of the requested type
|
||||||
// and productVariablesValues expects an interface, so no need to cast
|
// and productVariablesValues expects an interface, so no need to cast
|
||||||
|
@ -674,7 +679,8 @@ func ProductVariableProperties(ctx BazelConversionPathContext) ProductConfigProp
|
||||||
props,
|
props,
|
||||||
"",
|
"",
|
||||||
config,
|
config,
|
||||||
&productConfigProperties)
|
&productConfigProperties,
|
||||||
|
axis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -687,7 +693,8 @@ func ProductVariableProperties(ctx BazelConversionPathContext) ProductConfigProp
|
||||||
namespacedVariableProp,
|
namespacedVariableProp,
|
||||||
namespace,
|
namespace,
|
||||||
"",
|
"",
|
||||||
&productConfigProperties)
|
&productConfigProperties,
|
||||||
|
bazel.NoConfigAxis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -803,6 +810,7 @@ func (props *ProductConfigProperties) zeroValuesForNamespacedVariables() {
|
||||||
p.Name,
|
p.Name,
|
||||||
p.FullConfig,
|
p.FullConfig,
|
||||||
zeroValue,
|
zeroValue,
|
||||||
|
bazel.NoConfigAxis,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,7 +818,7 @@ func (props *ProductConfigProperties) zeroValuesForNamespacedVariables() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProductConfigProperties) AddProductConfigProperty(
|
func (p *ProductConfigProperties) AddProductConfigProperty(
|
||||||
propertyName, namespace, productVariableName, config string, property interface{}) {
|
propertyName, namespace, productVariableName, config string, property interface{}, outerAxis bazel.ConfigurationAxis) {
|
||||||
if (*p)[propertyName] == nil {
|
if (*p)[propertyName] == nil {
|
||||||
(*p)[propertyName] = make(map[ProductConfigProperty]interface{})
|
(*p)[propertyName] = make(map[ProductConfigProperty]interface{})
|
||||||
}
|
}
|
||||||
|
@ -819,6 +827,7 @@ func (p *ProductConfigProperties) AddProductConfigProperty(
|
||||||
Namespace: namespace, // e.g. acme, android
|
Namespace: namespace, // e.g. acme, android
|
||||||
Name: productVariableName, // e.g. size, feature1, feature2, FEATURE3, board
|
Name: productVariableName, // e.g. size, feature1, feature2, FEATURE3, board
|
||||||
FullConfig: config, // e.g. size, feature1-x86, size__conditions_default
|
FullConfig: config, // e.g. size, feature1-x86, size__conditions_default
|
||||||
|
OuterAxis: outerAxis,
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing, ok := (*p)[propertyName][productConfigProp]; ok && namespace != "" {
|
if existing, ok := (*p)[propertyName][productConfigProp]; ok && namespace != "" {
|
||||||
|
@ -869,7 +878,7 @@ func maybeExtractConfigVarProp(v reflect.Value) (reflect.Value, bool) {
|
||||||
return v, true
|
return v, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (productConfigProperties *ProductConfigProperties) AddProductConfigProperties(namespace, suffix string, variableValues reflect.Value) {
|
func (productConfigProperties *ProductConfigProperties) AddProductConfigProperties(namespace, suffix string, variableValues reflect.Value, outerAxis bazel.ConfigurationAxis) {
|
||||||
// variableValues can either be a product_variables or
|
// variableValues can either be a product_variables or
|
||||||
// soong_config_variables struct.
|
// soong_config_variables struct.
|
||||||
//
|
//
|
||||||
|
@ -974,7 +983,8 @@ func (productConfigProperties *ProductConfigProperties) AddProductConfigProperti
|
||||||
namespace, // e.g. acme, android
|
namespace, // e.g. acme, android
|
||||||
productVariableName, // e.g. size, feature1, FEATURE2, board
|
productVariableName, // e.g. size, feature1, FEATURE2, board
|
||||||
config,
|
config,
|
||||||
field.Field(k).Interface(), // e.g. ["-DDEFAULT"], ["foo", "bar"]
|
field.Field(k).Interface(), // e.g. ["-DDEFAULT"], ["foo", "bar"],
|
||||||
|
outerAxis,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if property.Kind() != reflect.Interface {
|
} else if property.Kind() != reflect.Interface {
|
||||||
|
@ -988,6 +998,7 @@ func (productConfigProperties *ProductConfigProperties) AddProductConfigProperti
|
||||||
productVariableName,
|
productVariableName,
|
||||||
config,
|
config,
|
||||||
property.Interface(),
|
property.Interface(),
|
||||||
|
outerAxis,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -998,14 +1009,14 @@ func (productConfigProperties *ProductConfigProperties) AddProductConfigProperti
|
||||||
// product_variables and soong_config_variables to structs that can be generated
|
// product_variables and soong_config_variables to structs that can be generated
|
||||||
// as select statements.
|
// as select statements.
|
||||||
func productVariableValues(
|
func productVariableValues(
|
||||||
fieldName string, variableProps interface{}, namespace, suffix string, productConfigProperties *ProductConfigProperties) {
|
fieldName string, variableProps interface{}, namespace, suffix string, productConfigProperties *ProductConfigProperties, outerAxis bazel.ConfigurationAxis) {
|
||||||
if suffix != "" {
|
if suffix != "" {
|
||||||
suffix = "-" + suffix
|
suffix = "-" + suffix
|
||||||
}
|
}
|
||||||
|
|
||||||
// variableValues represent the product_variables or soong_config_variables struct.
|
// variableValues represent the product_variables or soong_config_variables struct.
|
||||||
variableValues := reflect.ValueOf(variableProps).Elem().FieldByName(fieldName)
|
variableValues := reflect.ValueOf(variableProps).Elem().FieldByName(fieldName)
|
||||||
productConfigProperties.AddProductConfigProperties(namespace, suffix, variableValues)
|
productConfigProperties.AddProductConfigProperties(namespace, suffix, variableValues, outerAxis)
|
||||||
}
|
}
|
||||||
|
|
||||||
func VariableMutator(mctx BottomUpMutatorContext) {
|
func VariableMutator(mctx BottomUpMutatorContext) {
|
||||||
|
|
|
@ -295,10 +295,11 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProductVariableConfigurationAxis returns an axis for the given product variable
|
// ProductVariableConfigurationAxis returns an axis for the given product variable
|
||||||
func ProductVariableConfigurationAxis(variable string) ConfigurationAxis {
|
func ProductVariableConfigurationAxis(variable string, outerAxis ConfigurationAxis) ConfigurationAxis {
|
||||||
return ConfigurationAxis{
|
return ConfigurationAxis{
|
||||||
configurationType: productVariables,
|
configurationType: productVariables,
|
||||||
subType: variable,
|
subType: variable,
|
||||||
|
outerAxisType: outerAxis.configurationType,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,6 +310,8 @@ type ConfigurationAxis struct {
|
||||||
// some configuration types (e.g. productVariables) have multiple independent axes, subType helps
|
// some configuration types (e.g. productVariables) have multiple independent axes, subType helps
|
||||||
// distinguish between them without needing to list all 17 product variables.
|
// distinguish between them without needing to list all 17 product variables.
|
||||||
subType string
|
subType string
|
||||||
|
// used to keep track of which product variables are arch variant
|
||||||
|
outerAxisType configurationType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
|
func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
|
||||||
|
|
|
@ -309,8 +309,20 @@ func (la *LabelAttribute) Collapse() error {
|
||||||
_, containsProductVariables := axisTypes[productVariables]
|
_, containsProductVariables := axisTypes[productVariables]
|
||||||
if containsProductVariables {
|
if containsProductVariables {
|
||||||
if containsOs || containsArch || containsOsArch {
|
if containsOs || containsArch || containsOsArch {
|
||||||
|
if containsArch {
|
||||||
|
allProductVariablesAreArchVariant := true
|
||||||
|
for k := range la.ConfigurableValues {
|
||||||
|
if k.configurationType == productVariables && k.outerAxisType != arch {
|
||||||
|
allProductVariablesAreArchVariant = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !allProductVariablesAreArchVariant {
|
||||||
return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
|
return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
|
if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
|
||||||
// If a bool attribute has both os and arch configuration axes, the only
|
// If a bool attribute has both os and arch configuration axes, the only
|
||||||
|
|
|
@ -247,13 +247,13 @@ func TestResolveExcludes(t *testing.T) {
|
||||||
OsArchConfigurationAxis: labelListSelectValues{
|
OsArchConfigurationAxis: labelListSelectValues{
|
||||||
"linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
|
"linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
|
||||||
},
|
},
|
||||||
ProductVariableConfigurationAxis("product_with_defaults"): labelListSelectValues{
|
ProductVariableConfigurationAxis("product_with_defaults", NoConfigAxis): labelListSelectValues{
|
||||||
"a": makeLabelList([]string{}, []string{"not_in_value"}),
|
"a": makeLabelList([]string{}, []string{"not_in_value"}),
|
||||||
"b": makeLabelList([]string{"b_val"}, []string{}),
|
"b": makeLabelList([]string{"b_val"}, []string{}),
|
||||||
"c": makeLabelList([]string{"c_val"}, []string{}),
|
"c": makeLabelList([]string{"c_val"}, []string{}),
|
||||||
ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2"}, []string{}),
|
ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2"}, []string{}),
|
||||||
},
|
},
|
||||||
ProductVariableConfigurationAxis("product_only_with_excludes"): labelListSelectValues{
|
ProductVariableConfigurationAxis("product_only_with_excludes", NoConfigAxis): labelListSelectValues{
|
||||||
"a": makeLabelList([]string{}, []string{"not_in_value"}),
|
"a": makeLabelList([]string{}, []string{"not_in_value"}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -281,7 +281,7 @@ func TestResolveExcludes(t *testing.T) {
|
||||||
"linux_x86": makeLabels("linux_x86_include"),
|
"linux_x86": makeLabels("linux_x86_include"),
|
||||||
ConditionsDefaultConfigKey: nilLabels,
|
ConditionsDefaultConfigKey: nilLabels,
|
||||||
},
|
},
|
||||||
ProductVariableConfigurationAxis("product_with_defaults"): {
|
ProductVariableConfigurationAxis("product_with_defaults", NoConfigAxis): {
|
||||||
"a": nilLabels,
|
"a": nilLabels,
|
||||||
"b": makeLabels("b_val"),
|
"b": makeLabels("b_val"),
|
||||||
"c": makeLabels("c_val"),
|
"c": makeLabels("c_val"),
|
||||||
|
@ -674,7 +674,7 @@ func TestDeduplicateAxesFromBase(t *testing.T) {
|
||||||
OsArchConfigurationAxis: stringListSelectValues{
|
OsArchConfigurationAxis: stringListSelectValues{
|
||||||
"linux_x86": {"linux_x86_include"},
|
"linux_x86": {"linux_x86_include"},
|
||||||
},
|
},
|
||||||
ProductVariableConfigurationAxis("a"): stringListSelectValues{
|
ProductVariableConfigurationAxis("a", NoConfigAxis): stringListSelectValues{
|
||||||
"a": []string{"not_in_value"},
|
"a": []string{"not_in_value"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -699,7 +699,7 @@ func TestDeduplicateAxesFromBase(t *testing.T) {
|
||||||
"linux": []string{"linux_include"},
|
"linux": []string{"linux_include"},
|
||||||
},
|
},
|
||||||
OsArchConfigurationAxis: stringListSelectValues{},
|
OsArchConfigurationAxis: stringListSelectValues{},
|
||||||
ProductVariableConfigurationAxis("a"): stringListSelectValues{
|
ProductVariableConfigurationAxis("a", NoConfigAxis): stringListSelectValues{
|
||||||
"a": []string{"not_in_value"},
|
"a": []string{"not_in_value"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
package bp2build
|
package bp2build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/etc"
|
"android/soong/etc"
|
||||||
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func runPrebuiltEtcTestCase(t *testing.T, tc Bp2buildTestCase) {
|
func runPrebuiltEtcTestCase(t *testing.T, tc Bp2buildTestCase) {
|
||||||
|
@ -128,6 +129,32 @@ prebuilt_etc {
|
||||||
"dir": `"etc/tz"`,
|
"dir": `"etc/tz"`,
|
||||||
})}})
|
})}})
|
||||||
}
|
}
|
||||||
|
func TestPrebuiltEtcProductVariables(t *testing.T) {
|
||||||
|
runPrebuiltEtcTestCase(t, Bp2buildTestCase{
|
||||||
|
Description: "prebuilt etc - product variables",
|
||||||
|
Filesystem: map[string]string{},
|
||||||
|
Blueprint: `
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "apex_tz_version",
|
||||||
|
src: "version/tz_version",
|
||||||
|
filename: "tz_version",
|
||||||
|
product_variables: {
|
||||||
|
native_coverage: {
|
||||||
|
src: "src1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
ExpectedBazelTargets: []string{
|
||||||
|
MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
|
||||||
|
"filename": `"tz_version"`,
|
||||||
|
"src": `select({
|
||||||
|
"//build/bazel/product_variables:native_coverage": "src1",
|
||||||
|
"//conditions:default": "version/tz_version",
|
||||||
|
})`,
|
||||||
|
"dir": `"etc"`,
|
||||||
|
})}})
|
||||||
|
}
|
||||||
|
|
||||||
func runPrebuiltUsrShareTestCase(t *testing.T, tc Bp2buildTestCase) {
|
func runPrebuiltUsrShareTestCase(t *testing.T, tc Bp2buildTestCase) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
@ -265,3 +292,57 @@ prebuilt_etc {
|
||||||
"dir": `"etc"`,
|
"dir": `"etc"`,
|
||||||
})}})
|
})}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrebuiltEtcProductVariableArchSrcs(t *testing.T) {
|
||||||
|
runPrebuiltEtcTestCase(t, Bp2buildTestCase{
|
||||||
|
Description: "prebuilt etc- SRcs from arch variant product variables",
|
||||||
|
Filesystem: map[string]string{},
|
||||||
|
Blueprint: `
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "foo",
|
||||||
|
filename: "fooFilename",
|
||||||
|
arch: {
|
||||||
|
arm: {
|
||||||
|
src: "armSrc",
|
||||||
|
product_variables: {
|
||||||
|
native_coverage: {
|
||||||
|
src: "nativeCoverageArmSrc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}`,
|
||||||
|
ExpectedBazelTargets: []string{
|
||||||
|
MakeBazelTarget("prebuilt_file", "foo", AttrNameToString{
|
||||||
|
"filename": `"fooFilename"`,
|
||||||
|
"dir": `"etc"`,
|
||||||
|
"src": `select({
|
||||||
|
"//build/bazel/platforms/arch:arm": "armSrc",
|
||||||
|
"//build/bazel/product_variables:native_coverage-arm": "nativeCoverageArmSrc",
|
||||||
|
"//conditions:default": None,
|
||||||
|
})`,
|
||||||
|
})}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrebuiltEtcProductVariableError(t *testing.T) {
|
||||||
|
runPrebuiltEtcTestCase(t, Bp2buildTestCase{
|
||||||
|
Description: "",
|
||||||
|
Filesystem: map[string]string{},
|
||||||
|
Blueprint: `
|
||||||
|
prebuilt_etc {
|
||||||
|
name: "foo",
|
||||||
|
filename: "fooFilename",
|
||||||
|
arch: {
|
||||||
|
arm: {
|
||||||
|
src: "armSrc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
product_variables: {
|
||||||
|
native_coverage: {
|
||||||
|
src: "nativeCoverageArmSrc",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}`,
|
||||||
|
ExpectedErr: fmt.Errorf("label attribute could not be collapsed"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
|
@ -692,6 +693,22 @@ func (module *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext
|
||||||
src.SetSelectValue(axis, config, label)
|
src.SetSelectValue(axis, config, label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for propName, productConfigProps := range android.ProductVariableProperties(ctx) {
|
||||||
|
for configProp, propVal := range productConfigProps {
|
||||||
|
if propName == "Src" {
|
||||||
|
props, ok := propVal.(*string)
|
||||||
|
if !ok {
|
||||||
|
ctx.PropertyErrorf(" Expected Property to have type string, but was %s\n", reflect.TypeOf(propVal).String())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if props != nil {
|
||||||
|
label := android.BazelLabelForModuleSrcSingle(ctx, *props)
|
||||||
|
src.SetSelectValue(configProp.ConfigurationAxis(), configProp.SelectKey(), label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var filename string
|
var filename string
|
||||||
|
|
Loading…
Reference in a new issue