Loading bp2build/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ bootstrap_go_package { "build_conversion.go", "bzl_conversion.go", "conversion.go", "metrics.go", ], deps: [ "soong-android", Loading bp2build/bp2build.go +4 −2 Original line number Diff line number Diff line Loading @@ -22,13 +22,13 @@ import ( // The Bazel bp2build code generator is responsible for writing .bzl files that are equivalent to // Android.bp files that are capable of being built with Bazel. func Codegen(ctx CodegenContext) { func Codegen(ctx CodegenContext) CodegenMetrics { outputDir := android.PathForOutput(ctx, "bp2build") android.RemoveAllOutputDir(outputDir) ruleShims := CreateRuleShims(android.ModuleTypeFactories()) buildToTargets := GenerateBazelTargets(ctx.Context(), ctx.mode) buildToTargets, metrics := GenerateBazelTargets(ctx) filesToWrite := CreateBazelFiles(ruleShims, buildToTargets, ctx.mode) for _, f := range filesToWrite { Loading @@ -36,6 +36,8 @@ func Codegen(ctx CodegenContext) { fmt.Errorf("Failed to write %q (dir %q) due to %q", f.Basename, f.Dir, err) } } return metrics } func writeFile(outputDir android.OutputPath, ctx android.PathContext, f BazelFile) error { Loading bp2build/build_conversion.go +34 −9 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ type CodegenContext struct { mode CodegenMode } func (c *CodegenContext) Mode() CodegenMode { return c.mode } // CodegenMode is an enum to differentiate code-generation modes. type CodegenMode int Loading Loading @@ -160,33 +164,54 @@ func propsToAttributes(props map[string]string) string { return attributes } func GenerateBazelTargets(ctx bpToBuildContext, codegenMode CodegenMode) map[string]BazelTargets { func GenerateBazelTargets(ctx CodegenContext) (map[string]BazelTargets, CodegenMetrics) { buildFileToTargets := make(map[string]BazelTargets) ctx.VisitAllModules(func(m blueprint.Module) { dir := ctx.ModuleDir(m) // Simple metrics tracking for bp2build totalModuleCount := 0 ruleClassCount := make(map[string]int) bpCtx := ctx.Context() bpCtx.VisitAllModules(func(m blueprint.Module) { dir := bpCtx.ModuleDir(m) var t BazelTarget switch codegenMode { switch ctx.Mode() { case Bp2Build: if _, ok := m.(android.BazelTargetModule); !ok { // Only include regular Soong modules (non-BazelTargetModules) into the total count. totalModuleCount += 1 return } t = generateBazelTarget(ctx, m) t = generateBazelTarget(bpCtx, m) ruleClassCount[t.ruleClass] += 1 case QueryView: // Blocklist certain module types from being generated. if canonicalizeModuleType(ctx.ModuleType(m)) == "package" { if canonicalizeModuleType(bpCtx.ModuleType(m)) == "package" { // package module name contain slashes, and thus cannot // be mapped cleanly to a bazel label. return } t = generateSoongModuleTarget(ctx, m) t = generateSoongModuleTarget(bpCtx, m) default: panic(fmt.Errorf("Unknown code-generation mode: %s", codegenMode)) panic(fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode())) } buildFileToTargets[dir] = append(buildFileToTargets[dir], t) }) return buildFileToTargets metrics := CodegenMetrics{ TotalModuleCount: totalModuleCount, RuleClassCount: ruleClassCount, } return buildFileToTargets, metrics } // Helper method for tests to easily access the targets in a dir. func GenerateBazelTargetsForDir(codegenCtx CodegenContext, dir string) BazelTargets { bazelTargetsMap, _ := GenerateBazelTargets(codegenCtx) return bazelTargetsMap[dir] } // Helper method to trim quotes around strings. Loading bp2build/build_conversion_test.go +16 −6 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) { for _, testCase := range testCases { config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) ctx.RegisterModuleType("custom", customModuleFactory) ctx.Register() Loading @@ -202,7 +203,8 @@ func TestGenerateSoongModuleTargets(t *testing.T) { _, errs = ctx.PrepareBuildActions(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, QueryView)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount) } Loading Loading @@ -245,6 +247,7 @@ func TestGenerateBazelTargetModules(t *testing.T) { for _, testCase := range testCases { config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) ctx.RegisterModuleType("custom", customModuleFactory) ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator) ctx.RegisterForBazelConversion() Loading @@ -258,7 +261,9 @@ func TestGenerateBazelTargetModules(t *testing.T) { continue } bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount) } else { Loading Loading @@ -415,7 +420,8 @@ load("//build/bazel/rules:rules.bzl", "my_library")`, _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount := len(bazelTargets); actualCount != testCase.expectedBazelTargetCount { t.Fatalf("Expected %d bazel target, got %d", testCase.expectedBazelTargetCount, actualCount) } Loading Loading @@ -904,7 +910,9 @@ genrule { if testCase.dir != "" { checkDir = testCase.dir } bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, checkDir) if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount) } else { Loading Loading @@ -1118,7 +1126,8 @@ genrule { _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount := len(bazelTargets); actualCount != 1 { t.Fatalf("%s: Expected 1 bazel target, got %d", testCase.description, actualCount) } Loading Loading @@ -1205,7 +1214,8 @@ func TestAllowlistingBp2buildTargets(t *testing.T) { _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount := len(bazelTargets); actualCount != testCase.expectedCount { t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount) } Loading bp2build/cc_library_headers_conversion_test.go +2 −1 Original line number Diff line number Diff line Loading @@ -202,7 +202,8 @@ cc_library_headers { if testCase.dir != "" { checkDir = testCase.dir } bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, checkDir) if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount) } else { Loading Loading
bp2build/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ bootstrap_go_package { "build_conversion.go", "bzl_conversion.go", "conversion.go", "metrics.go", ], deps: [ "soong-android", Loading
bp2build/bp2build.go +4 −2 Original line number Diff line number Diff line Loading @@ -22,13 +22,13 @@ import ( // The Bazel bp2build code generator is responsible for writing .bzl files that are equivalent to // Android.bp files that are capable of being built with Bazel. func Codegen(ctx CodegenContext) { func Codegen(ctx CodegenContext) CodegenMetrics { outputDir := android.PathForOutput(ctx, "bp2build") android.RemoveAllOutputDir(outputDir) ruleShims := CreateRuleShims(android.ModuleTypeFactories()) buildToTargets := GenerateBazelTargets(ctx.Context(), ctx.mode) buildToTargets, metrics := GenerateBazelTargets(ctx) filesToWrite := CreateBazelFiles(ruleShims, buildToTargets, ctx.mode) for _, f := range filesToWrite { Loading @@ -36,6 +36,8 @@ func Codegen(ctx CodegenContext) { fmt.Errorf("Failed to write %q (dir %q) due to %q", f.Basename, f.Dir, err) } } return metrics } func writeFile(outputDir android.OutputPath, ctx android.PathContext, f BazelFile) error { Loading
bp2build/build_conversion.go +34 −9 Original line number Diff line number Diff line Loading @@ -105,6 +105,10 @@ type CodegenContext struct { mode CodegenMode } func (c *CodegenContext) Mode() CodegenMode { return c.mode } // CodegenMode is an enum to differentiate code-generation modes. type CodegenMode int Loading Loading @@ -160,33 +164,54 @@ func propsToAttributes(props map[string]string) string { return attributes } func GenerateBazelTargets(ctx bpToBuildContext, codegenMode CodegenMode) map[string]BazelTargets { func GenerateBazelTargets(ctx CodegenContext) (map[string]BazelTargets, CodegenMetrics) { buildFileToTargets := make(map[string]BazelTargets) ctx.VisitAllModules(func(m blueprint.Module) { dir := ctx.ModuleDir(m) // Simple metrics tracking for bp2build totalModuleCount := 0 ruleClassCount := make(map[string]int) bpCtx := ctx.Context() bpCtx.VisitAllModules(func(m blueprint.Module) { dir := bpCtx.ModuleDir(m) var t BazelTarget switch codegenMode { switch ctx.Mode() { case Bp2Build: if _, ok := m.(android.BazelTargetModule); !ok { // Only include regular Soong modules (non-BazelTargetModules) into the total count. totalModuleCount += 1 return } t = generateBazelTarget(ctx, m) t = generateBazelTarget(bpCtx, m) ruleClassCount[t.ruleClass] += 1 case QueryView: // Blocklist certain module types from being generated. if canonicalizeModuleType(ctx.ModuleType(m)) == "package" { if canonicalizeModuleType(bpCtx.ModuleType(m)) == "package" { // package module name contain slashes, and thus cannot // be mapped cleanly to a bazel label. return } t = generateSoongModuleTarget(ctx, m) t = generateSoongModuleTarget(bpCtx, m) default: panic(fmt.Errorf("Unknown code-generation mode: %s", codegenMode)) panic(fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode())) } buildFileToTargets[dir] = append(buildFileToTargets[dir], t) }) return buildFileToTargets metrics := CodegenMetrics{ TotalModuleCount: totalModuleCount, RuleClassCount: ruleClassCount, } return buildFileToTargets, metrics } // Helper method for tests to easily access the targets in a dir. func GenerateBazelTargetsForDir(codegenCtx CodegenContext, dir string) BazelTargets { bazelTargetsMap, _ := GenerateBazelTargets(codegenCtx) return bazelTargetsMap[dir] } // Helper method to trim quotes around strings. Loading
bp2build/build_conversion_test.go +16 −6 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) { for _, testCase := range testCases { config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) ctx.RegisterModuleType("custom", customModuleFactory) ctx.Register() Loading @@ -202,7 +203,8 @@ func TestGenerateSoongModuleTargets(t *testing.T) { _, errs = ctx.PrepareBuildActions(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, QueryView)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount) } Loading Loading @@ -245,6 +247,7 @@ func TestGenerateBazelTargetModules(t *testing.T) { for _, testCase := range testCases { config := android.TestConfig(buildDir, nil, testCase.bp, nil) ctx := android.NewTestContext(config) ctx.RegisterModuleType("custom", customModuleFactory) ctx.RegisterBp2BuildMutator("custom", customBp2BuildMutator) ctx.RegisterForBazelConversion() Loading @@ -258,7 +261,9 @@ func TestGenerateBazelTargetModules(t *testing.T) { continue } bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount) } else { Loading Loading @@ -415,7 +420,8 @@ load("//build/bazel/rules:rules.bzl", "my_library")`, _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount := len(bazelTargets); actualCount != testCase.expectedBazelTargetCount { t.Fatalf("Expected %d bazel target, got %d", testCase.expectedBazelTargetCount, actualCount) } Loading Loading @@ -904,7 +910,9 @@ genrule { if testCase.dir != "" { checkDir = testCase.dir } bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, checkDir) if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount) } else { Loading Loading @@ -1118,7 +1126,8 @@ genrule { _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount := len(bazelTargets); actualCount != 1 { t.Fatalf("%s: Expected 1 bazel target, got %d", testCase.description, actualCount) } Loading Loading @@ -1205,7 +1214,8 @@ func TestAllowlistingBp2buildTargets(t *testing.T) { _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, dir) if actualCount := len(bazelTargets); actualCount != testCase.expectedCount { t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount) } Loading
bp2build/cc_library_headers_conversion_test.go +2 −1 Original line number Diff line number Diff line Loading @@ -202,7 +202,8 @@ cc_library_headers { if testCase.dir != "" { checkDir = testCase.dir } bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[checkDir] codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build) bazelTargets := GenerateBazelTargetsForDir(codegenCtx, checkDir) if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount { t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount) } else { Loading