summaryrefslogtreecommitdiff
path: root/bp2build
diff options
context:
space:
mode:
Diffstat (limited to 'bp2build')
-rw-r--r--bp2build/build_conversion.go44
-rw-r--r--bp2build/build_conversion_test.go86
-rw-r--r--bp2build/cc_library_conversion_test.go147
-rw-r--r--bp2build/cc_library_headers_conversion_test.go1
-rw-r--r--bp2build/cc_library_static_conversion_test.go216
-rw-r--r--bp2build/cc_object_conversion_test.go6
-rw-r--r--bp2build/configurability.go94
-rw-r--r--bp2build/conversion.go35
-rw-r--r--bp2build/python_binary_conversion_test.go1
-rw-r--r--bp2build/sh_conversion_test.go1
10 files changed, 527 insertions, 104 deletions
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index bddc524cd..388c8cf66 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -19,6 +19,7 @@ import (
"android/soong/bazel"
"fmt"
"reflect"
+ "sort"
"strings"
"github.com/google/blueprint"
@@ -34,6 +35,7 @@ type BazelTarget struct {
content string
ruleClass string
bzlLoadLocation string
+ handcrafted bool
}
// IsLoadedFromStarlark determines if the BazelTarget's rule class is loaded from a .bzl file,
@@ -45,12 +47,47 @@ func (t BazelTarget) IsLoadedFromStarlark() bool {
// BazelTargets is a typedef for a slice of BazelTarget objects.
type BazelTargets []BazelTarget
+// HasHandcraftedTargetsreturns true if a set of bazel targets contain
+// handcrafted ones.
+func (targets BazelTargets) hasHandcraftedTargets() bool {
+ for _, target := range targets {
+ if target.handcrafted {
+ return true
+ }
+ }
+ return false
+}
+
+// sort a list of BazelTargets in-place, by name, and by generated/handcrafted types.
+func (targets BazelTargets) sort() {
+ sort.Slice(targets, func(i, j int) bool {
+ if targets[i].handcrafted != targets[j].handcrafted {
+ // Handcrafted targets will be generated after the bp2build generated targets.
+ return targets[j].handcrafted
+ }
+ // This will cover all bp2build generated targets.
+ return targets[i].name < targets[j].name
+ })
+}
+
// String returns the string representation of BazelTargets, without load
// statements (use LoadStatements for that), since the targets are usually not
// adjacent to the load statements at the top of the BUILD file.
func (targets BazelTargets) String() string {
var res string
for i, target := range targets {
+ // There is only at most 1 handcrafted "target", because its contents
+ // represent the entire BUILD file content from the tree. See
+ // build_conversion.go#getHandcraftedBuildContent for more information.
+ //
+ // Add a header to make it easy to debug where the handcrafted targets
+ // are in a generated BUILD file.
+ if target.handcrafted {
+ res += "# -----------------------------\n"
+ res += "# Section: Handcrafted targets. \n"
+ res += "# -----------------------------\n\n"
+ }
+
res += target.content
if i != len(targets)-1 {
res += "\n\n"
@@ -267,7 +304,8 @@ func getHandcraftedBuildContent(ctx *CodegenContext, b android.Bazelable, pathTo
}
// TODO(b/181575318): once this is more targeted, we need to include name, rule class, etc
return BazelTarget{
- content: c,
+ content: c,
+ handcrafted: true,
}, nil
}
@@ -294,6 +332,7 @@ func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module, btm android.B
targetName,
attributes,
),
+ handcrafted: false,
}
}
@@ -529,6 +568,9 @@ func isZero(value reflect.Value) bool {
return true
}
default:
+ if !value.IsValid() {
+ return true
+ }
zeroValue := reflect.Zero(value.Type())
result := value.Interface() == zeroValue.Interface()
return result
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 71660a8e1..b1c342c69 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -1452,53 +1452,61 @@ filegroup {
dir := "."
for _, testCase := range testCases {
- fs := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.fs {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
+ t.Run(testCase.description, func(t *testing.T) {
+ fs := make(map[string][]byte)
+ toParse := []string{
+ "Android.bp",
}
- fs[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.bp, fs)
- ctx := android.NewTestContext(config)
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- for _, m := range testCase.depsMutators {
- ctx.DepsBp2BuildMutators(m)
- }
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
+ for f, content := range testCase.fs {
+ if strings.HasSuffix(f, "Android.bp") {
+ toParse = append(toParse, f)
+ }
+ fs[f] = []byte(content)
+ }
+ config := android.TestConfig(buildDir, nil, testCase.bp, fs)
+ ctx := android.NewTestContext(config)
+ ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ for _, m := range testCase.depsMutators {
+ ctx.DepsBp2BuildMutators(m)
+ }
+ ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
- _, errs := ctx.ParseFileList(dir, toParse)
- if errored(t, testCase.description, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if errored(t, testCase.description, errs) {
- continue
- }
+ _, errs := ctx.ParseFileList(dir, toParse)
+ if errored(t, testCase.description, errs) {
+ return
+ }
+ _, errs = ctx.ResolveDependencies(config)
+ if errored(t, testCase.description, errs) {
+ return
+ }
- checkDir := dir
- if testCase.dir != "" {
- checkDir = testCase.dir
- }
- bazelTargets := generateBazelTargetsForDir(NewCodegenContext(config, *ctx.Context, Bp2Build), checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d\n%s", testCase.description, expectedCount, actualCount, bazelTargets)
- } else {
+ checkDir := dir
+ if testCase.dir != "" {
+ checkDir = testCase.dir
+ }
+ bazelTargets := generateBazelTargetsForDir(NewCodegenContext(config, *ctx.Context, Bp2Build), checkDir)
+ bazelTargets.sort()
+ actualCount := len(bazelTargets)
+ expectedCount := len(testCase.expectedBazelTargets)
+ if actualCount != expectedCount {
+ t.Errorf("Expected %d bazel target, got %d\n%s", expectedCount, actualCount, bazelTargets)
+ }
+ if !strings.Contains(bazelTargets.String(), "Section: Handcrafted targets. ") {
+ t.Errorf("Expected string representation of bazelTargets to contain handcrafted section header.")
+ }
for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
+ actualContent := target.content
+ expectedContent := testCase.expectedBazelTargets[i]
+ if expectedContent != actualContent {
t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
+ "Expected generated Bazel target to be '%s', got '%s'",
+ expectedContent,
+ actualContent,
)
}
}
- }
+ })
}
}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 0a729374e..6aa148ec2 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -41,6 +41,7 @@ toolchain_library {
)
func runCcLibraryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
runBp2BuildTestCase(t, registerCcLibraryModuleTypes, tc)
}
@@ -52,6 +53,7 @@ func registerCcLibraryModuleTypes(ctx android.RegistrationContext) {
}
func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
+ t.Helper()
dir := "."
filesystem := make(map[string][]byte)
toParse := []string{
@@ -311,7 +313,7 @@ cc_library {
"//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
"//conditions:default": [],
}),
- srcs = ["math/cosf.c"],
+ srcs_c = ["math/cosf.c"],
)`},
})
}
@@ -398,6 +400,141 @@ cc_library { name: "shared_dep_for_both" }
})
}
+func TestCcLibrarySharedStaticPropsInArch(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ description: "cc_library shared/static props in arch",
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ dir: "foo/bar",
+ filesystem: map[string]string{
+ "foo/bar/arm.cpp": "",
+ "foo/bar/x86.cpp": "",
+ "foo/bar/sharedonly.cpp": "",
+ "foo/bar/staticonly.cpp": "",
+ "foo/bar/Android.bp": `
+cc_library {
+ name: "a",
+ arch: {
+ arm: {
+ shared: {
+ srcs: ["arm_shared.cpp"],
+ cflags: ["-DARM_SHARED"],
+ static_libs: ["arm_static_dep_for_shared"],
+ whole_static_libs: ["arm_whole_static_dep_for_shared"],
+ shared_libs: ["arm_shared_dep_for_shared"],
+ },
+ },
+ x86: {
+ static: {
+ srcs: ["x86_static.cpp"],
+ cflags: ["-DX86_STATIC"],
+ static_libs: ["x86_dep_for_static"],
+ },
+ },
+ },
+ target: {
+ android: {
+ shared: {
+ srcs: ["android_shared.cpp"],
+ cflags: ["-DANDROID_SHARED"],
+ static_libs: ["android_dep_for_shared"],
+ },
+ },
+ android_arm: {
+ shared: {
+ cflags: ["-DANDROID_ARM_SHARED"],
+ },
+ },
+ },
+ srcs: ["both.cpp"],
+ cflags: ["bothflag"],
+ static_libs: ["static_dep_for_both"],
+ static: {
+ srcs: ["staticonly.cpp"],
+ cflags: ["staticflag"],
+ static_libs: ["static_dep_for_static"],
+ },
+ shared: {
+ srcs: ["sharedonly.cpp"],
+ cflags: ["sharedflag"],
+ static_libs: ["static_dep_for_shared"],
+ },
+ bazel_module: { bp2build_available: true },
+}
+
+cc_library_static { name: "static_dep_for_shared" }
+cc_library_static { name: "static_dep_for_static" }
+cc_library_static { name: "static_dep_for_both" }
+
+cc_library_static { name: "arm_static_dep_for_shared" }
+cc_library_static { name: "arm_whole_static_dep_for_shared" }
+cc_library_static { name: "arm_shared_dep_for_shared" }
+
+cc_library_static { name: "x86_dep_for_static" }
+
+cc_library_static { name: "android_dep_for_shared" }
+`,
+ },
+ blueprint: soongCcLibraryPreamble,
+ expectedBazelTargets: []string{`cc_library(
+ name = "a",
+ copts = [
+ "bothflag",
+ "-Ifoo/bar",
+ "-I$(BINDIR)/foo/bar",
+ ],
+ dynamic_deps_for_shared = select({
+ "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+ implementation_deps = [":static_dep_for_both"],
+ shared_copts = ["sharedflag"] + select({
+ "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms:android_arm": ["-DANDROID_ARM_SHARED"],
+ "//conditions:default": [],
+ }),
+ shared_srcs = ["sharedonly.cpp"] + select({
+ "//build/bazel/platforms/arch:arm": ["arm_shared.cpp"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": ["android_shared.cpp"],
+ "//conditions:default": [],
+ }),
+ srcs = ["both.cpp"],
+ static_copts = ["staticflag"] + select({
+ "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
+ "//conditions:default": [],
+ }),
+ static_deps_for_shared = [":static_dep_for_shared"] + select({
+ "//build/bazel/platforms/arch:arm": [":arm_static_dep_for_shared"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:android": [":android_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+ static_deps_for_static = [":static_dep_for_static"] + select({
+ "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
+ "//conditions:default": [],
+ }),
+ static_srcs = ["staticonly.cpp"] + select({
+ "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
+ "//conditions:default": [],
+ }),
+ whole_archive_deps_for_shared = select({
+ "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
+ "//conditions:default": [],
+ }),
+)`},
+ })
+}
+
func TestCcLibraryNonConfiguredVersionScript(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library non-configured version script",
@@ -618,7 +755,7 @@ cc_library {
func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
- description: "cc_library cppflags goes into copts",
+ description: "cc_library cppflags usage",
moduleTypeUnderTest: "cc_library",
moduleTypeUnderTestFactory: cc.LibraryFactory,
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
@@ -654,10 +791,12 @@ func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
name = "a",
copts = [
"-Wall",
- "-fsigned-char",
- "-pedantic",
"-Ifoo/bar",
"-I$(BINDIR)/foo/bar",
+ ],
+ cppflags = [
+ "-fsigned-char",
+ "-pedantic",
] + select({
"//build/bazel/platforms/arch:arm64": ["-DARM64=1"],
"//conditions:default": [],
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 2859bab70..264ba6bb8 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -84,6 +84,7 @@ func registerCcLibraryHeadersModuleTypes(ctx android.RegistrationContext) {
}
func runCcLibraryHeadersTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
runBp2BuildTestCase(t, registerCcLibraryHeadersModuleTypes, tc)
}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 62084a544..833ceba09 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -76,6 +76,7 @@ func registerCcLibraryStaticModuleTypes(ctx android.RegistrationContext) {
}
func runCcLibraryStaticTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
runBp2BuildTestCase(t, registerCcLibraryStaticModuleTypes, tc)
}
@@ -650,7 +651,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = [
+ srcs_c = [
"common.c",
"foo-a.c",
],
@@ -682,7 +683,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["foo-arm.c"],
"//conditions:default": [],
}),
@@ -719,7 +720,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["for-arm.c"],
"//conditions:default": ["not-for-arm.c"],
}),
@@ -758,7 +759,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-arm.c",
"not-for-x86.c",
@@ -813,7 +814,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-arm.c",
"not-for-arm64.c",
@@ -909,7 +910,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": ["for-lib32.c"],
"//build/bazel/platforms/arch:x86": ["for-lib32.c"],
"//conditions:default": ["not-for-lib32.c"],
@@ -948,7 +949,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-lib32.c",
"not-for-lib64.c",
@@ -1020,7 +1021,7 @@ cc_library_static {
"-I$(BINDIR)/.",
],
linkstatic = True,
- srcs = ["common.c"] + select({
+ srcs_c = ["common.c"] + select({
"//build/bazel/platforms/arch:arm": [
"for-arm.c",
"for-lib32.c",
@@ -1074,10 +1075,10 @@ func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
filesystem: map[string]string{
- "common.c": "",
- "for-x86.c": "",
- "not-for-x86.c": "",
- "not-for-everything.c": "",
+ "common.cpp": "",
+ "for-x86.cpp": "",
+ "not-for-x86.cpp": "",
+ "not-for-everything.cpp": "",
"dep/Android.bp": `
genrule {
name: "generated_src_other_pkg",
@@ -1118,14 +1119,14 @@ genrule {
cc_library_static {
name: "foo_static3",
- srcs: ["common.c", "not-for-*.c"],
- exclude_srcs: ["not-for-everything.c"],
+ srcs: ["common.cpp", "not-for-*.cpp"],
+ exclude_srcs: ["not-for-everything.cpp"],
generated_sources: ["generated_src", "generated_src_other_pkg"],
generated_headers: ["generated_hdr", "generated_hdr_other_pkg"],
arch: {
x86: {
- srcs: ["for-x86.c"],
- exclude_srcs: ["not-for-x86.c"],
+ srcs: ["for-x86.cpp"],
+ exclude_srcs: ["not-for-x86.cpp"],
generated_sources: ["generated_src_x86"],
generated_headers: ["generated_hdr_other_pkg_x86"],
},
@@ -1144,15 +1145,192 @@ cc_library_static {
"//dep:generated_src_other_pkg",
":generated_hdr",
":generated_src",
- "common.c",
+ "common.cpp",
] + select({
"//build/bazel/platforms/arch:x86": [
"//dep:generated_hdr_other_pkg_x86",
":generated_src_x86",
- "for-x86.c",
+ "for-x86.cpp",
],
- "//conditions:default": ["not-for-x86.c"],
+ "//conditions:default": ["not-for-x86.cpp"],
+ }),
+)`},
+ })
+}
+
+func TestCcLibraryStaticGetTargetProperties(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+
+ description: "cc_library_static complex GetTargetProperties",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ target: {
+ android: {
+ srcs: ["android_src.c"],
+ },
+ android_arm: {
+ srcs: ["android_arm_src.c"],
+ },
+ android_arm64: {
+ srcs: ["android_arm64_src.c"],
+ },
+ android_x86: {
+ srcs: ["android_x86_src.c"],
+ },
+ android_x86_64: {
+ srcs: ["android_x86_64_src.c"],
+ },
+ linux_bionic_arm64: {
+ srcs: ["linux_bionic_arm64_src.c"],
+ },
+ linux_bionic_x86_64: {
+ srcs: ["linux_bionic_x86_64_src.c"],
+ },
+ },
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ],
+ linkstatic = True,
+ srcs_c = select({
+ "//build/bazel/platforms/os:android": ["android_src.c"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms:android_arm": ["android_arm_src.c"],
+ "//build/bazel/platforms:android_arm64": ["android_arm64_src.c"],
+ "//build/bazel/platforms:android_x86": ["android_x86_src.c"],
+ "//build/bazel/platforms:android_x86_64": ["android_x86_64_src.c"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms:linux_bionic_arm64": ["linux_bionic_arm64_src.c"],
+ "//build/bazel/platforms:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
+ "//conditions:default": [],
+ }),
+)`},
+ })
+}
+
+func TestCcLibraryStaticProductVariableSelects(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static product variable selects",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.c"],
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wmalloc_not_svelte"],
+ },
+ malloc_zero_contents: {
+ cflags: ["-Wmalloc_zero_contents"],
+ },
+ binder32bit: {
+ cflags: ["-Wbinder32bit"],
+ },
+ },
+} `,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ] + select({
+ "//build/bazel/product_variables:binder32bit": ["-Wbinder32bit"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_zero_contents": ["-Wmalloc_zero_contents"],
+ "//conditions:default": [],
+ }),
+ linkstatic = True,
+ srcs_c = ["common.c"],
+)`},
+ })
+}
+
+func TestCcLibraryStaticProductVariableArchSpecificSelects(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ description: "cc_library_static arch-specific product variable selects",
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+ filesystem: map[string]string{},
+ blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+ name: "foo_static",
+ srcs: ["common.c"],
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wmalloc_not_svelte"],
+ },
+ },
+ arch: {
+ arm64: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Warm64_malloc_not_svelte"],
+ },
+ },
+ },
+ },
+ multilib: {
+ lib32: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wlib32_malloc_not_svelte"],
+ },
+ },
+ },
+ },
+ target: {
+ android: {
+ product_variables: {
+ malloc_not_svelte: {
+ cflags: ["-Wandroid_malloc_not_svelte"],
+ },
+ },
+ }
+ },
+} `,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ copts = [
+ "-I.",
+ "-I$(BINDIR)/.",
+ ] + select({
+ "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-android": ["-Wandroid_malloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-arm": ["-Wlib32_malloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-arm64": ["-Warm64_malloc_not_svelte"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/product_variables:malloc_not_svelte-x86": ["-Wlib32_malloc_not_svelte"],
+ "//conditions:default": [],
}),
+ linkstatic = True,
+ srcs_c = ["common.c"],
)`},
})
}
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index b69135b6e..f7e94c28c 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -27,6 +27,7 @@ func registerCcObjectModuleTypes(ctx android.RegistrationContext) {
}
func runCcObjectTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
runBp2BuildTestCase(t, registerCcObjectModuleTypes, tc)
}
@@ -208,7 +209,10 @@ func TestCcObjectProductVariable(t *testing.T) {
`,
expectedBazelTargets: []string{`cc_object(
name = "foo",
- asflags = ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
+ asflags = select({
+ "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
+ "//conditions:default": [],
+ }),
copts = ["-fno-addrsig"],
)`,
},
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index 2b8f6cc2e..b5070b9c9 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -11,26 +11,55 @@ import (
type selects map[string]reflect.Value
-func getStringListValues(list bazel.StringListAttribute) (reflect.Value, selects, selects) {
+func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value)
if !list.HasConfigurableValues() {
- return value, nil, nil
+ return value, []selects{}
}
+ selectValues := make([]selects, 0)
archSelects := map[string]reflect.Value{}
for arch, selectKey := range bazel.PlatformArchMap {
archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch))
}
+ if len(archSelects) > 0 {
+ selectValues = append(selectValues, archSelects)
+ }
osSelects := map[string]reflect.Value{}
- for os, selectKey := range bazel.PlatformOsMap {
- osSelects[selectKey] = reflect.ValueOf(list.GetValueForOS(os))
+ osArchSelects := make([]selects, 0)
+ for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
+ selectKey := bazel.PlatformOsMap[os]
+ osSelects[selectKey] = reflect.ValueOf(list.GetOsValueForTarget(os))
+ archSelects := make(map[string]reflect.Value)
+ // TODO(b/187530594): Should we also check arch=CONDITIONS_DEFAULT? (not in AllArches)
+ for _, arch := range bazel.AllArches {
+ target := os + "_" + arch
+ selectKey := bazel.PlatformTargetMap[target]
+ archSelects[selectKey] = reflect.ValueOf(list.GetOsArchValueForTarget(os, arch))
+ }
+ osArchSelects = append(osArchSelects, archSelects)
+ }
+ if len(osSelects) > 0 {
+ selectValues = append(selectValues, osSelects)
+ }
+ if len(osArchSelects) > 0 {
+ selectValues = append(selectValues, osArchSelects...)
+ }
+
+ for _, pv := range list.SortedProductVariables() {
+ s := make(selects)
+ if len(pv.Values) > 0 {
+ s[pv.SelectKey()] = reflect.ValueOf(pv.Values)
+ s[bazel.ConditionsDefaultSelectKey] = reflect.ValueOf([]string{})
+ selectValues = append(selectValues, s)
+ }
}
- return value, archSelects, osSelects
+ return value, selectValues
}
-func getLabelValue(label bazel.LabelAttribute) (reflect.Value, selects, selects) {
+func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
var value reflect.Value
var archSelects selects
@@ -43,13 +72,13 @@ func getLabelValue(label bazel.LabelAttribute) (reflect.Value, selects, selects)
value = reflect.ValueOf(label.Value)
}
- return value, archSelects, nil
+ return value, []selects{archSelects}
}
-func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, selects, selects) {
+func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value.Includes)
if !list.HasConfigurableValues() {
- return value, nil, nil
+ return value, []selects{}
}
archSelects := map[string]reflect.Value{}
@@ -58,33 +87,48 @@ func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, selects,
}
osSelects := map[string]reflect.Value{}
- for os, selectKey := range bazel.PlatformOsMap {
- osSelects[selectKey] = reflect.ValueOf(list.GetValueForOS(os).Includes)
+ osArchSelects := make([]selects, 0)
+ for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
+ selectKey := bazel.PlatformOsMap[os]
+ osSelects[selectKey] = reflect.ValueOf(list.GetOsValueForTarget(os).Includes)
+ archSelects := make(map[string]reflect.Value)
+ // TODO(b/187530594): Should we also check arch=CONDITIOSN_DEFAULT? (not in AllArches)
+ for _, arch := range bazel.AllArches {
+ target := os + "_" + arch
+ selectKey := bazel.PlatformTargetMap[target]
+ archSelects[selectKey] = reflect.ValueOf(list.GetOsArchValueForTarget(os, arch).Includes)
+ }
+ osArchSelects = append(osArchSelects, archSelects)
}
- return value, archSelects, osSelects
+ var selects []selects
+ selects = append(selects, archSelects)
+ selects = append(selects, osSelects)
+ selects = append(selects, osArchSelects...)
+ return value, selects
}
// prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
// select statements.
func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
var value reflect.Value
- var archSelects, osSelects selects
+ var configurableAttrs []selects
var defaultSelectValue string
switch list := v.(type) {
case bazel.StringListAttribute:
- value, archSelects, osSelects = getStringListValues(list)
+ value, configurableAttrs = getStringListValues(list)
defaultSelectValue = "[]"
case bazel.LabelListAttribute:
- value, archSelects, osSelects = getLabelListValues(list)
+ value, configurableAttrs = getLabelListValues(list)
defaultSelectValue = "[]"
case bazel.LabelAttribute:
- value, archSelects, osSelects = getLabelValue(list)
+ value, configurableAttrs = getLabelValue(list)
defaultSelectValue = "None"
default:
return "", fmt.Errorf("Not a supported Bazel attribute type: %s", v)
}
+ var err error
ret := ""
if value.Kind() != reflect.Invalid {
s, err := prettyPrint(value, indent)
@@ -108,13 +152,14 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
return s, nil
}
- ret, err := appendSelects(archSelects, defaultSelectValue, ret)
- if err != nil {
- return "", err
+ for _, configurableAttr := range configurableAttrs {
+ ret, err = appendSelects(configurableAttr, defaultSelectValue, ret)
+ if err != nil {
+ return "", err
+ }
}
- ret, err = appendSelects(osSelects, defaultSelectValue, ret)
- return ret, err
+ return ret, nil
}
// prettyPrintSelectMap converts a map of select keys to reflected Values as a generic way
@@ -125,11 +170,10 @@ func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue strin
}
// addConditionsDefault := false
- conditionsDefaultKey := bazel.PlatformArchMap[bazel.CONDITIONS_DEFAULT]
var selects string
for _, selectKey := range android.SortedStringKeys(selectMap) {
- if selectKey == conditionsDefaultKey {
+ if selectKey == bazel.ConditionsDefaultSelectKey {
// Handle default condition later.
continue
}
@@ -159,14 +203,14 @@ func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue strin
ret += selects
// Handle the default condition
- s, err := prettyPrintSelectEntry(selectMap[conditionsDefaultKey], conditionsDefaultKey, indent)
+ s, err := prettyPrintSelectEntry(selectMap[bazel.ConditionsDefaultSelectKey], bazel.ConditionsDefaultSelectKey, indent)
if err != nil {
return "", err
}
if s == "" {
// Print an explicit empty list (the default value) even if the value is
// empty, to avoid errors about not finding a configuration that matches.
- ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), "//conditions:default", defaultValue)
+ ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), bazel.ConditionsDefaultSelectKey, defaultValue)
} else {
// Print the custom default value.
ret += s
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 101ad3d04..bced4c19f 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -5,7 +5,6 @@ import (
"android/soong/cc/config"
"fmt"
"reflect"
- "sort"
"strings"
"github.com/google/blueprint/proptools"
@@ -64,22 +63,28 @@ func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode)
continue
}
targets := buildToTargets[dir]
- sort.Slice(targets, func(i, j int) bool {
- // this will cover all bp2build generated targets
- if targets[i].name < targets[j].name {
- return true
- }
- // give a strict ordering to content from hand-crafted targets
- return targets[i].content < targets[j].content
- })
- content := soongModuleLoad
+ targets.sort()
+
+ var content string
if mode == Bp2Build {
- content = `# This file was automatically generated by bp2build for the Bazel migration project.
-# Feel free to edit or test it, but do *not* check it into your version control system.`
- content += "\n\n"
- content += "package(default_visibility = [\"//visibility:public\"])"
- content += "\n\n"
+ content = `# READ THIS FIRST:
+# This file was automatically generated by bp2build for the Bazel migration project.
+# Feel free to edit or test it, but do *not* check it into your version control system.
+`
+ if targets.hasHandcraftedTargets() {
+ // For BUILD files with both handcrafted and generated targets,
+ // don't hardcode actual content, like package() declarations.
+ // Leave that responsibility to the checked-in BUILD file
+ // instead.
+ content += `# This file contains generated targets and handcrafted targets that are manually managed in the source tree.`
+ } else {
+ // For fully-generated BUILD files, hardcode the default visibility.
+ content += "package(default_visibility = [\"//visibility:public\"])"
+ }
+ content += "\n"
content += targets.LoadStatements()
+ } else if mode == QueryView {
+ content = soongModuleLoad
}
if content != "" {
// If there are load statements, add a couple of newlines.
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 95bce3c18..7bedf7120 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -8,6 +8,7 @@ import (
)
func runPythonTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
}
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index 91bba541d..82e0a14ca 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -49,6 +49,7 @@ func TestShBinaryLoadStatement(t *testing.T) {
}
func runShBinaryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
}