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
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 8cd4f97..9dcb5f3 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -19,6 +19,7 @@
 	"fmt"
 	"os"
 	"path/filepath"
+	"strings"
 
 	"github.com/google/blueprint/bootstrap"
 
@@ -166,12 +167,43 @@
 	// 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