Add support for variant_prepend properties in bp2build for cc library

Some properties in soong are marked "variant_prepend", which means
in bp2build output, variant properties(select ...) should come before
general properties.
Prepend property is added in StringListAttribute
stuct so that bp2build can handlle variant_prepend properly, if
Prepend is properly set in different module logics.
This change also coordinates cc library with Prepend.
Coordination with other module types will be in separate CLs.

Bug: 261644490
Test: TestCcLibraryHeadersSimple,
TestCcLibraryHeadersArchAndTargetExportSystemIncludes and TH

Change-Id: I3b61c491c54bbe91ba9aa2af9b4c84193c91ae7f
This commit is contained in:
Zi Wang
2022-12-09 16:08:54 -08:00
parent c0f432edfd
commit 1cb11800f7
4 changed files with 45 additions and 22 deletions

View File

@@ -1207,6 +1207,11 @@ type StringListAttribute struct {
// The configured attribute label list Values. Optional
// a map of independent configurability axes
ConfigurableValues configurableStringLists
// If a property has struct tag "variant_prepend", this value should
// be set to True, so that when bp2build generates BUILD.bazel, variant
// properties(select ...) come before general properties.
Prepend bool
}
// IsEmpty returns true if the attribute has no values under any configuration.
@@ -1273,6 +1278,9 @@ func (sla StringListAttribute) HasConfigurableValues() bool {
// Append appends all values, including os and arch specific ones, from another
// StringListAttribute to this StringListAttribute
func (sla *StringListAttribute) Append(other StringListAttribute) *StringListAttribute {
if sla.Prepend != other.Prepend {
panic(fmt.Errorf("StringListAttribute could not be appended because it has different prepend value"))
}
sla.Value = append(sla.Value, other.Value...)
if sla.ConfigurableValues == nil {
sla.ConfigurableValues = make(configurableStringLists)

View File

@@ -107,15 +107,15 @@ cc_library_headers {
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"export_includes": `[
"dir-1",
"dir-2",
] + select({
"export_includes": `select({
"//build/bazel/platforms/arch:arm64": ["arch_arm64_exported_include_dir"],
"//build/bazel/platforms/arch:x86": ["arch_x86_exported_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["arch_x86_64_exported_include_dir"],
"//conditions:default": [],
})`,
}) + [
"dir-1",
"dir-2",
]`,
"sdk_version": `"current"`,
"min_sdk_version": `"29"`,
}),
@@ -340,16 +340,16 @@ func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) {
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"export_system_includes": `["shared_include_dir"] + select({
"//build/bazel/platforms/arch:arm": ["arm_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
"//conditions:default": [],
}) + select({
"export_system_includes": `select({
"//build/bazel/platforms/os:android": ["android_include_dir"],
"//build/bazel/platforms/os:darwin": ["darwin_include_dir"],
"//build/bazel/platforms/os:linux": ["linux_include_dir"],
"//conditions:default": [],
})`,
}) + select({
"//build/bazel/platforms/arch:arm": ["arm_include_dir"],
"//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
"//conditions:default": [],
}) + ["shared_include_dir"]`,
}),
},
})

View File

@@ -37,10 +37,11 @@ func getStringValue(str bazel.StringAttribute) (reflect.Value, []selects) {
return value, []selects{ret}
}
func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects) {
func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects, bool) {
value := reflect.ValueOf(list.Value)
prepend := reflect.ValueOf(list.Prepend).Bool()
if !list.HasConfigurableValues() {
return value, []selects{}
return value, []selects{}, prepend
}
var ret []selects
@@ -56,7 +57,7 @@ func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selec
}
}
return value, ret
return value, ret, prepend
}
func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
@@ -156,6 +157,7 @@ var (
func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
var value reflect.Value
var configurableAttrs []selects
var prepend bool
var defaultSelectValue *string
var emitZeroValues bool
// If true, print the default attribute value, even if the attribute is zero.
@@ -168,7 +170,7 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
value, configurableAttrs = getStringValue(list)
defaultSelectValue = &bazelNone
case bazel.StringListAttribute:
value, configurableAttrs = getStringListValues(list)
value, configurableAttrs, prepend = getStringListValues(list)
defaultSelectValue = &emptyBazelList
case bazel.LabelListAttribute:
value, configurableAttrs = getLabelListValues(list)
@@ -203,22 +205,28 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
ret += s
}
// Convenience function to append selects components to an attribute value.
appendSelects := func(selectsData selects, defaultValue *string, s string) (string, error) {
// Convenience function to prepend/append selects components to an attribute value.
concatenateSelects := func(selectsData selects, defaultValue *string, s string, prepend bool) (string, error) {
selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent, emitZeroValues)
if err != nil {
return "", err
}
if s != "" && selectMap != "" {
s += " + "
var left, right string
if prepend {
left, right = selectMap, s
} else {
left, right = s, selectMap
}
s += selectMap
if left != "" && right != "" {
left += " + "
}
left += right
return s, nil
return left, nil
}
for _, configurableAttr := range configurableAttrs {
ret, err = appendSelects(configurableAttr, defaultSelectValue, ret)
ret, err = concatenateSelects(configurableAttr, defaultSelectValue, ret, prepend)
if err != nil {
return "", err
}

View File

@@ -1257,6 +1257,13 @@ func bp2BuildParseExportedIncludes(ctx android.BazelConversionPathContext, modul
} else {
exported = BazelIncludes{}
}
// cc library Export_include_dirs and Export_system_include_dirs are marked
// "variant_prepend" in struct tag, set their prepend property to true to make
// sure bp2build generates correct result.
exported.Includes.Prepend = true
exported.SystemIncludes.Prepend = true
bp2BuildPropParseHelper(ctx, module, &FlagExporterProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
if len(flagExporterProperties.Export_include_dirs) > 0 {