Merge "Support arch variations for export_system_include_dirs in cc_library_headers bp2build converter." am: 64a90286c4 am: 197a03958b

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1665920

Change-Id: I26de22672318d9e2af2f7ac83595744aa7ebd135
This commit is contained in:
Rupert Shuttleworth 2021-04-08 02:15:52 +00:00 committed by Automerger Merge Worker
commit 4f95eb9f95
6 changed files with 268 additions and 36 deletions

View file

@ -79,6 +79,63 @@ func UniqueBazelLabelList(originalLabelList LabelList) LabelList {
return uniqueLabelList 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 ( const (
// ArchType names in arch.go // ArchType names in arch.go
ARCH_ARM = "arm" ARCH_ARM = "arm"
@ -257,6 +314,12 @@ type StringListAttribute struct {
OsValues stringListOsValues 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 // Arch-specific string_list typed Bazel attribute values. This should correspond
// to the types of architectures supported for compilation in arch.go. // to the types of architectures supported for compilation in arch.go.
type stringListArchValues struct { type stringListArchValues struct {

View file

@ -46,6 +46,82 @@ func TestUniqueBazelLabels(t *testing.T) {
} }
} }
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) { func TestUniqueBazelLabelList(t *testing.T) {
testCases := []struct { testCases := []struct {
originalLabelList LabelList originalLabelList LabelList

View file

@ -94,6 +94,9 @@ func TestCcLibraryHeadersBp2Build(t *testing.T) {
"dir-1/dir1b.h": "", "dir-1/dir1b.h": "",
"dir-2/dir2a.h": "", "dir-2/dir2a.h": "",
"dir-2/dir2b.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 + ` bp: soongCcLibraryPreamble + `
cc_library_headers { cc_library_headers {
@ -111,6 +114,19 @@ cc_library_headers {
export_include_dirs: ["dir-1", "dir-2"], export_include_dirs: ["dir-1", "dir-2"],
header_libs: ["lib-1", "lib-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 // TODO: Also support export_header_lib_headers
}`, }`,
expectedBazelTargets: []string{`cc_library_headers( expectedBazelTargets: []string{`cc_library_headers(
@ -124,11 +140,33 @@ cc_library_headers {
"dir-1/dir1b.h", "dir-1/dir1b.h",
"dir-2/dir2a.h", "dir-2/dir2a.h",
"dir-2/dir2b.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 = [ includes = [
"dir-1", "dir-1",
"dir-2", "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( )`, `cc_library_headers(
name = "lib-1", name = "lib-1",
hdrs = [ hdrs = [

View file

@ -16,6 +16,7 @@ package cc
import ( import (
"android/soong/android" "android/soong/android"
"android/soong/bazel" "android/soong/bazel"
"strings"
) )
// bp2build functions and helpers for converting cc_* modules to Bazel. // bp2build functions and helpers for converting cc_* modules to Bazel.
@ -109,23 +110,78 @@ func bp2BuildParseHeaderLibs(ctx android.TopDownMutatorContext, module *Module)
return ret 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 // bp2BuildParseExportedIncludes creates a label list attribute contains the
// exported included directories of a module. // 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) libraryDecorator := module.linker.(*libraryDecorator)
includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_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 headersAttribute bazel.LabelListAttribute
var headers bazel.LabelList
var includeDirGlobs []string
for _, includeDir := range includeDirs { for _, includeDir := range includeDirs {
includeDirGlobs = append(includeDirGlobs, includeDir+"/**/*.h") headers.Append(bp2BuildListHeadersInDir(ctx, includeDir))
includeDirGlobs = append(includeDirGlobs, includeDir+"/**/*.inc") }
includeDirGlobs = append(includeDirGlobs, includeDir+"/**/*.hpp") 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)
} }
headersLabels := android.BazelLabelForModuleSrc(ctx, includeDirGlobs) var archHeaders bazel.LabelList
return bazel.MakeLabelListAttribute(includeDirsLabels), bazel.MakeLabelListAttribute(headersLabels) 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)
}
}
}
return includeDirsAttribute, headersAttribute
} }

View file

@ -2062,7 +2062,7 @@ type bazelCcLibraryStaticAttributes struct {
Srcs bazel.LabelListAttribute Srcs bazel.LabelListAttribute
Deps bazel.LabelListAttribute Deps bazel.LabelListAttribute
Linkstatic bool Linkstatic bool
Includes bazel.LabelListAttribute Includes bazel.StringListAttribute
Hdrs bazel.LabelListAttribute Hdrs bazel.LabelListAttribute
} }
@ -2099,8 +2099,8 @@ func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
copts = baseCompilerProps.Cflags copts = baseCompilerProps.Cflags
srcs = baseCompilerProps.Srcs srcs = baseCompilerProps.Srcs
includeDirs = baseCompilerProps.Include_dirs includeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
localIncludeDirs = baseCompilerProps.Local_include_dirs localIncludeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Local_include_dirs)
break break
} }
} }
@ -2122,14 +2122,13 @@ func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) {
depsLabels := android.BazelLabelForModuleDeps(ctx, allDeps) depsLabels := android.BazelLabelForModuleDeps(ctx, allDeps)
exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, module)
// FIXME: Unify absolute vs relative paths // FIXME: Unify absolute vs relative paths
// FIXME: Use -I copts instead of setting includes= ? // FIXME: Use -I copts instead of setting includes= ?
allIncludes := includeDirs allIncludes := exportedIncludes
allIncludes = append(allIncludes, localIncludeDirs...) allIncludes.Value = append(allIncludes.Value, includeDirs...)
includesLabels := android.BazelLabelForModuleSrc(ctx, allIncludes) allIncludes.Value = append(allIncludes.Value, localIncludeDirs...)
exportedIncludesLabels, exportedIncludesHeadersLabels := bp2BuildParseExportedIncludes(ctx, module)
includesLabels.Append(exportedIncludesLabels.Value)
headerLibsLabels := bp2BuildParseHeaderLibs(ctx, module) headerLibsLabels := bp2BuildParseHeaderLibs(ctx, module)
depsLabels.Append(headerLibsLabels.Value) depsLabels.Append(headerLibsLabels.Value)
@ -2139,8 +2138,8 @@ func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) {
Srcs: srcsLabels, Srcs: srcsLabels,
Deps: bazel.MakeLabelListAttribute(depsLabels), Deps: bazel.MakeLabelListAttribute(depsLabels),
Linkstatic: true, Linkstatic: true,
Includes: bazel.MakeLabelListAttribute(includesLabels), Includes: allIncludes,
Hdrs: exportedIncludesHeadersLabels, Hdrs: exportedIncludesHeaders,
} }
props := bazel.BazelTargetModuleProperties{ props := bazel.BazelTargetModuleProperties{

View file

@ -64,7 +64,7 @@ func prebuiltLibraryHeaderFactory() android.Module {
type bazelCcLibraryHeadersAttributes struct { type bazelCcLibraryHeadersAttributes struct {
Copts bazel.StringListAttribute Copts bazel.StringListAttribute
Hdrs bazel.LabelListAttribute Hdrs bazel.LabelListAttribute
Includes bazel.LabelListAttribute Includes bazel.StringListAttribute
Deps bazel.LabelListAttribute Deps bazel.LabelListAttribute
} }
@ -95,15 +95,15 @@ func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) {
return return
} }
exportedIncludesLabels, exportedIncludesHeadersLabels := bp2BuildParseExportedIncludes(ctx, module) exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, module)
headerLibsLabels := bp2BuildParseHeaderLibs(ctx, module) headerLibs := bp2BuildParseHeaderLibs(ctx, module)
attrs := &bazelCcLibraryHeadersAttributes{ attrs := &bazelCcLibraryHeadersAttributes{
Copts: bp2BuildParseCflags(ctx, module), Copts: bp2BuildParseCflags(ctx, module),
Includes: exportedIncludesLabels, Includes: exportedIncludes,
Hdrs: exportedIncludesHeadersLabels, Hdrs: exportedIncludesHeaders,
Deps: headerLibsLabels, Deps: headerLibs,
} }
props := bazel.BazelTargetModuleProperties{ props := bazel.BazelTargetModuleProperties{