bp2build: Add special arch-variant targets.

Soong supports additional arch-variant targets based on arch/os aside
from strictly arch/os names. Handle the unconverted cases based solely
on arch/os.

Test: build/bazel/ci/bp2build.sh
Change-Id: I8dc987b1aa4a4ea646dd5b03a94b84297ba6113a
This commit is contained in:
Liz Kammer
2021-10-11 15:41:03 -04:00
parent 06f00c33a7
commit fdd72e6351
4 changed files with 149 additions and 68 deletions

View File

@@ -2006,17 +2006,10 @@ func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySe
osToProp := ArchVariantProperties{} osToProp := ArchVariantProperties{}
archOsToProp := ArchVariantProperties{} archOsToProp := ArchVariantProperties{}
var linuxStructs, bionicStructs []reflect.Value linuxStructs := getTargetStructs(ctx, archProperties, "Linux")
var ok bool bionicStructs := getTargetStructs(ctx, archProperties, "Bionic")
hostStructs := getTargetStructs(ctx, archProperties, "Host")
linuxStructs, ok = getTargetStructs(ctx, archProperties, "Linux") hostNotWindowsStructs := getTargetStructs(ctx, archProperties, "Not_windows")
if !ok {
linuxStructs = make([]reflect.Value, 0)
}
bionicStructs, ok = getTargetStructs(ctx, archProperties, "Bionic")
if !ok {
bionicStructs = make([]reflect.Value, 0)
}
// For android, linux, ... // For android, linux, ...
for _, os := range osTypeList { for _, os := range osTypeList {
@@ -2025,9 +2018,10 @@ func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySe
continue continue
} }
osStructs := make([]reflect.Value, 0) osStructs := make([]reflect.Value, 0)
osSpecificStructs, ok := getTargetStructs(ctx, archProperties, os.Field)
if ok { osSpecificStructs := getTargetStructs(ctx, archProperties, os.Field)
osStructs = append(osStructs, osSpecificStructs...) if os.Class == Host {
osStructs = append(osStructs, hostStructs...)
} }
if os.Linux() { if os.Linux() {
osStructs = append(osStructs, linuxStructs...) osStructs = append(osStructs, linuxStructs...)
@@ -2035,37 +2029,44 @@ func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySe
if os.Bionic() { if os.Bionic() {
osStructs = append(osStructs, bionicStructs...) osStructs = append(osStructs, bionicStructs...)
} }
if os == LinuxMusl {
osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Musl")...)
}
if os == Linux {
osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Glibc")...)
}
osStructs = append(osStructs, osSpecificStructs...)
if os.Class == Host && os != Windows {
osStructs = append(osStructs, hostNotWindowsStructs...)
}
osToProp[os.Name] = mergeStructs(ctx, osStructs, propertySet) osToProp[os.Name] = mergeStructs(ctx, osStructs, propertySet)
// For arm, x86, ... // For arm, x86, ...
for _, arch := range osArchTypeMap[os] { for _, arch := range osArchTypeMap[os] {
osArchStructs := make([]reflect.Value, 0) osArchStructs := make([]reflect.Value, 0)
targetField := GetCompoundTargetField(os, arch)
targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name)
targetStructs, ok := getTargetStructs(ctx, archProperties, targetField)
if ok {
osArchStructs = append(osArchStructs, targetStructs...)
}
// Auto-combine with Linux_ and Bionic_ targets. This potentially results in // Auto-combine with Linux_ and Bionic_ targets. This potentially results in
// repetition and select() bloat, but use of Linux_* and Bionic_* targets is rare. // repetition and select() bloat, but use of Linux_* and Bionic_* targets is rare.
// TODO(b/201423152): Look into cleanup. // TODO(b/201423152): Look into cleanup.
if os.Linux() { if os.Linux() {
targetField := "Linux_" + arch.Name targetField := "Linux_" + arch.Name
targetStructs, ok := getTargetStructs(ctx, archProperties, targetField) targetStructs := getTargetStructs(ctx, archProperties, targetField)
if ok { osArchStructs = append(osArchStructs, targetStructs...)
osArchStructs = append(osArchStructs, targetStructs...)
}
} }
if os.Bionic() { if os.Bionic() {
targetField := "Bionic_" + arch.Name targetField := "Bionic_" + arch.Name
targetStructs, ok := getTargetStructs(ctx, archProperties, targetField) targetStructs := getTargetStructs(ctx, archProperties, targetField)
if ok { osArchStructs = append(osArchStructs, targetStructs...)
osArchStructs = append(osArchStructs, targetStructs...)
}
} }
targetField := GetCompoundTargetField(os, arch)
targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name)
targetStructs := getTargetStructs(ctx, archProperties, targetField)
osArchStructs = append(osArchStructs, targetStructs...)
archOsToProp[targetName] = mergeStructs(ctx, osArchStructs, propertySet) archOsToProp[targetName] = mergeStructs(ctx, osArchStructs, propertySet)
} }
} }
@@ -2089,8 +2090,8 @@ func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySe
// } // }
// } // }
// This would return a BaseCompilerProperties with BaseCompilerProperties.Srcs = ["foo.c"] // This would return a BaseCompilerProperties with BaseCompilerProperties.Srcs = ["foo.c"]
func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targetName string) ([]reflect.Value, bool) { func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targetName string) []reflect.Value {
propertyStructs := make([]reflect.Value, 0) var propertyStructs []reflect.Value
for _, archProperty := range archProperties { for _, archProperty := range archProperties {
archPropValues := reflect.ValueOf(archProperty).Elem() archPropValues := reflect.ValueOf(archProperty).Elem()
targetProp := archPropValues.FieldByName("Target").Elem() targetProp := archPropValues.FieldByName("Target").Elem()
@@ -2098,11 +2099,11 @@ func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targ
if ok { if ok {
propertyStructs = append(propertyStructs, targetStruct) propertyStructs = append(propertyStructs, targetStruct)
} else { } else {
return propertyStructs, false return []reflect.Value{}
} }
} }
return propertyStructs, true return propertyStructs
} }
func mergeStructs(ctx ArchVariantContext, propertyStructs []reflect.Value, propertySet interface{}) interface{} { func mergeStructs(ctx ArchVariantContext, propertyStructs []reflect.Value, propertySet interface{}) interface{} {

View File

@@ -223,6 +223,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
func TestGenerateBazelTargetModules(t *testing.T) { func TestGenerateBazelTargetModules(t *testing.T) {
testCases := []bp2buildTestCase{ testCases := []bp2buildTestCase{
{ {
description: "string props",
blueprint: `custom { blueprint: `custom {
name: "foo", name: "foo",
string_list_prop: ["a", "b"], string_list_prop: ["a", "b"],
@@ -240,6 +241,7 @@ func TestGenerateBazelTargetModules(t *testing.T) {
}, },
}, },
{ {
description: "control characters",
blueprint: `custom { blueprint: `custom {
name: "control_characters", name: "control_characters",
string_list_prop: ["\t", "\n"], string_list_prop: ["\t", "\n"],
@@ -257,6 +259,7 @@ func TestGenerateBazelTargetModules(t *testing.T) {
}, },
}, },
{ {
description: "handles dep",
blueprint: `custom { blueprint: `custom {
name: "has_dep", name: "has_dep",
arch_paths: [":dep"], arch_paths: [":dep"],
@@ -279,25 +282,98 @@ custom {
}, },
}, },
{ {
description: "arch-variant srcs",
blueprint: `custom { blueprint: `custom {
name: "arch_paths", name: "arch_paths",
arch: { arch: {
x86: { x86: { arch_paths: ["x86.txt"] },
arch_paths: ["abc"], x86_64: { arch_paths: ["x86_64.txt"] },
}, arm: { arch_paths: ["arm.txt"] },
arm64: { arch_paths: ["arm64.txt"] },
},
target: {
linux: { arch_paths: ["linux.txt"] },
bionic: { arch_paths: ["bionic.txt"] },
host: { arch_paths: ["host.txt"] },
not_windows: { arch_paths: ["not_windows.txt"] },
android: { arch_paths: ["android.txt"] },
linux_musl: { arch_paths: ["linux_musl.txt"] },
musl: { arch_paths: ["musl.txt"] },
linux_glibc: { arch_paths: ["linux_glibc.txt"] },
glibc: { arch_paths: ["glibc.txt"] },
linux_bionic: { arch_paths: ["linux_bionic.txt"] },
darwin: { arch_paths: ["darwin.txt"] },
windows: { arch_paths: ["windows.txt"] },
},
multilib: {
lib32: { arch_paths: ["lib32.txt"] },
lib64: { arch_paths: ["lib64.txt"] },
}, },
bazel_module: { bp2build_available: true }, bazel_module: { bp2build_available: true },
}`, }`,
expectedBazelTargets: []string{`custom( expectedBazelTargets: []string{`custom(
name = "arch_paths", name = "arch_paths",
arch_paths = select({ arch_paths = select({
"//build/bazel/platforms/arch:x86": ["abc"], "//build/bazel/platforms/arch:arm": [
"arm.txt",
"lib32.txt",
],
"//build/bazel/platforms/arch:arm64": [
"arm64.txt",
"lib64.txt",
],
"//build/bazel/platforms/arch:x86": [
"x86.txt",
"lib32.txt",
],
"//build/bazel/platforms/arch:x86_64": [
"x86_64.txt",
"lib64.txt",
],
"//conditions:default": [],
}) + select({
"//build/bazel/platforms/os:android": [
"linux.txt",
"bionic.txt",
"android.txt",
],
"//build/bazel/platforms/os:darwin": [
"host.txt",
"darwin.txt",
"not_windows.txt",
],
"//build/bazel/platforms/os:linux": [
"host.txt",
"linux.txt",
"glibc.txt",
"linux_glibc.txt",
"not_windows.txt",
],
"//build/bazel/platforms/os:linux_bionic": [
"host.txt",
"linux.txt",
"bionic.txt",
"linux_bionic.txt",
"not_windows.txt",
],
"//build/bazel/platforms/os:linux_musl": [
"host.txt",
"linux.txt",
"musl.txt",
"linux_musl.txt",
"not_windows.txt",
],
"//build/bazel/platforms/os:windows": [
"host.txt",
"windows.txt",
],
"//conditions:default": [], "//conditions:default": [],
}), }),
)`, )`,
}, },
}, },
{ {
description: "arch-variant deps",
blueprint: `custom { blueprint: `custom {
name: "has_dep", name: "has_dep",
arch: { arch: {
@@ -327,6 +403,7 @@ custom {
}, },
}, },
{ {
description: "embedded props",
blueprint: `custom { blueprint: `custom {
name: "embedded_props", name: "embedded_props",
embedded_prop: "abc", embedded_prop: "abc",
@@ -339,6 +416,7 @@ custom {
}, },
}, },
{ {
description: "ptr to embedded props",
blueprint: `custom { blueprint: `custom {
name: "ptr_to_embedded_props", name: "ptr_to_embedded_props",
other_embedded_prop: "abc", other_embedded_prop: "abc",
@@ -354,38 +432,40 @@ custom {
dir := "." dir := "."
for _, testCase := range testCases { for _, testCase := range testCases {
config := android.TestConfig(buildDir, nil, testCase.blueprint, nil) t.Run(testCase.description, func(t *testing.T) {
ctx := android.NewTestContext(config) config := android.TestConfig(buildDir, nil, testCase.blueprint, nil)
ctx := android.NewTestContext(config)
registerCustomModuleForBp2buildConversion(ctx) registerCustomModuleForBp2buildConversion(ctx)
_, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
if errored(t, testCase, errs) { if errored(t, testCase, errs) {
continue return
} }
_, errs = ctx.ResolveDependencies(config) _, errs = ctx.ResolveDependencies(config)
if errored(t, testCase, errs) { if errored(t, testCase, errs) {
continue return
} }
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir) bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
android.FailIfErrored(t, err) android.FailIfErrored(t, err)
if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount) t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
} else { } else {
for i, expectedBazelTarget := range testCase.expectedBazelTargets { for i, expectedBazelTarget := range testCase.expectedBazelTargets {
actualBazelTarget := bazelTargets[i] actualBazelTarget := bazelTargets[i]
if actualBazelTarget.content != expectedBazelTarget { if actualBazelTarget.content != expectedBazelTarget {
t.Errorf( t.Errorf(
"Expected generated Bazel target to be '%s', got '%s'", "Expected generated Bazel target to be '%s', got '%s'",
expectedBazelTarget, expectedBazelTarget,
actualBazelTarget.content, actualBazelTarget.content,
) )
}
} }
} }
} })
} }
} }

View File

@@ -133,8 +133,8 @@ cc_library {
"//conditions:default": [], "//conditions:default": [],
}) + select({ }) + select({
"//build/bazel/platforms/os:android": [ "//build/bazel/platforms/os:android": [
"android.cpp",
"bionic.cpp", "bionic.cpp",
"android.cpp",
], ],
"//build/bazel/platforms/os:darwin": ["darwin.cpp"], "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
"//build/bazel/platforms/os:linux": ["linux.cpp"], "//build/bazel/platforms/os:linux": ["linux.cpp"],
@@ -1668,22 +1668,22 @@ cc_library {
name = "foo-lib", name = "foo-lib",
srcs = ["base.cpp"] + select({ srcs = ["base.cpp"] + select({
"//build/bazel/platforms/os:android": [ "//build/bazel/platforms/os:android": [
"android.cpp",
"linux.cpp", "linux.cpp",
"bionic.cpp", "bionic.cpp",
"android.cpp",
], ],
"//build/bazel/platforms/os:darwin": ["darwin.cpp"], "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
"//build/bazel/platforms/os:linux": [ "//build/bazel/platforms/os:linux": [
"linux_glibc.cpp",
"linux.cpp", "linux.cpp",
"linux_glibc.cpp",
], ],
"//build/bazel/platforms/os:linux_bionic": [ "//build/bazel/platforms/os:linux_bionic": [
"linux.cpp", "linux.cpp",
"bionic.cpp", "bionic.cpp",
], ],
"//build/bazel/platforms/os:linux_musl": [ "//build/bazel/platforms/os:linux_musl": [
"linux_musl.cpp",
"linux.cpp", "linux.cpp",
"linux_musl.cpp",
], ],
"//build/bazel/platforms/os:windows": ["windows.cpp"], "//build/bazel/platforms/os:windows": ["windows.cpp"],
"//conditions:default": [], "//conditions:default": [],

View File

@@ -283,7 +283,7 @@ func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
return return
} }
paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.props.Arch_paths, m.props.Arch_paths_exclude)) paths := bazel.LabelListAttribute{}
for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) { for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
for config, props := range configToProps { for config, props := range configToProps {