diff options
Diffstat (limited to 'bp2build')
| -rw-r--r-- | bp2build/build_conversion.go | 44 | ||||
| -rw-r--r-- | bp2build/build_conversion_test.go | 86 | ||||
| -rw-r--r-- | bp2build/cc_library_conversion_test.go | 147 | ||||
| -rw-r--r-- | bp2build/cc_library_headers_conversion_test.go | 1 | ||||
| -rw-r--r-- | bp2build/cc_library_static_conversion_test.go | 216 | ||||
| -rw-r--r-- | bp2build/cc_object_conversion_test.go | 6 | ||||
| -rw-r--r-- | bp2build/configurability.go | 94 | ||||
| -rw-r--r-- | bp2build/conversion.go | 35 | ||||
| -rw-r--r-- | bp2build/python_binary_conversion_test.go | 1 | ||||
| -rw-r--r-- | bp2build/sh_conversion_test.go | 1 |
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) } |