From 33832f96e0101a1a6c36c5fb15ec854e132af445 Mon Sep 17 00:00:00 2001 From: Jingwen Chen Date: Sun, 24 Jan 2021 22:55:54 -0500 Subject: [PATCH] bp2build: introduce CodegenMode. The CodegenMode enum helps to differentiate between bp2build and queryview modes of generating BUILD files from the Soong module graph. bp2build is used for generating BUILD files from an unconfigured Soong module graph for Soong->Bazel conversion, whereas QueryView is a front-end for querying the existing Soong configured module graph with Bazel query. Test: go test Test: TH Change-Id: I5709f591f1ae08b2770adf272d8ce60c9ee1f46a --- bp2build/bp2build.go | 4 ++-- bp2build/build_conversion.go | 31 +++++++++++++++++++++++++++---- bp2build/build_conversion_test.go | 6 +++--- bp2build/bzl_conversion_test.go | 2 +- bp2build/conversion.go | 10 +++++----- bp2build/conversion_test.go | 4 ++-- cmd/soong_build/main.go | 2 +- cmd/soong_build/queryview.go | 4 ++-- 8 files changed, 43 insertions(+), 20 deletions(-) diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go index 75b60977a..a414f04b4 100644 --- a/bp2build/bp2build.go +++ b/bp2build/bp2build.go @@ -28,9 +28,9 @@ func Codegen(ctx CodegenContext) { ruleShims := CreateRuleShims(android.ModuleTypeFactories()) - buildToTargets := GenerateSoongModuleTargets(ctx.Context(), true) + buildToTargets := GenerateSoongModuleTargets(ctx.Context(), ctx.mode) - filesToWrite := CreateBazelFiles(ruleShims, buildToTargets, true) + filesToWrite := CreateBazelFiles(ruleShims, buildToTargets, ctx.mode) for _, f := range filesToWrite { if err := writeFile(outputDir, ctx, f); err != nil { fmt.Errorf("Failed to write %q (dir %q) due to %q", f.Basename, f.Dir, err) diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go index da2fb7f89..8284ae39d 100644 --- a/bp2build/build_conversion.go +++ b/bp2build/build_conversion.go @@ -46,18 +46,38 @@ type bpToBuildContext interface { type CodegenContext struct { config android.Config context android.Context + mode CodegenMode } +// CodegenMode is an enum to differentiate code-generation modes. +type CodegenMode int + +const ( + // Bp2Build: generate BUILD files with targets buildable by Bazel directly. + // + // This mode is used for the Soong->Bazel build definition conversion. + Bp2Build CodegenMode = iota + + // QueryView: generate BUILD files with targets representing fully mutated + // Soong modules, representing the fully configured Soong module graph with + // variants and dependency endges. + // + // This mode is used for discovering and introspecting the existing Soong + // module graph. + QueryView +) + func (ctx CodegenContext) AddNinjaFileDeps(...string) {} func (ctx CodegenContext) Config() android.Config { return ctx.config } func (ctx CodegenContext) Context() android.Context { return ctx.context } // NewCodegenContext creates a wrapper context that conforms to PathContext for // writing BUILD files in the output directory. -func NewCodegenContext(config android.Config, context android.Context) CodegenContext { +func NewCodegenContext(config android.Config, context android.Context, mode CodegenMode) CodegenContext { return CodegenContext{ context: context, config: config, + mode: mode, } } @@ -73,19 +93,22 @@ func propsToAttributes(props map[string]string) string { return attributes } -func GenerateSoongModuleTargets(ctx bpToBuildContext, bp2buildEnabled bool) map[string][]BazelTarget { +func GenerateSoongModuleTargets(ctx bpToBuildContext, codegenMode CodegenMode) map[string][]BazelTarget { buildFileToTargets := make(map[string][]BazelTarget) ctx.VisitAllModules(func(m blueprint.Module) { dir := ctx.ModuleDir(m) var t BazelTarget - if bp2buildEnabled { + switch codegenMode { + case Bp2Build: if _, ok := m.(android.BazelTargetModule); !ok { return } t = generateBazelTarget(ctx, m) - } else { + case QueryView: t = generateSoongModuleTarget(ctx, m) + default: + panic(fmt.Errorf("Unknown code-generation mode: %s", codegenMode)) } buildFileToTargets[ctx.ModuleDir(m)] = append(buildFileToTargets[dir], t) diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go index 7fbd257e4..be325304c 100644 --- a/bp2build/build_conversion_test.go +++ b/bp2build/build_conversion_test.go @@ -201,7 +201,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) { _, errs = ctx.PrepareBuildActions(config) android.FailIfErrored(t, errs) - bazelTargets := GenerateSoongModuleTargets(ctx.Context.Context, false)[dir] + bazelTargets := GenerateSoongModuleTargets(ctx.Context.Context, QueryView)[dir] if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount) } @@ -252,7 +252,7 @@ func TestGenerateBazelTargetModules(t *testing.T) { _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) - bazelTargets := GenerateSoongModuleTargets(ctx.Context.Context, true)[dir] + bazelTargets := GenerateSoongModuleTargets(ctx.Context.Context, Bp2Build)[dir] if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount) } @@ -365,7 +365,7 @@ func TestModuleTypeBp2Build(t *testing.T) { _, errs = ctx.ResolveDependencies(config) android.FailIfErrored(t, errs) - bazelTargets := GenerateSoongModuleTargets(ctx.Context.Context, true)[dir] + bazelTargets := GenerateSoongModuleTargets(ctx.Context.Context, Bp2Build)[dir] if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount) } diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go index c1e660eb6..8cdee655c 100644 --- a/bp2build/bzl_conversion_test.go +++ b/bp2build/bzl_conversion_test.go @@ -172,7 +172,7 @@ func TestGenerateSoongModuleBzl(t *testing.T) { content: "irrelevant", }, } - files := CreateBazelFiles(ruleShims, make(map[string][]BazelTarget), false) + files := CreateBazelFiles(ruleShims, make(map[string][]BazelTarget), QueryView) var actualSoongModuleBzl BazelFile for _, f := range files { diff --git a/bp2build/conversion.go b/bp2build/conversion.go index cccc47400..2025ef706 100644 --- a/bp2build/conversion.go +++ b/bp2build/conversion.go @@ -18,7 +18,7 @@ type BazelFile struct { func CreateBazelFiles( ruleShims map[string]RuleShim, buildToTargets map[string][]BazelTarget, - bp2buildEnabled bool) []BazelFile { + mode CodegenMode) []BazelFile { files := make([]BazelFile, 0, len(ruleShims)+len(buildToTargets)+numAdditionalFiles) // Write top level files: WORKSPACE and BUILD. These files are empty. @@ -28,7 +28,7 @@ func CreateBazelFiles( files = append(files, newFile(bazelRulesSubDir, "BUILD", "")) - if !bp2buildEnabled { + if mode == QueryView { // These files are only used for queryview. files = append(files, newFile(bazelRulesSubDir, "providers.bzl", providersBzl)) @@ -38,16 +38,16 @@ func CreateBazelFiles( files = append(files, newFile(bazelRulesSubDir, "soong_module.bzl", generateSoongModuleBzl(ruleShims))) } - files = append(files, createBuildFiles(buildToTargets, bp2buildEnabled)...) + files = append(files, createBuildFiles(buildToTargets, mode)...) return files } -func createBuildFiles(buildToTargets map[string][]BazelTarget, bp2buildEnabled bool) []BazelFile { +func createBuildFiles(buildToTargets map[string][]BazelTarget, mode CodegenMode) []BazelFile { files := make([]BazelFile, 0, len(buildToTargets)) for _, dir := range android.SortedStringKeys(buildToTargets) { content := soongModuleLoad - if bp2buildEnabled { + if mode == Bp2Build { // No need to load soong_module for bp2build BUILD files. content = "" } diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go index b40aa1b25..7f75b14f7 100644 --- a/bp2build/conversion_test.go +++ b/bp2build/conversion_test.go @@ -55,7 +55,7 @@ func sortFiles(files []BazelFile) { } func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) { - files := CreateBazelFiles(map[string]RuleShim{}, map[string][]BazelTarget{}, false) + files := CreateBazelFiles(map[string]RuleShim{}, map[string][]BazelTarget{}, QueryView) expectedFilePaths := []filepath{ { dir: "", @@ -85,7 +85,7 @@ func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) { } func TestCreateBazelFiles_Bp2Build_AddsTopLevelFiles(t *testing.T) { - files := CreateBazelFiles(map[string]RuleShim{}, map[string][]BazelTarget{}, true) + files := CreateBazelFiles(map[string]RuleShim{}, map[string][]BazelTarget{}, Bp2Build) expectedFilePaths := []filepath{ { dir: "", diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index 1d5e7b3af..8cd4f974b 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -170,7 +170,7 @@ func runBp2Build(configuration android.Config, extraNinjaDeps []string) { bp2buildCtx.SetNameInterface(newNameResolver(configuration)) bootstrap.Main(bp2buildCtx.Context, configuration, extraNinjaDeps...) - codegenContext := bp2build.NewCodegenContext(configuration, *bp2buildCtx) + codegenContext := bp2build.NewCodegenContext(configuration, *bp2buildCtx, bp2build.Bp2Build) bp2build.Codegen(codegenContext) } diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go index 305a22440..5d61d0c5e 100644 --- a/cmd/soong_build/queryview.go +++ b/cmd/soong_build/queryview.go @@ -24,9 +24,9 @@ import ( func createBazelQueryView(ctx *android.Context, bazelQueryViewDir string) error { ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories()) - buildToTargets := bp2build.GenerateSoongModuleTargets(*ctx, false) + buildToTargets := bp2build.GenerateSoongModuleTargets(*ctx, bp2build.QueryView) - filesToWrite := bp2build.CreateBazelFiles(ruleShims, buildToTargets, false) + filesToWrite := bp2build.CreateBazelFiles(ruleShims, buildToTargets, bp2build.QueryView) for _, f := range filesToWrite { if err := writeReadOnlyFile(bazelQueryViewDir, f); err != nil { return err