Support arch variations for export_system_include_dirs in cc_library_headers bp2build converter.
Test: Added unit test
Test: bp2build-sync.py write; bazel build //bionic/... works for more cc_library_static targets (in a parent CL)
Change-Id: Ib487216a4bcbc52958ff948722dae347b0d8b606
diff --git a/bazel/properties.go b/bazel/properties.go
index 2440ca1..148386f 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -79,6 +79,63 @@
return uniqueLabelList
}
+// Subtract needle from haystack
+func SubtractStrings(haystack []string, needle []string) []string {
+ // This is really a set
+ remainder := make(map[string]bool)
+
+ for _, s := range haystack {
+ remainder[s] = true
+ }
+ for _, s := range needle {
+ delete(remainder, s)
+ }
+
+ var strings []string
+ for s, _ := range remainder {
+ strings = append(strings, s)
+ }
+
+ sort.SliceStable(strings, func(i, j int) bool {
+ return strings[i] < strings[j]
+ })
+
+ return strings
+}
+
+// Subtract needle from haystack
+func SubtractBazelLabels(haystack []Label, needle []Label) []Label {
+ // This is really a set
+ remainder := make(map[Label]bool)
+
+ for _, label := range haystack {
+ remainder[label] = true
+ }
+ for _, label := range needle {
+ delete(remainder, label)
+ }
+
+ var labels []Label
+ for label, _ := range remainder {
+ labels = append(labels, label)
+ }
+
+ sort.SliceStable(labels, func(i, j int) bool {
+ return labels[i].Label < labels[j].Label
+ })
+
+ return labels
+}
+
+// Subtract needle from haystack
+func SubtractBazelLabelList(haystack LabelList, needle LabelList) LabelList {
+ var result LabelList
+ result.Includes = SubtractBazelLabels(haystack.Includes, needle.Includes)
+ // NOTE: Excludes are intentionally not subtracted
+ result.Excludes = haystack.Excludes
+ return result
+}
+
const (
// ArchType names in arch.go
ARCH_ARM = "arm"
@@ -257,6 +314,12 @@
OsValues stringListOsValues
}
+// MakeStringListAttribute initializes a StringListAttribute with the non-arch specific value.
+func MakeStringListAttribute(value []string) StringListAttribute {
+ // NOTE: These strings are not necessarily unique or sorted.
+ return StringListAttribute{Value: value}
+}
+
// Arch-specific string_list typed Bazel attribute values. This should correspond
// to the types of architectures supported for compilation in arch.go.
type stringListArchValues struct {
diff --git a/bazel/properties_test.go b/bazel/properties_test.go
index 0fcb904..56840ef 100644
--- a/bazel/properties_test.go
+++ b/bazel/properties_test.go
@@ -46,6 +46,82 @@
}
}
+func TestSubtractStrings(t *testing.T) {
+ testCases := []struct {
+ haystack []string
+ needle []string
+ expectedResult []string
+ }{
+ {
+ haystack: []string{
+ "a",
+ "b",
+ "c",
+ },
+ needle: []string{
+ "a",
+ },
+ expectedResult: []string{
+ "b", "c",
+ },
+ },
+ }
+ for _, tc := range testCases {
+ actualResult := SubtractStrings(tc.haystack, tc.needle)
+ if !reflect.DeepEqual(tc.expectedResult, actualResult) {
+ t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
+ }
+ }
+}
+
+func TestSubtractBazelLabelList(t *testing.T) {
+ testCases := []struct {
+ haystack LabelList
+ needle LabelList
+ expectedResult LabelList
+ }{
+ {
+ haystack: LabelList{
+ Includes: []Label{
+ {Label: "a"},
+ {Label: "b"},
+ {Label: "c"},
+ },
+ Excludes: []Label{
+ {Label: "x"},
+ {Label: "y"},
+ {Label: "z"},
+ },
+ },
+ needle: LabelList{
+ Includes: []Label{
+ {Label: "a"},
+ },
+ Excludes: []Label{
+ {Label: "z"},
+ },
+ },
+ // NOTE: Excludes are intentionally not subtracted
+ expectedResult: LabelList{
+ Includes: []Label{
+ {Label: "b"},
+ {Label: "c"},
+ },
+ Excludes: []Label{
+ {Label: "x"},
+ {Label: "y"},
+ {Label: "z"},
+ },
+ },
+ },
+ }
+ for _, tc := range testCases {
+ actualResult := SubtractBazelLabelList(tc.haystack, tc.needle)
+ if !reflect.DeepEqual(tc.expectedResult, actualResult) {
+ t.Fatalf("Expected %v, got %v", tc.expectedResult, actualResult)
+ }
+ }
+}
func TestUniqueBazelLabelList(t *testing.T) {
testCases := []struct {
originalLabelList LabelList
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index d828168..9d91ffa 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -97,14 +97,17 @@
moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
filesystem: map[string]string{
- "lib-1/lib1a.h": "",
- "lib-1/lib1b.h": "",
- "lib-2/lib2a.h": "",
- "lib-2/lib2b.h": "",
- "dir-1/dir1a.h": "",
- "dir-1/dir1b.h": "",
- "dir-2/dir2a.h": "",
- "dir-2/dir2b.h": "",
+ "lib-1/lib1a.h": "",
+ "lib-1/lib1b.h": "",
+ "lib-2/lib2a.h": "",
+ "lib-2/lib2b.h": "",
+ "dir-1/dir1a.h": "",
+ "dir-1/dir1b.h": "",
+ "dir-2/dir2a.h": "",
+ "dir-2/dir2b.h": "",
+ "arch_arm64_exported_include_dir/a.h": "",
+ "arch_x86_exported_include_dir/b.h": "",
+ "arch_x86_64_exported_include_dir/c.h": "",
},
bp: soongCcLibraryPreamble + `
cc_library_headers {
@@ -122,6 +125,19 @@
export_include_dirs: ["dir-1", "dir-2"],
header_libs: ["lib-1", "lib-2"],
+ arch: {
+ arm64: {
+ // We expect dir-1 headers to be dropped, because dir-1 is already in export_include_dirs
+ export_include_dirs: ["arch_arm64_exported_include_dir", "dir-1"],
+ },
+ x86: {
+ export_include_dirs: ["arch_x86_exported_include_dir"],
+ },
+ x86_64: {
+ export_include_dirs: ["arch_x86_64_exported_include_dir"],
+ },
+ },
+
// TODO: Also support export_header_lib_headers
}`,
expectedBazelTargets: []string{`cc_library_headers(
@@ -135,11 +151,33 @@
"dir-1/dir1b.h",
"dir-2/dir2a.h",
"dir-2/dir2b.h",
- ],
+ ] + select({
+ "//build/bazel/platforms/arch:arm64": [
+ "arch_arm64_exported_include_dir/a.h",
+ ],
+ "//build/bazel/platforms/arch:x86": [
+ "arch_x86_exported_include_dir/b.h",
+ ],
+ "//build/bazel/platforms/arch:x86_64": [
+ "arch_x86_64_exported_include_dir/c.h",
+ ],
+ "//conditions:default": [],
+ }),
includes = [
"dir-1",
"dir-2",
- ],
+ ] + 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": [],
+ }),
)`, `cc_library_headers(
name = "lib-1",
hdrs = [
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 497d227..cffeb24 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
"android/soong/bazel"
+ "strings"
)
// bp2build functions and helpers for converting cc_* modules to Bazel.
@@ -109,23 +110,78 @@
return ret
}
+func bp2BuildListHeadersInDir(ctx android.TopDownMutatorContext, includeDir string) bazel.LabelList {
+ var globInfix string
+
+ if includeDir == "." {
+ globInfix = ""
+ } else {
+ globInfix = "/**"
+ }
+
+ var includeDirGlobs []string
+ includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.h")
+ includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.inc")
+ includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.hpp")
+
+ return android.BazelLabelForModuleSrc(ctx, includeDirGlobs)
+}
+
+// Bazel wants include paths to be relative to the module
+func bp2BuildMakePathsRelativeToModule(ctx android.TopDownMutatorContext, paths []string) []string {
+ var relativePaths []string
+ for _, path := range paths {
+ relativePath := strings.TrimPrefix(path, ctx.ModuleDir()+"/")
+ relativePaths = append(relativePaths, relativePath)
+ }
+ return relativePaths
+}
+
// bp2BuildParseExportedIncludes creates a label list attribute contains the
// exported included directories of a module.
-func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) (bazel.LabelListAttribute, bazel.LabelListAttribute) {
+func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) (bazel.StringListAttribute, bazel.LabelListAttribute) {
libraryDecorator := module.linker.(*libraryDecorator)
includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
+ includeDirs = bp2BuildMakePathsRelativeToModule(ctx, includeDirs)
+ includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
- includeDirsLabels := android.BazelLabelForModuleSrc(ctx, includeDirs)
-
- var includeDirGlobs []string
+ var headersAttribute bazel.LabelListAttribute
+ var headers bazel.LabelList
for _, includeDir := range includeDirs {
- includeDirGlobs = append(includeDirGlobs, includeDir+"/**/*.h")
- includeDirGlobs = append(includeDirGlobs, includeDir+"/**/*.inc")
- includeDirGlobs = append(includeDirGlobs, includeDir+"/**/*.hpp")
+ headers.Append(bp2BuildListHeadersInDir(ctx, includeDir))
+ }
+ headers = bazel.UniqueBazelLabelList(headers)
+ headersAttribute.Value = headers
+
+ for arch, props := range module.GetArchProperties(&FlagExporterProperties{}) {
+ if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
+ archIncludeDirs := flagExporterProperties.Export_system_include_dirs
+ archIncludeDirs = append(archIncludeDirs, flagExporterProperties.Export_include_dirs...)
+ archIncludeDirs = bp2BuildMakePathsRelativeToModule(ctx, archIncludeDirs)
+
+ // To avoid duplicate includes when base includes + arch includes are combined
+ archIncludeDirs = bazel.SubtractStrings(archIncludeDirs, includeDirs)
+
+ if len(archIncludeDirs) > 0 {
+ includeDirsAttribute.SetValueForArch(arch.Name, archIncludeDirs)
+ }
+
+ var archHeaders bazel.LabelList
+ for _, archIncludeDir := range archIncludeDirs {
+ archHeaders.Append(bp2BuildListHeadersInDir(ctx, archIncludeDir))
+ }
+ archHeaders = bazel.UniqueBazelLabelList(archHeaders)
+
+ // To avoid duplicate headers when base headers + arch headers are combined
+ archHeaders = bazel.SubtractBazelLabelList(archHeaders, headers)
+
+ if len(archHeaders.Includes) > 0 || len(archHeaders.Excludes) > 0 {
+ headersAttribute.SetValueForArch(arch.Name, archHeaders)
+ }
+ }
}
- headersLabels := android.BazelLabelForModuleSrc(ctx, includeDirGlobs)
- return bazel.MakeLabelListAttribute(includeDirsLabels), bazel.MakeLabelListAttribute(headersLabels)
+ return includeDirsAttribute, headersAttribute
}
diff --git a/cc/library.go b/cc/library.go
index 50fff7f..97c7ba1 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -2051,7 +2051,7 @@
Srcs bazel.LabelListAttribute
Deps bazel.LabelListAttribute
Linkstatic bool
- Includes bazel.LabelListAttribute
+ Includes bazel.StringListAttribute
Hdrs bazel.LabelListAttribute
}
@@ -2088,8 +2088,8 @@
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
copts = baseCompilerProps.Cflags
srcs = baseCompilerProps.Srcs
- includeDirs = baseCompilerProps.Include_dirs
- localIncludeDirs = baseCompilerProps.Local_include_dirs
+ includeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
+ localIncludeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Local_include_dirs)
break
}
}
@@ -2111,14 +2111,13 @@
depsLabels := android.BazelLabelForModuleDeps(ctx, allDeps)
+ exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, module)
+
// FIXME: Unify absolute vs relative paths
// FIXME: Use -I copts instead of setting includes= ?
- allIncludes := includeDirs
- allIncludes = append(allIncludes, localIncludeDirs...)
- includesLabels := android.BazelLabelForModuleSrc(ctx, allIncludes)
-
- exportedIncludesLabels, exportedIncludesHeadersLabels := bp2BuildParseExportedIncludes(ctx, module)
- includesLabels.Append(exportedIncludesLabels.Value)
+ allIncludes := exportedIncludes
+ allIncludes.Value = append(allIncludes.Value, includeDirs...)
+ allIncludes.Value = append(allIncludes.Value, localIncludeDirs...)
headerLibsLabels := bp2BuildParseHeaderLibs(ctx, module)
depsLabels.Append(headerLibsLabels.Value)
@@ -2128,8 +2127,8 @@
Srcs: srcsLabels,
Deps: bazel.MakeLabelListAttribute(depsLabels),
Linkstatic: true,
- Includes: bazel.MakeLabelListAttribute(includesLabels),
- Hdrs: exportedIncludesHeadersLabels,
+ Includes: allIncludes,
+ Hdrs: exportedIncludesHeaders,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 82af16a..d35748b 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -64,7 +64,7 @@
type bazelCcLibraryHeadersAttributes struct {
Copts bazel.StringListAttribute
Hdrs bazel.LabelListAttribute
- Includes bazel.LabelListAttribute
+ Includes bazel.StringListAttribute
Deps bazel.LabelListAttribute
}
@@ -95,15 +95,15 @@
return
}
- exportedIncludesLabels, exportedIncludesHeadersLabels := bp2BuildParseExportedIncludes(ctx, module)
+ exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, module)
- headerLibsLabels := bp2BuildParseHeaderLibs(ctx, module)
+ headerLibs := bp2BuildParseHeaderLibs(ctx, module)
attrs := &bazelCcLibraryHeadersAttributes{
Copts: bp2BuildParseCflags(ctx, module),
- Includes: exportedIncludesLabels,
- Hdrs: exportedIncludesHeadersLabels,
- Deps: headerLibsLabels,
+ Includes: exportedIncludes,
+ Hdrs: exportedIncludesHeaders,
+ Deps: headerLibs,
}
props := bazel.BazelTargetModuleProperties{