Add PRODUCT_SOONG_ONLY

Setting this product variable will cause the product to be built
with only soong (no kati) by default.

This is what we will enable to launch soong-only builds, but will
also be needed to test atest in soong-only builds, as atest won't
pass --soong-only when it runs soong.

Bug: 376727180
Test: manually
Change-Id: Ie6148ffecdc1e0a46821136b2f4601d757b3d7ad
diff --git a/ui/build/build.go b/ui/build/build.go
index e0c9e6d..ea86782 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -33,17 +33,6 @@
 	ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
 	ensureEmptyDirectoriesExist(ctx, config.TempDir())
 
-	// Potentially write a marker file for whether kati is enabled. This is used by soong_build to
-	// potentially run the AndroidMk singleton and postinstall commands.
-	// Note that the absence of the  file does not not preclude running Kati for product
-	// configuration purposes.
-	katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
-	if config.SkipKati() || config.SkipKatiNinja() {
-		os.Remove(katiEnabledMarker)
-	} else {
-		ensureEmptyFileExists(ctx, katiEnabledMarker)
-	}
-
 	// The ninja_build file is used by our buildbots to understand that the output
 	// can be parsed as ninja output.
 	ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
@@ -98,6 +87,21 @@
 	writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
 }
 
+// SetupKatiEnabledMarker creates or delets a file that tells soong_build if we're running with
+// kati.
+func SetupKatiEnabledMarker(ctx Context, config Config) {
+	// Potentially write a marker file for whether kati is enabled. This is used by soong_build to
+	// potentially run the AndroidMk singleton and postinstall commands.
+	// Note that the absence of the file does not preclude running Kati for product
+	// configuration purposes.
+	katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
+	if config.SkipKati() || config.SkipKatiNinja() {
+		os.Remove(katiEnabledMarker)
+	} else {
+		ensureEmptyFileExists(ctx, katiEnabledMarker)
+	}
+}
+
 var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
 builddir = {{.OutDir}}
 {{if .UseRemoteBuild }}pool local_pool
@@ -327,10 +331,16 @@
 
 	if what&RunProductConfig != 0 {
 		runMakeProductConfig(ctx, config)
+
+		// Re-evaluate what to run because there are product variables that control how
+		// soong and make are run.
+		what = evaluateWhatToRun(config, ctx.Verboseln)
 	}
 
 	// Everything below here depends on product config.
 
+	SetupKatiEnabledMarker(ctx, config)
+
 	if inList("installclean", config.Arguments()) ||
 		inList("install-clean", config.Arguments()) {
 		logArgsOtherThan("installclean", "install-clean")
diff --git a/ui/build/config.go b/ui/build/config.go
index 5c2debb..8b73f9f 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -77,26 +77,27 @@
 	logsPrefix    string
 
 	// From the arguments
-	parallel                 int
-	keepGoing                int
-	verbose                  bool
-	checkbuild               bool
-	dist                     bool
-	jsonModuleGraph          bool
-	reportMkMetrics          bool // Collect and report mk2bp migration progress metrics.
-	soongDocs                bool
-	skipConfig               bool
-	skipKati                 bool
-	skipKatiNinja            bool
-	skipSoong                bool
-	skipNinja                bool
-	skipSoongTests           bool
-	searchApiDir             bool // Scan the Android.bp files generated in out/api_surfaces
-	skipMetricsUpload        bool
-	buildStartedTime         int64 // For metrics-upload-only - manually specify a build-started time
-	buildFromSourceStub      bool
-	incrementalBuildActions  bool
-	ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built
+	parallel                  int
+	keepGoing                 int
+	verbose                   bool
+	checkbuild                bool
+	dist                      bool
+	jsonModuleGraph           bool
+	reportMkMetrics           bool // Collect and report mk2bp migration progress metrics.
+	soongDocs                 bool
+	skipConfig                bool
+	skipKati                  bool
+	skipKatiControlledByFlags bool
+	skipKatiNinja             bool
+	skipSoong                 bool
+	skipNinja                 bool
+	skipSoongTests            bool
+	searchApiDir              bool // Scan the Android.bp files generated in out/api_surfaces
+	skipMetricsUpload         bool
+	buildStartedTime          int64 // For metrics-upload-only - manually specify a build-started time
+	buildFromSourceStub       bool
+	incrementalBuildActions   bool
+	ensureAllowlistIntegrity  bool // For CI builds - make sure modules are mixed-built
 
 	// From the product config
 	katiArgs        []string
@@ -844,8 +845,19 @@
 		} else if arg == "--skip-ninja" {
 			c.skipNinja = true
 		} else if arg == "--soong-only" {
+			if c.skipKatiControlledByFlags {
+				ctx.Fatalf("Cannot specify both --soong-only and --no-soong-only")
+			}
+			c.skipKatiControlledByFlags = true
 			c.skipKati = true
 			c.skipKatiNinja = true
+		} else if arg == "--no-soong-only" {
+			if c.skipKatiControlledByFlags {
+				ctx.Fatalf("Cannot specify both --soong-only and --no-soong-only")
+			}
+			c.skipKatiControlledByFlags = true
+			c.skipKati = false
+			c.skipKatiNinja = false
 		} else if arg == "--config-only" {
 			c.skipKati = true
 			c.skipKatiNinja = true
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index b592f11..d5aab54 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -246,6 +246,8 @@
 		// `true` will relegate missing outputs to warnings.
 		"BUILD_BROKEN_MISSING_OUTPUTS",
 
+		"PRODUCT_SOONG_ONLY",
+
 		// Not used, but useful to be in the soong.log
 		"TARGET_BUILD_TYPE",
 		"HOST_ARCH",
@@ -314,4 +316,11 @@
 	config.SetBuildBrokenNinjaUsesEnvVars(strings.Fields(makeVars["BUILD_BROKEN_NINJA_USES_ENV_VARS"]))
 	config.SetSourceRootDirs(strings.Fields(makeVars["PRODUCT_SOURCE_ROOT_DIRS"]))
 	config.SetBuildBrokenMissingOutputs(makeVars["BUILD_BROKEN_MISSING_OUTPUTS"] == "true")
+
+	if !config.skipKatiControlledByFlags {
+		if makeVars["PRODUCT_SOONG_ONLY"] == "true" {
+			config.skipKati = true
+			config.skipKatiNinja = true
+		}
+	}
 }