Merge "Add "updatable" property to ApexModule interface."
diff --git a/apex/apex.go b/apex/apex.go
index 1f9e1f3..3b17886 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -562,7 +562,6 @@
 		"libnativebridge_lazy",
 		"libnativeloader_lazy",
 		"libnativewindow_headers",
-		"libopus",
 		"libpdx_headers",
 		"libprocessgroup",
 		"libprocessgroup_headers",
diff --git a/cc/builder.go b/cc/builder.go
index b583586..d8e90b6 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -307,7 +307,7 @@
 	rsFlags       string
 	toolchain     config.Toolchain
 	tidy          bool
-	coverage      bool
+	gcovCoverage  bool
 	sAbiDump      bool
 	emitXrefs     bool
 
@@ -369,7 +369,7 @@
 		tidyFiles = make(android.Paths, 0, len(srcFiles))
 	}
 	var coverageFiles android.Paths
-	if flags.coverage {
+	if flags.gcovCoverage {
 		coverageFiles = make(android.Paths, 0, len(srcFiles))
 	}
 	var kytheFiles android.Paths
@@ -470,7 +470,7 @@
 
 		var ccCmd string
 		tidy := flags.tidy
-		coverage := flags.coverage
+		coverage := flags.gcovCoverage
 		dump := flags.sAbiDump
 		rule := cc
 		emitXref := flags.emitXrefs
diff --git a/cc/cc.go b/cc/cc.go
index fdfc221..24173ee 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -182,11 +182,11 @@
 	// These must be after any module include flags, which will be in CommonFlags.
 	SystemIncludeFlags []string
 
-	Toolchain config.Toolchain
-	Tidy      bool
-	Coverage  bool
-	SAbiDump  bool
-	EmitXrefs bool // If true, generate Ninja rules to generate emitXrefs input files for Kythe
+	Toolchain    config.Toolchain
+	Tidy         bool
+	GcovCoverage bool
+	SAbiDump     bool
+	EmitXrefs    bool // If true, generate Ninja rules to generate emitXrefs input files for Kythe
 
 	RequiredInstructionSet string
 	DynamicLinker          string
@@ -213,6 +213,9 @@
 	// two variants to be built, one for the platform and one for apps.
 	Sdk_version *string
 
+	// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+	Min_sdk_version *string
+
 	// If true, always create an sdk variant and don't create a platform variant.
 	Sdk_variant_only *bool
 
@@ -1906,8 +1909,7 @@
 	addSharedLibDependencies := func(depTag DependencyTag, name string, version string) {
 		var variations []blueprint.Variation
 		variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
-		versionVariantAvail := !c.InRecovery() && !c.InRamdisk()
-		if version != "" && versionVariantAvail {
+		if version != "" && VersionVariantAvailable(c) {
 			// Version is explicitly specified. i.e. libFoo#30
 			variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
 			depTag.ExplicitlyVersioned = true
@@ -1917,7 +1919,7 @@
 		// If the version is not specified, add dependency to all stubs libraries.
 		// The stubs library will be used when the depending module is built for APEX and
 		// the dependent module is not in the same APEX.
-		if version == "" && versionVariantAvail {
+		if version == "" && VersionVariantAvailable(c) {
 			for _, ver := range stubsVersionsFor(actx.Config())[name] {
 				// Note that depTag.ExplicitlyVersioned is false in this case.
 				actx.AddVariationDependencies([]blueprint.Variation{
@@ -2315,7 +2317,7 @@
 			}
 			if ccDep.CcLibrary() && !depIsStatic {
 				depIsStubs := ccDep.BuildStubs()
-				depHasStubs := ccDep.HasStubsVariants()
+				depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants()
 				depInSameApex := android.DirectlyInApex(c.ApexName(), depName)
 				depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
 
@@ -2331,8 +2333,8 @@
 					// If not building for APEX, use stubs only when it is from
 					// an APEX (and not from platform)
 					useThisDep = (depInPlatform != depIsStubs)
-					if c.InRamdisk() || c.InRecovery() || c.bootstrap() {
-						// However, for ramdisk, recovery or bootstrap modules,
+					if c.bootstrap() {
+						// However, for host, ramdisk, recovery or bootstrap modules,
 						// always link to non-stub variant
 						useThisDep = !depIsStubs
 					}
diff --git a/cc/coverage.go b/cc/coverage.go
index b94b628..bde07fd 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -82,10 +82,10 @@
 	}
 
 	if cov.Properties.CoverageEnabled {
-		flags.Coverage = true
 		cov.linkCoverage = true
 
 		if gcovCoverage {
+			flags.GcovCoverage = true
 			flags.Local.CommonFlags = append(flags.Local.CommonFlags, "--coverage", "-O0")
 
 			// Override -Wframe-larger-than and non-default optimization
diff --git a/cc/library.go b/cc/library.go
index 94fffb9..e79d9bd 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1528,10 +1528,18 @@
 	}
 }
 
-// Version mutator splits a module into the mandatory non-stubs variant
+func VersionVariantAvailable(module interface {
+	Host() bool
+	InRamdisk() bool
+	InRecovery() bool
+}) bool {
+	return !module.Host() && !module.InRamdisk() && !module.InRecovery()
+}
+
+// VersionMutator splits a module into the mandatory non-stubs variant
 // (which is unnamed) and zero or more stubs variants.
 func VersionMutator(mctx android.BottomUpMutatorContext) {
-	if library, ok := mctx.Module().(LinkableInterface); ok && !library.InRecovery() {
+	if library, ok := mctx.Module().(LinkableInterface); ok && VersionVariantAvailable(library) {
 		if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 {
 			versions := library.StubsVersions()
 			checkVersions(mctx, versions)
@@ -1567,7 +1575,7 @@
 	}
 	if genrule, ok := mctx.Module().(*genrule.Module); ok {
 		if _, ok := genrule.Extra.(*GenruleExtraProperties); ok {
-			if !genrule.InRecovery() {
+			if VersionVariantAvailable(genrule) {
 				mctx.CreateVariations("")
 				return
 			}
diff --git a/cc/linkable.go b/cc/linkable.go
index fbe61a4..4a70d48 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -39,6 +39,8 @@
 	Shared() bool
 	Toc() android.OptionalPath
 
+	Host() bool
+
 	InRamdisk() bool
 	OnlyInRamdisk() bool
 
diff --git a/cc/util.go b/cc/util.go
index 60070bb..af26268 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -82,7 +82,7 @@
 		tidyFlags:     strings.Join(in.TidyFlags, " "),
 		sAbiFlags:     strings.Join(in.SAbiFlags, " "),
 		toolchain:     in.Toolchain,
-		coverage:      in.Coverage,
+		gcovCoverage:  in.GcovCoverage,
 		tidy:          in.Tidy,
 		sAbiDump:      in.SAbiDump,
 		emitXrefs:     in.EmitXrefs,
diff --git a/java/androidmk.go b/java/androidmk.go
index bbf2c33..7d57525 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -588,14 +588,12 @@
 					fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:",
 						dstubs.checkLastReleasedApiTimestamp.String())
 
-					if dstubs.Name() != "android.car-system-stubs-docs" {
-						fmt.Fprintln(w, ".PHONY: checkapi")
-						fmt.Fprintln(w, "checkapi:",
-							dstubs.checkLastReleasedApiTimestamp.String())
+					fmt.Fprintln(w, ".PHONY: checkapi")
+					fmt.Fprintln(w, "checkapi:",
+						dstubs.checkLastReleasedApiTimestamp.String())
 
-						fmt.Fprintln(w, ".PHONY: droidcore")
-						fmt.Fprintln(w, "droidcore: checkapi")
-					}
+					fmt.Fprintln(w, ".PHONY: droidcore")
+					fmt.Fprintln(w, "droidcore: checkapi")
 				}
 				if dstubs.apiLintTimestamp != nil {
 					fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-api-lint")
diff --git a/java/builder.go b/java/builder.go
index 3a0247d..98f70cd 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -147,7 +147,12 @@
 
 	jarjar = pctx.AndroidStaticRule("jarjar",
 		blueprint.RuleParams{
-			Command:     "${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.JarjarCmd} process $rulesFile $in $out",
+			Command: "${config.JavaCmd} ${config.JavaVmFlags}" +
+				// b/146418363 Enable Android specific jarjar transformer to drop compat annotations
+				// for newly repackaged classes. Dropping @UnsupportedAppUsage on repackaged classes
+				// avoids adding new hiddenapis after jarjar'ing.
+				" -DremoveAndroidCompatAnnotations=true" +
+				" -jar ${config.JarjarCmd} process $rulesFile $in $out",
 			CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
 		},
 		"rulesFile")
diff --git a/java/droiddoc.go b/java/droiddoc.go
index e4582f6..8df3c2d 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -177,37 +177,15 @@
 	// filegroup or genrule can be included within this property.
 	Knowntags []string `android:"path"`
 
-	// the tag name used to distinguish if the API files belong to public/system/test.
-	Api_tag_name *string
-
 	// the generated public API filename by Doclava.
 	Api_filename *string
 
-	// the generated public Dex API filename by Doclava.
-	Dex_api_filename *string
-
-	// the generated private API filename by Doclava.
-	Private_api_filename *string
-
-	// the generated private Dex API filename by Doclava.
-	Private_dex_api_filename *string
-
 	// the generated removed API filename by Doclava.
 	Removed_api_filename *string
 
 	// the generated removed Dex API filename by Doclava.
 	Removed_dex_api_filename *string
 
-	// mapping of dex signatures to source file and line number. This is a temporary property and
-	// will be deleted; you probably shouldn't be using it.
-	Dex_mapping_filename *string
-
-	// the generated exact API filename by Doclava.
-	Exact_api_filename *string
-
-	// the generated proguard filename by Doclava.
-	Proguard_filename *string
-
 	// if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
 	Create_stubs *bool
 
@@ -229,37 +207,15 @@
 }
 
 type DroidstubsProperties struct {
-	// the tag name used to distinguish if the API files belong to public/system/test.
-	Api_tag_name *string
-
 	// the generated public API filename by Metalava.
 	Api_filename *string
 
-	// the generated public Dex API filename by Metalava.
-	Dex_api_filename *string
-
-	// the generated private API filename by Metalava.
-	Private_api_filename *string
-
-	// the generated private Dex API filename by Metalava.
-	Private_dex_api_filename *string
-
 	// the generated removed API filename by Metalava.
 	Removed_api_filename *string
 
 	// the generated removed Dex API filename by Metalava.
 	Removed_dex_api_filename *string
 
-	// mapping of dex signatures to source file and line number. This is a temporary property and
-	// will be deleted; you probably shouldn't be using it.
-	Dex_mapping_filename *string
-
-	// the generated exact API filename by Metalava.
-	Exact_api_filename *string
-
-	// the generated proguard filename by Metalava.
-	Proguard_filename *string
-
 	Check_api struct {
 		Last_released ApiToCheck
 
@@ -731,14 +687,9 @@
 
 	properties        DroiddocProperties
 	apiFile           android.WritablePath
-	dexApiFile        android.WritablePath
 	privateApiFile    android.WritablePath
-	privateDexApiFile android.WritablePath
 	removedApiFile    android.WritablePath
 	removedDexApiFile android.WritablePath
-	exactApiFile      android.WritablePath
-	apiMappingFile    android.WritablePath
-	proguardFile      android.WritablePath
 
 	checkCurrentApiTimestamp      android.WritablePath
 	updateCurrentApiTimestamp     android.WritablePath
@@ -876,41 +827,11 @@
 		cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
 	}
 
-	if String(d.properties.Private_api_filename) != "" {
-		d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
-		cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
-	}
-
-	if String(d.properties.Dex_api_filename) != "" {
-		d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
-		cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
-	}
-
-	if String(d.properties.Private_dex_api_filename) != "" {
-		d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
-		cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
-	}
-
 	if String(d.properties.Removed_dex_api_filename) != "" {
 		d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
 		cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
 	}
 
-	if String(d.properties.Exact_api_filename) != "" {
-		d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
-		cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
-	}
-
-	if String(d.properties.Dex_mapping_filename) != "" {
-		d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
-		cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
-	}
-
-	if String(d.properties.Proguard_filename) != "" {
-		d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
-		cmd.FlagWithOutput("-proguard ", d.proguardFile)
-	}
-
 	if BoolDefault(d.properties.Create_stubs, true) {
 		cmd.FlagWithArg("-stubs ", stubsDir.String())
 	}
@@ -1210,14 +1131,9 @@
 	apiFile                 android.WritablePath
 	apiXmlFile              android.WritablePath
 	lastReleasedApiXmlFile  android.WritablePath
-	dexApiFile              android.WritablePath
 	privateApiFile          android.WritablePath
-	privateDexApiFile       android.WritablePath
 	removedApiFile          android.WritablePath
 	removedDexApiFile       android.WritablePath
-	apiMappingFile          android.WritablePath
-	exactApiFile            android.WritablePath
-	proguardFile            android.WritablePath
 	nullabilityWarningsFile android.WritablePath
 
 	checkCurrentApiTimestamp      android.WritablePath
@@ -1322,41 +1238,11 @@
 		cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
 	}
 
-	if String(d.properties.Private_api_filename) != "" {
-		d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
-		cmd.FlagWithOutput("--private-api ", d.privateApiFile)
-	}
-
-	if String(d.properties.Dex_api_filename) != "" {
-		d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
-		cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
-	}
-
-	if String(d.properties.Private_dex_api_filename) != "" {
-		d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
-		cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
-	}
-
 	if String(d.properties.Removed_dex_api_filename) != "" {
 		d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
 		cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
 	}
 
-	if String(d.properties.Exact_api_filename) != "" {
-		d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
-		cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
-	}
-
-	if String(d.properties.Dex_mapping_filename) != "" {
-		d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
-		cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
-	}
-
-	if String(d.properties.Proguard_filename) != "" {
-		d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
-		cmd.FlagWithOutput("--proguard ", d.proguardFile)
-	}
-
 	if Bool(d.properties.Write_sdk_values) {
 		d.metadataDir = android.PathForModuleOut(ctx, "metadata")
 		cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
diff --git a/rust/config/global.go b/rust/config/global.go
index 690d83e..c0bd0f2 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
 var pctx = android.NewPackageContext("android/soong/rust/config")
 
 var (
-	RustDefaultVersion = "1.40.0"
+	RustDefaultVersion = "1.42.0"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2018"
 	Stdlibs            = []string{
diff --git a/rust/rust.go b/rust/rust.go
index 6fe8871..5cc8845 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -735,13 +735,14 @@
 
 	deps := mod.deps(ctx)
 	commonDepVariations := []blueprint.Variation{}
-	commonDepVariations = append(commonDepVariations,
-		blueprint.Variation{Mutator: "version", Variation: ""})
+	if cc.VersionVariantAvailable(mod) {
+		commonDepVariations = append(commonDepVariations,
+			blueprint.Variation{Mutator: "version", Variation: ""})
+	}
 	if !mod.Host() {
 		commonDepVariations = append(commonDepVariations,
 			blueprint.Variation{Mutator: "image", Variation: android.CoreVariation})
 	}
-
 	actx.AddVariationDependencies(
 		append(commonDepVariations, []blueprint.Variation{
 			{Mutator: "rust_libraries", Variation: "rlib"},
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index 79e40dd..fc91c3d 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -18,6 +18,7 @@
   art-module-test-exports
   conscrypt-module-sdk
   conscrypt-module-test-exports
+  conscrypt-module-host-exports
 )
 
 # We want to create apex modules for all supported architectures.
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index a2e35d9..0932873 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -151,6 +151,12 @@
 
 	// Whether public stub exists or not.
 	Public_stub *bool `blueprint:"mutated"`
+
+	Cpp struct {
+		// Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+		// Forwarded to cc_library.min_sdk_version
+		Min_sdk_version *string
+	}
 }
 
 var (
@@ -344,6 +350,7 @@
 	Vendor_available   *bool
 	Host_supported     *bool
 	Apex_available     []string
+	Min_sdk_version    *string
 }
 
 type javaLibraryProperties struct {
@@ -433,6 +440,7 @@
 	ccProps.Vendor_available = m.properties.Vendor_available
 	ccProps.Host_supported = m.properties.Host_supported
 	ccProps.Apex_available = m.ApexProperties.Apex_available
+	ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
 	ctx.CreateModule(cc.LibraryFactory, &ccProps)
 
 	scope := "internal"
diff --git a/ui/build/build.go b/ui/build/build.go
index f3feac2..1122733 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -53,7 +53,6 @@
 {{end -}}
 pool highmem_pool
  depth = {{.HighmemParallel}}
-build _kati_always_build_: phony
 {{if .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
 subninja {{.KatiPackageNinjaFile}}
 {{end -}}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index a3234e3..a559330 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -229,8 +229,6 @@
 		"DEFAULT_ERROR_BUILD_MODULE_TYPES",
 		"BUILD_BROKEN_PREBUILT_ELF_FILES",
 		"BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW",
-		"BUILD_BROKEN_USES_BUILD_AUX_EXECUTABLE",
-		"BUILD_BROKEN_USES_BUILD_AUX_STATIC_LIBRARY",
 		"BUILD_BROKEN_USES_BUILD_COPY_HEADERS",
 		"BUILD_BROKEN_USES_BUILD_EXECUTABLE",
 		"BUILD_BROKEN_USES_BUILD_FUZZ_TEST",
@@ -238,17 +236,12 @@
 		"BUILD_BROKEN_USES_BUILD_HOST_DALVIK_JAVA_LIBRARY",
 		"BUILD_BROKEN_USES_BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY",
 		"BUILD_BROKEN_USES_BUILD_HOST_EXECUTABLE",
-		"BUILD_BROKEN_USES_BUILD_HOST_FUZZ_TEST",
 		"BUILD_BROKEN_USES_BUILD_HOST_JAVA_LIBRARY",
-		"BUILD_BROKEN_USES_BUILD_HOST_NATIVE_TEST",
 		"BUILD_BROKEN_USES_BUILD_HOST_PREBUILT",
 		"BUILD_BROKEN_USES_BUILD_HOST_SHARED_LIBRARY",
 		"BUILD_BROKEN_USES_BUILD_HOST_STATIC_LIBRARY",
-		"BUILD_BROKEN_USES_BUILD_HOST_STATIC_TEST_LIBRARY",
-		"BUILD_BROKEN_USES_BUILD_HOST_TEST_CONFIG",
 		"BUILD_BROKEN_USES_BUILD_JAVA_LIBRARY",
 		"BUILD_BROKEN_USES_BUILD_MULTI_PREBUILT",
-		"BUILD_BROKEN_USES_BUILD_NATIVE_BENCHMARK",
 		"BUILD_BROKEN_USES_BUILD_NATIVE_TEST",
 		"BUILD_BROKEN_USES_BUILD_NOTICE_FILE",
 		"BUILD_BROKEN_USES_BUILD_PACKAGE",
@@ -258,8 +251,6 @@
 		"BUILD_BROKEN_USES_BUILD_SHARED_LIBRARY",
 		"BUILD_BROKEN_USES_BUILD_STATIC_JAVA_LIBRARY",
 		"BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
-		"BUILD_BROKEN_USES_BUILD_STATIC_TEST_LIBRARY",
-		"BUILD_BROKEN_USES_BUILD_TARGET_TEST_CONFIG",
 	}, exportEnvVars...), BannerVars...)
 
 	make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
diff --git a/ui/build/exec.go b/ui/build/exec.go
index e435c53..053bbae 100644
--- a/ui/build/exec.go
+++ b/ui/build/exec.go
@@ -19,6 +19,8 @@
 	"io"
 	"os/exec"
 	"strings"
+	"syscall"
+	"time"
 )
 
 // Cmd is a wrapper of os/exec.Cmd that integrates with the build context for
@@ -33,6 +35,8 @@
 	ctx    Context
 	config Config
 	name   string
+
+	started time.Time
 }
 
 func Command(ctx Context, config Config, name string, executable string, args ...string) *Cmd {
@@ -57,7 +61,20 @@
 		c.wrapSandbox()
 	}
 
-	c.ctx.Verboseln(c.Path, c.Args)
+	c.ctx.Verbosef("%q executing %q %v\n", c.name, c.Path, c.Args)
+	c.started = time.Now()
+}
+
+func (c *Cmd) report() {
+	if c.Cmd.ProcessState != nil {
+		rusage := c.Cmd.ProcessState.SysUsage().(*syscall.Rusage)
+		c.ctx.Verbosef("%q finished with exit code %d (%s real, %s user, %s system, %dMB maxrss)",
+			c.name, c.Cmd.ProcessState.ExitCode(),
+			time.Since(c.started).Round(time.Millisecond),
+			c.Cmd.ProcessState.UserTime().Round(time.Millisecond),
+			c.Cmd.ProcessState.SystemTime().Round(time.Millisecond),
+			rusage.Maxrss/1024)
+	}
 }
 
 func (c *Cmd) Start() error {
@@ -68,21 +85,30 @@
 func (c *Cmd) Run() error {
 	c.prepare()
 	err := c.Cmd.Run()
+	c.report()
 	return err
 }
 
 func (c *Cmd) Output() ([]byte, error) {
 	c.prepare()
 	bytes, err := c.Cmd.Output()
+	c.report()
 	return bytes, err
 }
 
 func (c *Cmd) CombinedOutput() ([]byte, error) {
 	c.prepare()
 	bytes, err := c.Cmd.CombinedOutput()
+	c.report()
 	return bytes, err
 }
 
+func (c *Cmd) Wait() error {
+	err := c.Cmd.Wait()
+	c.report()
+	return err
+}
+
 // StartOrFatal is equivalent to Start, but handles the error with a call to ctx.Fatal
 func (c *Cmd) StartOrFatal() {
 	if err := c.Start(); err != nil {
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 8796a4f..2eb7850 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -67,6 +67,7 @@
 		"--ninja_dir=" + config.OutDir(),
 		"--ninja_suffix=" + config.KatiSuffix() + extraSuffix,
 		"--no_ninja_prelude",
+		"--use_ninja_phony_output",
 		"--regen",
 		"--ignore_optional_include=" + filepath.Join(config.OutDir(), "%.P"),
 		"--detect_android_echo",
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index dfc3be1..1b13e5d 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -58,6 +58,7 @@
 	args = append(args, "-f", config.CombinedNinjaFile())
 
 	args = append(args,
+		"-o", "usesphonyoutputs=yes",
 		"-w", "dupbuild=err",
 		"-w", "missingdepfile=err")
 
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 9b8d648..2fbf381 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -119,7 +119,11 @@
 		cmd := Command(ctx, config, "soong "+name,
 			config.PrebuiltBuildTool("ninja"),
 			"-d", "keepdepfile",
+			"-o", "usesphonyoutputs=yes",
+			"-o", "preremoveoutputs=yes",
 			"-w", "dupbuild=err",
+			"-w", "outputdir=err",
+			"-w", "missingoutfile=err",
 			"-j", strconv.Itoa(config.Parallel()),
 			"--frontend_file", fifo,
 			"-f", filepath.Join(config.SoongOutDir(), file))
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index 5109465..4ff9483 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -50,10 +50,10 @@
 	// Get a list of leaf nodes in the dependency graph from ninja
 	executable := config.PrebuiltBuildTool("ninja")
 
-	args := []string{}
-	args = append(args, config.NinjaArgs()...)
-	args = append(args, "-f", config.CombinedNinjaFile())
-	args = append(args, "-t", "targets", "rule")
+	common_args := []string{}
+	common_args = append(common_args, config.NinjaArgs()...)
+	common_args = append(common_args, "-f", config.CombinedNinjaFile())
+	args := append(common_args, "-t", "targets", "rule")
 
 	cmd := Command(ctx, config, "ninja", executable, args...)
 	stdout, err := cmd.StdoutPipe()
@@ -96,9 +96,31 @@
 		sb := &strings.Builder{}
 		title := "Dependencies in out found with no rule to create them:"
 		fmt.Fprintln(sb, title)
-		for _, dep := range danglingRulesList {
-			fmt.Fprintln(sb, "  ", dep)
+
+		report_lines := 1
+		for i, dep := range danglingRulesList {
+			if report_lines > 20 {
+				fmt.Fprintf(sb, "  ... and %d more\n", len(danglingRulesList)-i)
+				break
+			}
+			// It's helpful to see the reverse dependencies. ninja -t query is the
+			// best tool we got for that. Its output starts with the dependency
+			// itself.
+			query_cmd := Command(ctx, config, "ninja", executable,
+				append(common_args, "-t", "query", dep)...)
+			query_stdout, err := query_cmd.StdoutPipe()
+			if err != nil {
+				ctx.Fatal(err)
+			}
+			query_cmd.StartOrFatal()
+			scanner := bufio.NewScanner(query_stdout)
+			for scanner.Scan() {
+				report_lines++
+				fmt.Fprintln(sb, " ", scanner.Text())
+			}
+			query_cmd.WaitOrFatal()
 		}
+
 		ts.FinishAction(status.ActionResult{
 			Action: action,
 			Error:  fmt.Errorf(title),