bp2build: arch-configurable selects for label list attrs.
This CL adds the configurable LabelListAttribute support to bp2build.
Test: go test
Change-Id: I2ef9e385d9cf1b1845988128eca1d8cda1ecb5e8
diff --git a/android/filegroup.go b/android/filegroup.go
index abbb4d4..2f13ab8 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -30,7 +30,7 @@
// https://docs.bazel.build/versions/master/be/general.html#filegroup
type bazelFilegroupAttributes struct {
- Srcs bazel.LabelList
+ Srcs bazel.LabelListAttribute
}
type bazelFilegroup struct {
@@ -57,8 +57,10 @@
return
}
+ srcs := bazel.MakeLabelListAttribute(
+ BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs))
attrs := &bazelFilegroupAttributes{
- Srcs: BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs),
+ Srcs: srcs,
}
props := bazel.BazelTargetModuleProperties{Rule_class: "filegroup"}
diff --git a/android/paths.go b/android/paths.go
index b457372..ef7e1df 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -477,6 +477,9 @@
// already be resolved by either deps mutator or path deps mutator.
func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string) bazel.Label {
m, _ := ctx.GetDirectDep(dep)
+ if m == nil {
+ panic(fmt.Errorf("cannot get direct dep %s of %s", dep, ctx.Module().Name()))
+ }
otherLabel := bazelModuleLabel(ctx, m, tag)
label := bazelModuleLabel(ctx, ctx.Module(), "")
if samePackage(label, otherLabel) {
diff --git a/bazel/properties.go b/bazel/properties.go
index abdc107..25e110a 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -76,6 +76,92 @@
return uniqueLabelList
}
+const (
+ ARCH_X86 = "x86"
+ ARCH_X86_64 = "x86_64"
+ ARCH_ARM = "arm"
+ ARCH_ARM64 = "arm64"
+)
+
+var (
+ // This is the list of architectures with a Bazel config_setting and
+ // constraint value equivalent. is actually android.ArchTypeList, but the
+ // android package depends on the bazel package, so a cyclic dependency
+ // prevents using that here.
+ selectableArchs = []string{ARCH_X86, ARCH_X86_64, ARCH_ARM, ARCH_ARM64}
+)
+
+// 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
+ // TODO(b/181299724): this is currently missing the "common" arch, which
+ // doesn't have an equivalent platform() definition yet.
+}
+
+// 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.
+ 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
+}
+
+// MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
+func MakeLabelListAttribute(value LabelList) LabelListAttribute {
+ return LabelListAttribute{Value: UniqueBazelLabelList(value)}
+}
+
+// HasArchSpecificValues returns true if the attribute contains
+// architecture-specific label_list values.
+func (attrs *LabelListAttribute) HasArchSpecificValues() bool {
+ for _, arch := range selectableArchs {
+ if len(attrs.GetValueForArch(arch).Includes) > 0 || len(attrs.GetValueForArch(arch).Excludes) > 0 {
+ return true
+ }
+ }
+ return false
+}
+
+// GetValueForArch returns the label_list attribute value for an architecture.
+func (attrs *LabelListAttribute) GetValueForArch(arch string) LabelList {
+ switch arch {
+ case ARCH_X86:
+ return attrs.ArchValues.X86
+ case ARCH_X86_64:
+ return attrs.ArchValues.X86_64
+ case ARCH_ARM:
+ return attrs.ArchValues.Arm
+ case ARCH_ARM64:
+ return attrs.ArchValues.Arm64
+ default:
+ panic(fmt.Errorf("Unknown arch: %s", arch))
+ }
+}
+
+// SetValueForArch sets the label_list attribute value for an architecture.
+func (attrs *LabelListAttribute) SetValueForArch(arch string, value LabelList) {
+ switch arch {
+ case "x86":
+ attrs.ArchValues.X86 = value
+ case "x86_64":
+ attrs.ArchValues.X86_64 = value
+ case "arm":
+ attrs.ArchValues.Arm = value
+ case "arm64":
+ attrs.ArchValues.Arm64 = value
+ default:
+ panic(fmt.Errorf("Unknown arch: %s", arch))
+ }
+}
+
// StringListAttribute corresponds to the string_list Bazel attribute type with
// support for additional metadata, like configurations.
type StringListAttribute struct {
@@ -89,11 +175,10 @@
// 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
- Default []string
+ X86 []string
+ X86_64 []string
+ Arm []string
+ Arm64 []string
// TODO(b/181299724): this is currently missing the "common" arch, which
// doesn't have an equivalent platform() definition yet.
}
@@ -101,7 +186,7 @@
// HasArchSpecificValues returns true if the attribute contains
// architecture-specific string_list values.
func (attrs *StringListAttribute) HasArchSpecificValues() bool {
- for _, arch := range []string{"x86", "x86_64", "arm", "arm64", "default"} {
+ for _, arch := range selectableArchs {
if len(attrs.GetValueForArch(arch)) > 0 {
return true
}
@@ -112,16 +197,14 @@
// GetValueForArch returns the string_list attribute value for an architecture.
func (attrs *StringListAttribute) GetValueForArch(arch string) []string {
switch arch {
- case "x86":
+ case ARCH_X86:
return attrs.ArchValues.X86
- case "x86_64":
+ case ARCH_X86_64:
return attrs.ArchValues.X86_64
- case "arm":
+ case ARCH_ARM:
return attrs.ArchValues.Arm
- case "arm64":
+ case ARCH_ARM64:
return attrs.ArchValues.Arm64
- case "default":
- return attrs.ArchValues.Default
default:
panic(fmt.Errorf("Unknown arch: %s", arch))
}
@@ -130,16 +213,14 @@
// SetValueForArch sets the string_list attribute value for an architecture.
func (attrs *StringListAttribute) SetValueForArch(arch string, value []string) {
switch arch {
- case "x86":
+ case ARCH_X86:
attrs.ArchValues.X86 = value
- case "x86_64":
+ case ARCH_X86_64:
attrs.ArchValues.X86_64 = value
- case "arm":
+ case ARCH_ARM:
attrs.ArchValues.Arm = value
- case "arm64":
+ case ARCH_ARM64:
attrs.ArchValues.Arm64 = value
- case "default":
- attrs.ArchValues.Default = value
default:
panic(fmt.Errorf("Unknown arch: %s", arch))
}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 90bbd4d..d48d975 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -415,9 +415,34 @@
case reflect.Struct:
// Special cases where the bp2build sends additional information to the codegenerator
// by wrapping the attributes in a custom struct type.
- if labels, ok := propertyValue.Interface().(bazel.LabelList); ok {
+ if labels, ok := propertyValue.Interface().(bazel.LabelListAttribute); ok {
// TODO(b/165114590): convert glob syntax
- return prettyPrint(reflect.ValueOf(labels.Includes), indent)
+ ret, err := prettyPrint(reflect.ValueOf(labels.Value.Includes), indent)
+ if err != nil {
+ return ret, err
+ }
+
+ if !labels.HasArchSpecificValues() {
+ // Select statement not needed.
+ return ret, nil
+ }
+
+ ret += " + " + "select({\n"
+ for _, arch := range android.ArchTypeList() {
+ value := labels.GetValueForArch(arch.Name)
+ if len(value.Includes) > 0 {
+ ret += makeIndent(indent + 1)
+ list, _ := prettyPrint(reflect.ValueOf(value.Includes), indent+1)
+ ret += fmt.Sprintf("\"%s\": %s,\n", platformArchMap[arch], list)
+ }
+ }
+
+ ret += makeIndent(indent + 1)
+ ret += fmt.Sprintf("\"%s\": [],\n", "//conditions:default")
+
+ ret += makeIndent(indent)
+ ret += "})"
+ return ret, err
} else if label, ok := propertyValue.Interface().(bazel.Label); ok {
return fmt.Sprintf("%q", label.Label), nil
} else if stringList, ok := propertyValue.Interface().(bazel.StringListAttribute); ok {
@@ -443,8 +468,7 @@
}
ret += makeIndent(indent + 1)
- list, _ := prettyPrint(reflect.ValueOf(stringList.GetValueForArch("default")), indent+1)
- ret += fmt.Sprintf("\"%s\": %s,\n", "//conditions:default", list)
+ ret += fmt.Sprintf("\"%s\": [],\n", "//conditions:default")
ret += makeIndent(indent)
ret += "})"
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index b9b250a..ad88e97 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -502,8 +502,6 @@
expectedBazelTargets: []string{
`filegroup(
name = "fg_foo",
- srcs = [
- ],
)`,
},
},
@@ -1101,8 +1099,8 @@
"out",
],
srcs = [
- "srcs-from-3",
"in1",
+ "srcs-from-3",
],
)`,
description: "genrule applies properties from genrule_defaults transitively",
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index 1c058ba..b007033 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -74,8 +74,8 @@
],
srcs = [
"a/b/bar.h",
- "a/b/foo.h",
"a/b/c.c",
+ "a/b/foo.h",
],
)`,
},
@@ -278,9 +278,13 @@
moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
blueprint: `cc_object {
name: "foo",
+ srcs: ["a.cpp"],
arch: {
x86: {
- cflags: ["-fPIC"],
+ cflags: ["-fPIC"], // string list
+ },
+ arm: {
+ srcs: ["arch/arm/file.S"], // label list
},
},
bazel_module: { bp2build_available: true },
@@ -295,12 +299,19 @@
"@bazel_tools//platforms:x86_32": [
"-fPIC",
],
- "//conditions:default": [
- ],
+ "//conditions:default": [],
}),
local_include_dirs = [
".",
],
+ srcs = [
+ "a.cpp",
+ ] + select({
+ "@bazel_tools//platforms:arm": [
+ "arch/arm/file.S",
+ ],
+ "//conditions:default": [],
+ }),
)`,
},
},
@@ -311,17 +322,22 @@
moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
blueprint: `cc_object {
name: "foo",
+ srcs: ["base.cpp"],
arch: {
x86: {
+ srcs: ["x86.cpp"],
cflags: ["-fPIC"],
},
x86_64: {
+ srcs: ["x86_64.cpp"],
cflags: ["-fPIC"],
},
arm: {
+ srcs: ["arm.cpp"],
cflags: ["-Wall"],
},
arm64: {
+ srcs: ["arm64.cpp"],
cflags: ["-Wall"],
},
},
@@ -346,12 +362,28 @@
"@bazel_tools//platforms:x86_64": [
"-fPIC",
],
- "//conditions:default": [
- ],
+ "//conditions:default": [],
}),
local_include_dirs = [
".",
],
+ srcs = [
+ "base.cpp",
+ ] + select({
+ "@bazel_tools//platforms:arm": [
+ "arm.cpp",
+ ],
+ "@bazel_tools//platforms:aarch64": [
+ "arm64.cpp",
+ ],
+ "@bazel_tools//platforms:x86_32": [
+ "x86.cpp",
+ ],
+ "@bazel_tools//platforms:x86_64": [
+ "x86_64.cpp",
+ ],
+ "//conditions:default": [],
+ }),
)`,
},
},
diff --git a/cc/library.go b/cc/library.go
index 9bec974..28e4f61 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -2029,7 +2029,7 @@
return outputFile
}
-func Bp2BuildParseHeaderLibs(ctx android.TopDownMutatorContext, module *Module) bazel.LabelList {
+func Bp2BuildParseHeaderLibs(ctx android.TopDownMutatorContext, module *Module) bazel.LabelListAttribute {
var headerLibs []string
for _, linkerProps := range module.linker.linkerProps() {
if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
@@ -2038,12 +2038,11 @@
break
}
}
-
- headerLibsLabels := android.BazelLabelForModuleDeps(ctx, headerLibs)
+ headerLibsLabels := bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
return headerLibsLabels
}
-func Bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) (bazel.LabelList, bazel.LabelList) {
+func Bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) (bazel.LabelListAttribute, bazel.LabelListAttribute) {
libraryDecorator := module.linker.(*libraryDecorator)
includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
@@ -2059,17 +2058,16 @@
}
headersLabels := android.BazelLabelForModuleSrc(ctx, includeDirGlobs)
-
- return includeDirsLabels, headersLabels
+ return bazel.MakeLabelListAttribute(includeDirsLabels), bazel.MakeLabelListAttribute(headersLabels)
}
type bazelCcLibraryStaticAttributes struct {
Copts []string
- Srcs bazel.LabelList
- Deps bazel.LabelList
+ Srcs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
Linkstatic bool
- Includes bazel.LabelList
- Hdrs bazel.LabelList
+ Includes bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
}
type bazelCcLibraryStatic struct {
@@ -2110,7 +2108,7 @@
break
}
}
- srcsLabels := android.BazelLabelForModuleSrc(ctx, srcs)
+ srcsLabels := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, srcs))
var staticLibs []string
var wholeStaticLibs []string
@@ -2135,18 +2133,18 @@
includesLabels := android.BazelLabelForModuleSrc(ctx, allIncludes)
exportedIncludesLabels, exportedIncludesHeadersLabels := Bp2BuildParseExportedIncludes(ctx, module)
- includesLabels.Append(exportedIncludesLabels)
+ includesLabels.Append(exportedIncludesLabels.Value)
headerLibsLabels := Bp2BuildParseHeaderLibs(ctx, module)
- depsLabels.Append(headerLibsLabels)
+ depsLabels.Append(headerLibsLabels.Value)
attrs := &bazelCcLibraryStaticAttributes{
Copts: copts,
- Srcs: bazel.UniqueBazelLabelList(srcsLabels),
- Deps: bazel.UniqueBazelLabelList(depsLabels),
+ Srcs: srcsLabels,
+ Deps: bazel.MakeLabelListAttribute(depsLabels),
Linkstatic: true,
- Includes: bazel.UniqueBazelLabelList(includesLabels),
- Hdrs: bazel.UniqueBazelLabelList(exportedIncludesHeadersLabels),
+ Includes: bazel.MakeLabelListAttribute(includesLabels),
+ Hdrs: exportedIncludesHeadersLabels,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 719d538..8286848 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -62,9 +62,9 @@
}
type bazelCcLibraryHeadersAttributes struct {
- Hdrs bazel.LabelList
- Includes bazel.LabelList
- Deps bazel.LabelList
+ Hdrs bazel.LabelListAttribute
+ Includes bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
}
type bazelCcLibraryHeaders struct {
diff --git a/cc/object.go b/cc/object.go
index 664be8d..abc3e83 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -103,8 +103,8 @@
// For bp2build conversion.
type bazelObjectAttributes struct {
- Srcs bazel.LabelList
- Deps bazel.LabelList
+ Srcs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
Copts bazel.StringListAttribute
Local_include_dirs []string
}
@@ -147,14 +147,16 @@
// Set arch-specific configurable attributes
var copts bazel.StringListAttribute
- var srcs []string
- var excludeSrcs []string
+ var srcs bazel.LabelListAttribute
var localIncludeDirs []string
for _, props := range m.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
copts.Value = baseCompilerProps.Cflags
- srcs = baseCompilerProps.Srcs
- excludeSrcs = baseCompilerProps.Exclude_srcs
+ srcs = bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleSrcExcludes(
+ ctx,
+ baseCompilerProps.Srcs,
+ baseCompilerProps.Exclude_srcs))
localIncludeDirs = baseCompilerProps.Local_include_dirs
break
}
@@ -164,22 +166,23 @@
localIncludeDirs = append(localIncludeDirs, ".")
}
- var deps bazel.LabelList
+ var deps bazel.LabelListAttribute
for _, props := range m.linker.linkerProps() {
if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
- deps = android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs)
+ deps = bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
}
}
for arch, p := range m.GetArchProperties(&BaseCompilerProperties{}) {
if cProps, ok := p.(*BaseCompilerProperties); ok {
+ srcs.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcExcludes(ctx, cProps.Srcs, cProps.Exclude_srcs))
copts.SetValueForArch(arch.Name, cProps.Cflags)
}
}
- copts.SetValueForArch("default", []string{})
attrs := &bazelObjectAttributes{
- Srcs: android.BazelLabelForModuleSrcExcludes(ctx, srcs, excludeSrcs),
+ Srcs: srcs,
Deps: deps,
Copts: copts,
Local_include_dirs: localIncludeDirs,
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 9019a83..5d438ea 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -798,9 +798,9 @@
}
type bazelGenruleAttributes struct {
- Srcs bazel.LabelList
+ Srcs bazel.LabelListAttribute
Outs []string
- Tools bazel.LabelList
+ Tools bazel.LabelListAttribute
Cmd string
}
@@ -828,15 +828,16 @@
}
// Bazel only has the "tools" attribute.
- tools := android.BazelLabelForModuleDeps(ctx, m.properties.Tools)
- tool_files := android.BazelLabelForModuleSrc(ctx, m.properties.Tool_files)
- tools.Append(tool_files)
+ tools_prop := android.BazelLabelForModuleDeps(ctx, m.properties.Tools)
+ tool_files_prop := android.BazelLabelForModuleSrc(ctx, m.properties.Tool_files)
+ tools_prop.Append(tool_files_prop)
- srcs := android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)
+ tools := bazel.MakeLabelListAttribute(tools_prop)
+ srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs))
var allReplacements bazel.LabelList
- allReplacements.Append(tools)
- allReplacements.Append(srcs)
+ allReplacements.Append(tools.Value)
+ allReplacements.Append(srcs.Value)
// Replace in and out variables with $< and $@
var cmd string
@@ -844,9 +845,9 @@
cmd = strings.Replace(*m.properties.Cmd, "$(in)", "$(SRCS)", -1)
cmd = strings.Replace(cmd, "$(out)", "$(OUTS)", -1)
cmd = strings.Replace(cmd, "$(genDir)", "$(GENDIR)", -1)
- if len(tools.Includes) > 0 {
- cmd = strings.Replace(cmd, "$(location)", fmt.Sprintf("$(location %s)", tools.Includes[0].Label), -1)
- cmd = strings.Replace(cmd, "$(locations)", fmt.Sprintf("$(locations %s)", tools.Includes[0].Label), -1)
+ if len(tools.Value.Includes) > 0 {
+ cmd = strings.Replace(cmd, "$(location)", fmt.Sprintf("$(location %s)", tools.Value.Includes[0].Label), -1)
+ cmd = strings.Replace(cmd, "$(locations)", fmt.Sprintf("$(locations %s)", tools.Value.Includes[0].Label), -1)
}
for _, l := range allReplacements.Includes {
bpLoc := fmt.Sprintf("$(location %s)", l.Bp_text)
diff --git a/python/binary.go b/python/binary.go
index 5b0f080..e955492 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -36,8 +36,8 @@
type bazelPythonBinaryAttributes struct {
Main string
- Srcs bazel.LabelList
- Data bazel.LabelList
+ Srcs bazel.LabelListAttribute
+ Data bazel.LabelListAttribute
Python_version string
}
@@ -97,10 +97,13 @@
// do nothing, since python_version defaults to PY3.
}
+ srcs := android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
+ data := android.BazelLabelForModuleSrc(ctx, m.properties.Data)
+
attrs := &bazelPythonBinaryAttributes{
Main: main,
- Srcs: android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs),
- Data: android.BazelLabelForModuleSrc(ctx, m.properties.Data),
+ Srcs: bazel.MakeLabelListAttribute(srcs),
+ Data: bazel.MakeLabelListAttribute(data),
Python_version: python_version,
}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 1ae557a..6623381 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -485,7 +485,7 @@
}
type bazelShBinaryAttributes struct {
- Srcs bazel.LabelList
+ Srcs bazel.LabelListAttribute
// Bazel also supports the attributes below, but (so far) these are not required for Bionic
// deps
// data
@@ -525,7 +525,8 @@
return
}
- srcs := android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src})
+ srcs := bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src}))
attrs := &bazelShBinaryAttributes{
Srcs: srcs,