From eb76c4319d5aa9981cef24f8a645d89729c5aa92 Mon Sep 17 00:00:00 2001 From: Jingwen Chen Date: Thu, 28 Jan 2021 08:22:12 -0500 Subject: [PATCH] bp2build: fix running from clean checkout. bp2build is a Soong mode that returns as soon as the BUILD files are generated. This causes it not generate the build.ninja file, which the Ninja process executing soong_build itself expects to produce as an output. If there isn't an existing build.ninja file generated from a previous build, GENERATE_BAZEL_FILES=true m nothing will fail. This CL generates the expected files as a workaround, and also makes GENERATE_BAZEL_FILES=true skip the Kati/Ninja steps in soong_ui since they aren't needed. Test: rm -rf out/ && GENERATE_BAZEL_FILES=true m nothing && m libc Fixes: 178683777 Change-Id: I2515ef7961682d2be5f096ed24831cc185165a67 --- cmd/soong_build/main.go | 32 ++++++++++++++++++++++++++++++++ ui/build/build.go | 5 +++++ ui/build/soong.go | 14 +++++++++++--- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index 8cd4f974b..9dcb5f330 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -19,6 +19,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/google/blueprint/bootstrap" @@ -166,12 +167,43 @@ func runBp2Build(configuration android.Config, extraNinjaDeps []string) { // conversion for Bazel conversion. bp2buildCtx := android.NewContext(configuration) bp2buildCtx.RegisterForBazelConversion() + + // No need to generate Ninja build rules/statements from Modules and Singletons. configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions) bp2buildCtx.SetNameInterface(newNameResolver(configuration)) + + // Run the loading and analysis pipeline. bootstrap.Main(bp2buildCtx.Context, configuration, extraNinjaDeps...) + // Run the code-generation phase to convert BazelTargetModules to BUILD files. codegenContext := bp2build.NewCodegenContext(configuration, *bp2buildCtx, bp2build.Bp2Build) bp2build.Codegen(codegenContext) + + // Workarounds to support running bp2build in a clean AOSP checkout with no + // prior builds, and exiting early as soon as the BUILD files get generated, + // therefore not creating build.ninja files that soong_ui and callers of + // soong_build expects. + // + // These files are: build.ninja and build.ninja.d. Since Kati hasn't been + // ran as well, and `nothing` is defined in a .mk file, there isn't a ninja + // target called `nothing`, so we manually create it here. + // + // Even though outFile (build.ninja) and depFile (build.ninja.d) are values + // passed into bootstrap.Main, they are package-private fields in bootstrap. + // Short of modifying Blueprint to add an exported getter, inlining them + // here is the next-best practical option. + ninjaFileName := "build.ninja" + ninjaFile := android.PathForOutput(codegenContext, ninjaFileName) + ninjaFileD := android.PathForOutput(codegenContext, ninjaFileName+".d") + extraNinjaDepsString := strings.Join(extraNinjaDeps, " \\\n ") + // A workaround to create the 'nothing' ninja target so `m nothing` works, + // since bp2build runs without Kati, and the 'nothing' target is declared in + // a Makefile. + android.WriteFileToOutputDir(ninjaFile, []byte("build nothing: phony\n phony_output = true\n"), 0666) + android.WriteFileToOutputDir( + ninjaFileD, + []byte(fmt.Sprintf("%s: \\\n %s\n", ninjaFileName, extraNinjaDepsString)), + 0666) } // shouldPrepareBuildActions reads configuration and flags if build actions diff --git a/ui/build/build.go b/ui/build/build.go index 926da3137..215a6c8ce 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -252,6 +252,11 @@ func Build(ctx Context, config Config, what int) { if what&BuildSoong != 0 { // Run Soong runSoong(ctx, config) + + if config.Environment().IsEnvTrue("GENERATE_BAZEL_FILES") { + // Return early, if we're using Soong as the bp2build converter. + return + } } if what&BuildKati != 0 { diff --git a/ui/build/soong.go b/ui/build/soong.go index 6a9367259..899ab5da5 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -169,8 +169,11 @@ func runSoong(ctx Context, config Config) { // This build generates /build.ninja, which is used later by build/soong/ui/build/build.go#Build(). ninja("bootstrap", ".bootstrap/build.ninja") - soongBuildMetrics := loadSoongBuildMetrics(ctx, config) - logSoongBuildMetrics(ctx, soongBuildMetrics) + var soongBuildMetrics *soong_metrics_proto.SoongBuildMetrics + if shouldCollectBuildSoongMetrics(config) { + soongBuildMetrics := loadSoongBuildMetrics(ctx, config) + logSoongBuildMetrics(ctx, soongBuildMetrics) + } distGzipFile(ctx, config, config.SoongNinjaFile(), "soong") @@ -179,11 +182,16 @@ func runSoong(ctx Context, config Config) { distGzipFile(ctx, config, config.SoongMakeVarsMk(), "soong") } - if ctx.Metrics != nil { + if shouldCollectBuildSoongMetrics(config) && ctx.Metrics != nil { ctx.Metrics.SetSoongBuildMetrics(soongBuildMetrics) } } +func shouldCollectBuildSoongMetrics(config Config) bool { + // Do not collect metrics protobuf if the soong_build binary ran as the bp2build converter. + return config.Environment().IsFalse("GENERATE_BAZEL_FILES") +} + func loadSoongBuildMetrics(ctx Context, config Config) *soong_metrics_proto.SoongBuildMetrics { soongBuildMetricsFile := filepath.Join(config.OutDir(), "soong", "soong_build_metrics.pb") buf, err := ioutil.ReadFile(soongBuildMetricsFile)