Invoke soong_docs from the bootstrap Ninja file.

This makes soong_ui the only place where soong_build is invoked, thus
greatly simplifying the conceptual model of the build.

It comes with the slight limitation that now soong_docs (and queryview
and the JSON module graph) are not Make targets anymore, but I suppose
that's an acceptable loss.

The only place where someone depended on soong_docs from a Makefile is
removed in a separate change.

Test: Presubmits.
Change-Id: I3f9ac327725c15d84de725d05e3cdde1da3dcbe2
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 26afd43..ed3af18 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -143,6 +143,7 @@
 	bootstrapGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.ninja")
 	bp2buildGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.bp2build.ninja")
 	queryviewGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.queryview.ninja")
+	soongDocsGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.soong_docs.ninja")
 	moduleGraphGlobFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build-globs.modulegraph.ninja")
 
 	// The glob .ninja files are subninja'd. However, they are generated during
@@ -151,6 +152,7 @@
 	writeEmptyGlobFile(ctx, bootstrapGlobFile)
 	writeEmptyGlobFile(ctx, bp2buildGlobFile)
 	writeEmptyGlobFile(ctx, queryviewGlobFile)
+	writeEmptyGlobFile(ctx, soongDocsGlobFile)
 	writeEmptyGlobFile(ctx, moduleGraphGlobFile)
 
 	bootstrapDepFile := shared.JoinPath(config.SoongOutDir(), ".bootstrap/build.ninja.d")
@@ -164,7 +166,7 @@
 	// The primary builder (aka soong_build) will use bootstrapGlobFile as the globFile to generate build.ninja(.d)
 	// Building soong_build does not require a glob file
 	// Using "" instead of "<soong_build_glob>.ninja" will ensure that an unused glob file is not written to out/soong/.bootstrap during StagePrimary
-	args.Subninjas = []string{bootstrapGlobFile, bp2buildGlobFile, moduleGraphGlobFile, queryviewGlobFile}
+	args.Subninjas = []string{bootstrapGlobFile, bp2buildGlobFile, moduleGraphGlobFile, queryviewGlobFile, soongDocsGlobFile}
 	args.EmptyNinjaFile = config.EmptyNinjaFile()
 
 	args.DelveListen = os.Getenv("SOONG_DELVE")
@@ -226,6 +228,22 @@
 		Args:    queryviewArgs,
 	}
 
+	soongDocsArgs := []string{
+		"--soong_docs", config.SoongDocsHtml(),
+		"--globListDir", "soong_docs",
+		"--globFile", soongDocsGlobFile,
+	}
+
+	soongDocsArgs = append(soongDocsArgs, commonArgs...)
+	soongDocsArgs = append(soongDocsArgs, environmentArgs(config, ".soong_docs")...)
+	soongDocsArgs = append(soongDocsArgs, "Android.bp")
+
+	soongDocsInvocation := bootstrap.PrimaryBuilderInvocation{
+		Inputs:  []string{"Android.bp"},
+		Outputs: []string{config.SoongDocsHtml()},
+		Args:    soongDocsArgs,
+	}
+
 	moduleGraphArgs := []string{
 		"--module_graph_file", config.ModuleGraphFile(),
 		"--globListDir", "modulegraph",
@@ -247,6 +265,7 @@
 		mainSoongBuildInvocation,
 		moduleGraphInvocation,
 		queryviewInvocation,
+		soongDocsInvocation,
 	}
 
 	blueprintCtx := blueprint.NewContext()
@@ -386,6 +405,10 @@
 		targets = append(targets, config.QueryviewMarkerFile())
 	}
 
+	if config.SoongDocs() {
+		targets = append(targets, config.SoongDocsHtml())
+	}
+
 	if config.SoongBuildInvocationNeeded() {
 		// This build generates <builddir>/build.ninja, which is used later by build/soong/ui/build/build.go#Build().
 		targets = append(targets, config.MainNinjaFile())