Merge changes Iefcf4fbe,I450d4769,I1ffc7e7b

* changes:
  Prepend default to allow overriding in the bp file.
  Do not follow SDK member dependencies for APEX payloads.
  Do not follow prebuiltDependencyTags in APEX payload walks.
diff --git a/android/config.go b/android/config.go
index 6f73a12..7073a49 100644
--- a/android/config.go
+++ b/android/config.go
@@ -93,8 +93,9 @@
 
 	deviceConfig *deviceConfig
 
-	srcDir   string // the path of the root source directory
-	buildDir string // the path of the build output directory
+	srcDir         string // the path of the root source directory
+	buildDir       string // the path of the build output directory
+	moduleListFile string // the path to the file which lists blueprint files to parse.
 
 	env       map[string]string
 	envLock   sync.Mutex
@@ -316,7 +317,7 @@
 
 // New creates a new Config object.  The srcDir argument specifies the path to
 // the root source directory. It also loads the config file, if found.
-func NewConfig(srcDir, buildDir string) (Config, error) {
+func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) {
 	// Make a config with default options
 	config := &config{
 		ConfigFileName:           filepath.Join(buildDir, configFileName),
@@ -328,7 +329,8 @@
 		buildDir:          buildDir,
 		multilibConflicts: make(map[ArchType]bool),
 
-		fs: pathtools.NewOsFs(absSrcDir),
+		moduleListFile: moduleListFile,
+		fs:             pathtools.NewOsFs(absSrcDir),
 	}
 
 	config.deviceConfig = &deviceConfig{
diff --git a/android/module.go b/android/module.go
index 06079ca..f80f37e 100644
--- a/android/module.go
+++ b/android/module.go
@@ -228,6 +228,16 @@
 	// For more information, see Module.GenerateBuildActions within Blueprint's module_ctx.go
 	GenerateAndroidBuildActions(ModuleContext)
 
+	// Add dependencies to the components of a module, i.e. modules that are created
+	// by the module and which are considered to be part of the creating module.
+	//
+	// This is called before prebuilts are renamed so as to allow a dependency to be
+	// added directly to a prebuilt child module instead of depending on a source module
+	// and relying on prebuilt processing to switch to the prebuilt module if preferred.
+	//
+	// A dependency on a prebuilt must include the "prebuilt_" prefix.
+	ComponentDepsMutator(ctx BottomUpMutatorContext)
+
 	DepsMutator(BottomUpMutatorContext)
 
 	base() *ModuleBase
@@ -769,6 +779,8 @@
 	prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
 }
 
+func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {}
+
 func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
 
 func (m *ModuleBase) AddProperties(props ...interface{}) {
@@ -2099,15 +2111,6 @@
 	m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
 }
 
-func findStringInSlice(str string, slice []string) int {
-	for i, s := range slice {
-		if s == str {
-			return i
-		}
-	}
-	return -1
-}
-
 // SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
 // was not a module reference.
 func SrcIsModule(s string) (module string) {
diff --git a/android/mutator.go b/android/mutator.go
index 77d5f43..b70c4ff 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -115,6 +115,18 @@
 	// a DefaultableHook.
 	RegisterDefaultsPreArchMutators,
 
+	// Add dependencies on any components so that any component references can be
+	// resolved within the deps mutator.
+	//
+	// Must be run after defaults so it can be used to create dependencies on the
+	// component modules that are creating in a DefaultableHook.
+	//
+	// Must be run before RegisterPrebuiltsPreArchMutators, i.e. before prebuilts are
+	// renamed. That is so that if a module creates components using a prebuilt module
+	// type that any dependencies (which must use prebuilt_ prefixes) are resolved to
+	// the prebuilt module and not the source module.
+	RegisterComponentsMutator,
+
 	// Create an association between prebuilt modules and their corresponding source
 	// modules (if any).
 	//
@@ -202,6 +214,7 @@
 	AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
 	AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
 	ReplaceDependencies(string)
+	ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
 	AliasVariation(variationName string)
 }
 
@@ -252,8 +265,21 @@
 	return mutator
 }
 
+func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
+	ctx.BottomUp("component-deps", componentDepsMutator).Parallel()
+}
+
+// A special mutator that runs just prior to the deps mutator to allow the dependencies
+// on component modules to be added so that they can depend directly on a prebuilt
+// module.
+func componentDepsMutator(ctx BottomUpMutatorContext) {
+	if m := ctx.Module(); m.Enabled() {
+		m.ComponentDepsMutator(ctx)
+	}
+}
+
 func depsMutator(ctx BottomUpMutatorContext) {
-	if m, ok := ctx.Module().(Module); ok && m.Enabled() {
+	if m := ctx.Module(); m.Enabled() {
 		m.DepsMutator(ctx)
 	}
 }
@@ -403,6 +429,10 @@
 	b.bp.ReplaceDependencies(name)
 }
 
+func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) {
+	b.bp.ReplaceDependenciesIf(name, predicate)
+}
+
 func (b *bottomUpMutatorContext) AliasVariation(variationName string) {
 	b.bp.AliasVariation(variationName)
 }
diff --git a/android/paths.go b/android/paths.go
index d8d51a7..d13b6d8 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -380,6 +380,18 @@
 }
 
 func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (Paths, error) {
+	excludePaths := func(paths Paths) Paths {
+		if len(expandedExcludes) == 0 {
+			return paths
+		}
+		remainder := make(Paths, 0, len(paths))
+		for _, p := range paths {
+			if !InList(p.String(), expandedExcludes) {
+				remainder = append(remainder, p)
+			}
+		}
+		return remainder
+	}
 	if m, t := SrcIsModuleWithTag(s); m != "" {
 		module := ctx.GetDirectDepWithTag(m, sourceOrOutputDepTag(t))
 		if module == nil {
@@ -390,20 +402,11 @@
 			if err != nil {
 				return nil, fmt.Errorf("path dependency %q: %s", s, err)
 			}
-			return outputFiles, nil
+			return excludePaths(outputFiles), nil
 		} else if t != "" {
 			return nil, fmt.Errorf("path dependency %q is not an output file producing module", s)
 		} else if srcProducer, ok := module.(SourceFileProducer); ok {
-			moduleSrcs := srcProducer.Srcs()
-			for _, e := range expandedExcludes {
-				for j := 0; j < len(moduleSrcs); j++ {
-					if moduleSrcs[j].String() == e {
-						moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
-						j--
-					}
-				}
-			}
-			return moduleSrcs, nil
+			return excludePaths(srcProducer.Srcs()), nil
 		} else {
 			return nil, fmt.Errorf("path dependency %q is not a source file producing module", s)
 		}
@@ -418,8 +421,7 @@
 			reportPathErrorf(ctx, "module source path %q does not exist", p)
 		}
 
-		j := findStringInSlice(p.String(), expandedExcludes)
-		if j >= 0 {
+		if InList(p.String(), expandedExcludes) {
 			return nil, nil
 		}
 		return Paths{p}, nil
@@ -913,6 +915,22 @@
 var _ Path = OutputPath{}
 var _ WritablePath = OutputPath{}
 
+// toolDepPath is a Path representing a dependency of the build tool.
+type toolDepPath struct {
+	basePath
+}
+
+var _ Path = toolDepPath{}
+
+// pathForBuildToolDep returns a toolDepPath representing the given path string.
+// There is no validation for the path, as it is "trusted": It may fail
+// normal validation checks. For example, it may be an absolute path.
+// Only use this function to construct paths for dependencies of the build
+// tool invocation.
+func pathForBuildToolDep(ctx PathContext, path string) toolDepPath {
+	return toolDepPath{basePath{path, ctx.Config(), ""}}
+}
+
 // PathForOutput joins the provided paths and returns an OutputPath that is
 // validated to not escape the build dir.
 // On error, it will return a usable, but invalid OutputPath, and report a ModuleError.
diff --git a/android/paths_test.go b/android/paths_test.go
index 9b45d3f..a9cd22b 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -1091,6 +1091,21 @@
 			rels: []string{"gen/c"},
 		},
 		{
+			name: "output file provider with exclude",
+			bp: `
+			test {
+				name: "foo",
+				srcs: [":b", ":c"],
+				exclude_srcs: [":c"]
+			}
+			output_file_provider {
+				name: "c",
+				outs: ["gen/c"],
+			}`,
+			srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
+			rels: []string{"gen/b"},
+		},
+		{
 			name: "special characters glob",
 			bp: `
 			test {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index a29ec91..9f4df28 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -30,6 +30,16 @@
 	ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
 }
 
+// Marks a dependency tag as possibly preventing a reference to a source from being
+// replaced with the prebuilt.
+type ReplaceSourceWithPrebuilt interface {
+	blueprint.DependencyTag
+
+	// Return true if the dependency defined by this tag should be replaced with the
+	// prebuilt.
+	ReplaceSourceWithPrebuilt() bool
+}
+
 type prebuiltDependencyTag struct {
 	blueprint.BaseDependencyTag
 }
@@ -260,7 +270,13 @@
 		name := m.base().BaseModuleName()
 		if p.properties.UsePrebuilt {
 			if p.properties.SourceExists {
-				ctx.ReplaceDependencies(name)
+				ctx.ReplaceDependenciesIf(name, func(from blueprint.Module, tag blueprint.DependencyTag, to blueprint.Module) bool {
+					if t, ok := tag.(ReplaceSourceWithPrebuilt); ok {
+						return t.ReplaceSourceWithPrebuilt()
+					}
+
+					return true
+				})
 			}
 		} else {
 			m.SkipInstall()
diff --git a/android/writedocs.go b/android/writedocs.go
index 9e43e80..4eb15e6 100644
--- a/android/writedocs.go
+++ b/android/writedocs.go
@@ -44,6 +44,10 @@
 }
 
 func (c *docsSingleton) GenerateBuildActions(ctx SingletonContext) {
+	var deps Paths
+	deps = append(deps, pathForBuildToolDep(ctx, ctx.Config().moduleListFile))
+	deps = append(deps, pathForBuildToolDep(ctx, ctx.Config().ProductVariablesFileName))
+
 	// Generate build system docs for the primary builder.  Generating docs reads the source
 	// files used to build the primary builder, but that dependency will be picked up through
 	// the dependency on the primary builder itself.  There are no dependencies on the
@@ -63,6 +67,7 @@
 	ctx.Build(pctx, BuildParams{
 		Rule:   soongDocs,
 		Output: docsFile,
+		Inputs: deps,
 		Args: map[string]string{
 			"outDir": PathForOutput(ctx, "docs").String(),
 		},
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 6613ab5..f064338 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -233,6 +233,7 @@
 	ctx.RegisterModuleType("apex_set", apexSetFactory)
 
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+	ctx.PreArchMutators(android.RegisterComponentsMutator)
 	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
 
 	cc.RegisterRequiredBuildComponentsForTest(ctx)
diff --git a/cc/cc.go b/cc/cc.go
index e52adaf..0d5b6bd 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -96,6 +96,9 @@
 	HeaderLibs                                  []string
 	RuntimeLibs                                 []string
 
+	// Used for data dependencies adjacent to tests
+	DataLibs []string
+
 	StaticUnwinderIfLegacy bool
 
 	ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
@@ -423,6 +426,7 @@
 }
 
 var (
+	dataLibDepTag         = DependencyTag{Name: "data_lib", Library: true, Shared: true}
 	sharedExportDepTag    = DependencyTag{Name: "shared", Library: true, Shared: true, ReexportFlags: true}
 	earlySharedDepTag     = DependencyTag{Name: "early_shared", Library: true, Shared: true}
 	lateSharedDepTag      = DependencyTag{Name: "late shared", Library: true, Shared: true}
@@ -1982,6 +1986,10 @@
 
 	actx.AddVariationDependencies([]blueprint.Variation{
 		{Mutator: "link", Variation: "shared"},
+	}, dataLibDepTag, deps.DataLibs...)
+
+	actx.AddVariationDependencies([]blueprint.Variation{
+		{Mutator: "link", Variation: "shared"},
 	}, runtimeDepTag, deps.RuntimeLibs...)
 
 	actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index f73e021..8a1c8ed 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -526,6 +526,56 @@
 	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"})
 }
 
+func TestDataLibs(t *testing.T) {
+	bp := `
+		cc_test_library {
+			name: "test_lib",
+			srcs: ["test_lib.cpp"],
+			gtest: false,
+		}
+
+		cc_test {
+			name: "main_test",
+			data_libs: ["test_lib"],
+			gtest: false,
+		}
+  `
+
+	config := TestConfig(buildDir, android.Android, nil, bp, nil)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
+
+	ctx := testCcWithConfig(t, config)
+	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
+	testBinary := module.(*Module).linker.(*testBinary)
+	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
+	if err != nil {
+		t.Errorf("Expected cc_test to produce output files, error: %s", err)
+		return
+	}
+	if len(outputFiles) != 1 {
+		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
+		return
+	}
+	if len(testBinary.dataPaths()) != 1 {
+		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
+		return
+	}
+
+	outputPath := outputFiles[0].String()
+	testBinaryPath := testBinary.dataPaths()[0].String()
+
+	if !strings.HasSuffix(outputPath, "/main_test") {
+		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
+		return
+	}
+	if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
+		t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
+		return
+	}
+}
+
 func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
 	ctx := testCcNoVndk(t, `
 		cc_library {
diff --git a/cc/ccdeps.go b/cc/ccdeps.go
index 225405c..b96d8b0 100644
--- a/cc/ccdeps.go
+++ b/cc/ccdeps.go
@@ -38,8 +38,11 @@
 }
 
 type ccdepsGeneratorSingleton struct {
+	outputPath android.Path
 }
 
+var _ android.SingletonMakeVarsProvider = (*ccdepsGeneratorSingleton)(nil)
+
 const (
 	// Environment variables used to control the behavior of this singleton.
 	envVariableCollectCCDeps = "SOONG_COLLECT_CC_DEPS"
@@ -110,6 +113,21 @@
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
+	c.outputPath = ccfpath
+
+	// This is necessary to satisfy the dangling rules check as this file is written by Soong rather than a rule.
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   android.Touch,
+		Output: ccfpath,
+	})
+}
+
+func (c *ccdepsGeneratorSingleton) MakeVars(ctx android.MakeVarsContext) {
+	if c.outputPath == nil {
+		return
+	}
+
+	ctx.DistForGoal("general-tests", c.outputPath)
 }
 
 func parseCompilerCCParameters(ctx android.SingletonContext, params []string) ccParameters {
diff --git a/cc/config/global.go b/cc/config/global.go
index 7b651bc..373fc77 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -32,6 +32,7 @@
 		"-Wno-unused",
 		"-Winit-self",
 		"-Wpointer-arith",
+		"-Wunreachable-code-loop-increment",
 
 		// Make paths in deps files relative
 		"-no-canonical-prefixes",
@@ -51,6 +52,7 @@
 		"-Werror=date-time",
 		"-Werror=pragma-pack",
 		"-Werror=pragma-pack-suspicious-include",
+		"-Werror=unreachable-code-loop-increment",
 	}
 
 	commonGlobalConlyflags = []string{}
diff --git a/cc/test.go b/cc/test.go
index 09da976..37afb0c 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -58,6 +58,9 @@
 	// the test
 	Data []string `android:"path,arch_variant"`
 
+	// list of shared library modules that should be installed alongside the test
+	Data_libs []string `android:"arch_variant"`
+
 	// list of compatibility suites (for example "cts", "vts") that the module should be
 	// installed into.
 	Test_suites []string `android:"arch_variant"`
@@ -325,6 +328,7 @@
 func (test *testBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
 	deps = test.testDecorator.linkerDeps(ctx, deps)
 	deps = test.binaryDecorator.linkerDeps(ctx, deps)
+	deps.DataLibs = append(deps.DataLibs, test.Properties.Data_libs...)
 	return deps
 }
 
@@ -336,6 +340,21 @@
 
 func (test *testBinary) install(ctx ModuleContext, file android.Path) {
 	test.data = android.PathsForModuleSrc(ctx, test.Properties.Data)
+
+	ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
+		depName := ctx.OtherModuleName(dep)
+		ccDep, ok := dep.(LinkableInterface)
+
+		if !ok {
+			ctx.ModuleErrorf("data_lib %q is not a linkable cc module", depName)
+		}
+		if ccDep.OutputFile().Valid() {
+			test.data = append(test.data, ccDep.OutputFile().Path())
+		} else {
+			ctx.ModuleErrorf("data_lib %q has no output file", depName)
+		}
+	})
+
 	var api_level_prop string
 	var configs []tradefed.Config
 	var min_level string
@@ -507,6 +526,7 @@
 
 func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) {
 	benchmark.data = android.PathsForModuleSrc(ctx, benchmark.Properties.Data)
+
 	var configs []tradefed.Config
 	if Bool(benchmark.Properties.Require_root) {
 		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
diff --git a/cc/testing.go b/cc/testing.go
index b0c3c162..a106d46 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -500,6 +500,7 @@
 	ctx := android.NewTestArchContext()
 	ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
 	ctx.RegisterModuleType("cc_test", TestFactory)
+	ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
 	ctx.RegisterModuleType("llndk_headers", llndkHeadersFactory)
 	ctx.RegisterModuleType("vendor_public_library", vendorPublicLibraryFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 905f206..532d9e4 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -59,7 +59,7 @@
 	ctx := android.NewContext()
 	ctx.Register()
 
-	configuration, err := android.NewConfig(srcDir, bootstrap.BuildDir)
+	configuration, err := android.NewConfig(srcDir, bootstrap.BuildDir, bootstrap.ModuleListFile)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "%s", err)
 		os.Exit(1)
diff --git a/cmd/soong_build/writedocs.go b/cmd/soong_build/writedocs.go
index 9424b6c..c136846 100644
--- a/cmd/soong_build/writedocs.go
+++ b/cmd/soong_build/writedocs.go
@@ -44,7 +44,7 @@
 	"name":             0,
 	"src":              1,
 	"srcs":             2,
-	"defautls":         3,
+	"defaults":         3,
 	"host_supported":   4,
 	"device_supported": 5,
 }
diff --git a/docs/perf.md b/docs/perf.md
index 538adff..86a27b4 100644
--- a/docs/perf.md
+++ b/docs/perf.md
@@ -12,6 +12,41 @@
 
 ![trace example](./trace_example.png)
 
+### Critical path
+
+soong_ui logs the wall time of the longest dependency chain compared to the
+elapsed wall time in `$OUT_DIR/soong.log`.  For example:
+```
+critical path took 3m10s
+elapsed time 5m16s
+perfect parallelism ratio 60%
+critical path:
+    0:00 build out/target/product/generic_arm64/obj/FAKE/sepolicy_neverallows_intermediates/policy_2.conf
+    0:04 build out/target/product/generic_arm64/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows
+    0:13 build out/target/product/generic_arm64/obj/ETC/plat_sepolicy.cil_intermediates/plat_sepolicy.cil
+    0:01 build out/target/product/generic_arm64/obj/ETC/plat_pub_versioned.cil_intermediates/plat_pub_versioned.cil
+    0:02 build out/target/product/generic_arm64/obj/ETC/vendor_sepolicy.cil_intermediates/vendor_sepolicy.cil
+    0:16 build out/target/product/generic_arm64/obj/ETC/sepolicy_intermediates/sepolicy
+    0:00 build out/target/product/generic_arm64/obj/ETC/plat_seapp_contexts_intermediates/plat_seapp_contexts
+    0:00 Install: out/target/product/generic_arm64/system/etc/selinux/plat_seapp_contexts
+    0:02 build out/target/product/generic_arm64/obj/NOTICE.txt
+    0:00 build out/target/product/generic_arm64/obj/NOTICE.xml.gz
+    0:00 build out/target/product/generic_arm64/system/etc/NOTICE.xml.gz
+    0:01 Installed file list: out/target/product/generic_arm64/installed-files.txt
+    1:00 Target system fs image: out/target/product/generic_arm64/obj/PACKAGING/systemimage_intermediates/system.img
+    0:01 Install system fs image: out/target/product/generic_arm64/system.img
+    0:01 Target vbmeta image: out/target/product/generic_arm64/vbmeta.img
+    1:26 Package target files: out/target/product/generic_arm64/obj/PACKAGING/target_files_intermediates/aosp_arm64-target_files-6663974.zip
+    0:01 Package: out/target/product/generic_arm64/aosp_arm64-img-6663974.zip
+    0:01 Dist: /buildbot/dist_dirs/aosp-master-linux-aosp_arm64-userdebug/6663974/aosp_arm64-img-6663974.zip
+```
+
+If the elapsed time is much longer than the critical path then additional
+parallelism on the build machine will improve total build times.  If there are
+long individual times listed in the critical path then improving build times
+for those steps or adjusting dependencies so that those steps can run earlier
+in the build graph will improve total build times.
+
 ### Soong
 
 Soong can be traced and profiled using the standard Go tools. It understands
diff --git a/finder/finder.go b/finder/finder.go
index f20bed2..6513fa3 100644
--- a/finder/finder.go
+++ b/finder/finder.go
@@ -325,7 +325,12 @@
 // Shutdown declares that the finder is no longer needed and waits for its cleanup to complete
 // Currently, that only entails waiting for the database dump to complete.
 func (f *Finder) Shutdown() {
-	f.waitForDbDump()
+	f.WaitForDbDump()
+}
+
+// WaitForDbDump returns once the database has been written to f.DbPath.
+func (f *Finder) WaitForDbDump() {
+	f.shutdownWaitgroup.Wait()
 }
 
 // End of public api
@@ -345,10 +350,6 @@
 	}
 }
 
-func (f *Finder) waitForDbDump() {
-	f.shutdownWaitgroup.Wait()
-}
-
 // joinCleanPaths is like filepath.Join but is faster because
 // joinCleanPaths doesn't have to support paths ending in "/" or containing ".."
 func joinCleanPaths(base string, leaf string) string {
diff --git a/java/java.go b/java/java.go
index 0d46672..46ef98b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -140,10 +140,15 @@
 // Findbugs
 
 type CompilerProperties struct {
-	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
+	// list of source files used to compile the Java module.  May be .java, .kt, .logtags, .proto,
 	// or .aidl files.
 	Srcs []string `android:"path,arch_variant"`
 
+	// list Kotlin of source files containing Kotlin code that should be treated as common code in
+	// a codebase that supports Kotlin multiplatform.  See
+	// https://kotlinlang.org/docs/reference/multiplatform.html.  May be only be .kt files.
+	Common_srcs []string `android:"path,arch_variant"`
+
 	// list of source files that should not be used to build the Java module.
 	// This is most useful in the arch/multilib variants to remove non-common files
 	Exclude_srcs []string `android:"path,arch_variant"`
@@ -1300,6 +1305,11 @@
 		flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
 	}
 
+	kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil)
+	if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 {
+		ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files")
+	}
+
 	srcFiles = j.genSources(ctx, srcFiles, flags)
 
 	srcJars := srcFiles.FilterByExt(".srcjar")
@@ -1353,6 +1363,7 @@
 
 		// Collect .kt files for AIDEGen
 		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...)
+		j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...)
 
 		flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
 		flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)
@@ -1364,7 +1375,7 @@
 			// Use kapt for annotation processing
 			kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
 			kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
-			kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, srcJars, flags)
+			kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
 			srcJars = append(srcJars, kaptSrcJar)
 			kotlinJars = append(kotlinJars, kaptResJar)
 			// Disable annotation processing in javac, it's already been handled by kapt
@@ -1373,7 +1384,7 @@
 		}
 
 		kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
-		kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, srcJars, flags)
+		kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
 		if ctx.Failed() {
 			return
 		}
diff --git a/java/java_test.go b/java/java_test.go
index def42db..59a2ce7 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -86,6 +86,7 @@
 	RegisterStubsBuildComponents(ctx)
 	RegisterSdkLibraryBuildComponents(ctx)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+	ctx.PreArchMutators(android.RegisterComponentsMutator)
 
 	RegisterPrebuiltApisBuildComponents(ctx)
 
@@ -684,11 +685,11 @@
 	})
 
 	checkModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{
+		`prebuilt_sdklib.stubs`,
 		`sdklib.impl`,
 		// This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the
 		// dependency is added after prebuilts may have been renamed and so has to use
 		// the renamed name.
-		`sdklib.stubs`,
 		`sdklib.xml`,
 	})
 }
@@ -717,9 +718,8 @@
 	checkModuleDependencies(t, ctx, "sdklib", "android_common", []string{
 		`dex2oatd`,
 		`prebuilt_sdklib`,
-		// This should be sdklib.stubs but is switched to the prebuilt because it is preferred.
-		`prebuilt_sdklib.stubs`,
 		`sdklib.impl`,
+		`sdklib.stubs`,
 		`sdklib.stubs.source`,
 		`sdklib.xml`,
 	})
diff --git a/java/jdeps.go b/java/jdeps.go
index 9f43887..2b5ee74 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -34,8 +34,11 @@
 }
 
 type jdepsGeneratorSingleton struct {
+	outputPath android.Path
 }
 
+var _ android.SingletonMakeVarsProvider = (*jdepsGeneratorSingleton)(nil)
+
 const (
 	// Environment variables used to modify behavior of this singleton.
 	envVariableCollectJavaDeps = "SOONG_COLLECT_JAVA_DEPS"
@@ -97,6 +100,21 @@
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
+	j.outputPath = jfpath
+
+	// This is necessary to satisfy the dangling rules check as this file is written by Soong rather than a rule.
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   android.Touch,
+		Output: jfpath,
+	})
+}
+
+func (j *jdepsGeneratorSingleton) MakeVars(ctx android.MakeVarsContext) {
+	if j.outputPath == nil {
+		return
+	}
+
+	ctx.DistForGoal("general-tests", j.outputPath)
 }
 
 func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
diff --git a/java/kotlin.go b/java/kotlin.go
index e3356be..e8c030a 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -33,7 +33,7 @@
 			`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
 			`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
 			` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
-			` --out "$kotlinBuildFile" && ` +
+			` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
 			`${config.KotlincCmd} ${config.JavacHeapFlags} $kotlincFlags ` +
 			`-jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile -kotlin-home $emptyDir && ` +
 			`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir && ` +
@@ -54,21 +54,43 @@
 		Rspfile:        "$out.rsp",
 		RspfileContent: `$in`,
 	},
-	"kotlincFlags", "classpath", "srcJars", "srcJarDir", "classesDir", "kotlinJvmTarget", "kotlinBuildFile",
-	"emptyDir", "name")
+	"kotlincFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "classesDir",
+	"kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name")
+
+func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Paths) android.OptionalPath {
+	if len(commonSrcFiles) > 0 {
+		// The list of common_srcs may be too long to put on the command line, but
+		// we can't use the rsp file because it is already being used for srcs.
+		// Insert a second rule to write out the list of resources to a file.
+		commonSrcsList := android.PathForModuleOut(ctx, "kotlinc_common_srcs.list")
+		rule := android.NewRuleBuilder()
+		rule.Command().Text("cp").FlagWithRspFileInputList("", commonSrcFiles).Output(commonSrcsList)
+		rule.Build(pctx, ctx, "kotlin_common_srcs_list", "kotlin common_srcs list")
+		return android.OptionalPathForPath(commonSrcsList)
+	}
+	return android.OptionalPath{}
+}
 
 // kotlinCompile takes .java and .kt sources and srcJars, and compiles the .kt sources into a classes jar in outputFile.
 func kotlinCompile(ctx android.ModuleContext, outputFile android.WritablePath,
-	srcFiles, srcJars android.Paths,
+	srcFiles, commonSrcFiles, srcJars android.Paths,
 	flags javaBuilderFlags) {
 
 	var deps android.Paths
 	deps = append(deps, flags.kotlincClasspath...)
 	deps = append(deps, srcJars...)
+	deps = append(deps, commonSrcFiles...)
 
 	kotlinName := filepath.Join(ctx.ModuleDir(), ctx.ModuleSubDir(), ctx.ModuleName())
 	kotlinName = strings.ReplaceAll(kotlinName, "/", "__")
 
+	commonSrcsList := kotlinCommonSrcsList(ctx, commonSrcFiles)
+	commonSrcFilesArg := ""
+	if commonSrcsList.Valid() {
+		deps = append(deps, commonSrcsList.Path())
+		commonSrcFilesArg = "--common_srcs " + commonSrcsList.String()
+	}
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        kotlinc,
 		Description: "kotlinc",
@@ -76,13 +98,14 @@
 		Inputs:      srcFiles,
 		Implicits:   deps,
 		Args: map[string]string{
-			"classpath":       flags.kotlincClasspath.FormJavaClassPath(""),
-			"kotlincFlags":    flags.kotlincFlags,
-			"srcJars":         strings.Join(srcJars.Strings(), " "),
-			"classesDir":      android.PathForModuleOut(ctx, "kotlinc", "classes").String(),
-			"srcJarDir":       android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(),
-			"kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(),
-			"emptyDir":        android.PathForModuleOut(ctx, "kotlinc", "empty").String(),
+			"classpath":         flags.kotlincClasspath.FormJavaClassPath(""),
+			"kotlincFlags":      flags.kotlincFlags,
+			"commonSrcFilesArg": commonSrcFilesArg,
+			"srcJars":           strings.Join(srcJars.Strings(), " "),
+			"classesDir":        android.PathForModuleOut(ctx, "kotlinc", "classes").String(),
+			"srcJarDir":         android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(),
+			"kotlinBuildFile":   android.PathForModuleOut(ctx, "kotlinc-build.xml").String(),
+			"emptyDir":          android.PathForModuleOut(ctx, "kotlinc", "empty").String(),
 			// http://b/69160377 kotlinc only supports -jvm-target 1.6 and 1.8
 			"kotlinJvmTarget": "1.8",
 			"name":            kotlinName,
@@ -97,7 +120,7 @@
 			`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
 			`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
 			` --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
-			` --out "$kotlinBuildFile" && ` +
+			` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
 			`${config.KotlincCmd} ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} $kotlincFlags ` +
 			`-Xplugin=${config.KotlinKaptJar} ` +
 			`-P plugin:org.jetbrains.kotlin.kapt3:sources=$kaptDir/sources ` +
@@ -124,21 +147,31 @@
 		RspfileContent: `$in`,
 	},
 	"kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "kaptProcessor",
-	"classpath", "srcJars", "srcJarDir", "kaptDir", "kotlinJvmTarget", "kotlinBuildFile", "name",
-	"classesJarOut")
+	"classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "kaptDir", "kotlinJvmTarget",
+	"kotlinBuildFile", "name", "classesJarOut")
 
 // kotlinKapt performs Kotlin-compatible annotation processing.  It takes .kt and .java sources and srcjars, and runs
 // annotation processors over all of them, producing a srcjar of generated code in outputFile.  The srcjar should be
 // added as an additional input to kotlinc and javac rules, and the javac rule should have annotation processing
 // disabled.
 func kotlinKapt(ctx android.ModuleContext, srcJarOutputFile, resJarOutputFile android.WritablePath,
-	srcFiles, srcJars android.Paths,
+	srcFiles, commonSrcFiles, srcJars android.Paths,
 	flags javaBuilderFlags) {
 
+	srcFiles = append(android.Paths(nil), srcFiles...)
+
 	var deps android.Paths
 	deps = append(deps, flags.kotlincClasspath...)
 	deps = append(deps, srcJars...)
 	deps = append(deps, flags.processorPath...)
+	deps = append(deps, commonSrcFiles...)
+
+	commonSrcsList := kotlinCommonSrcsList(ctx, commonSrcFiles)
+	commonSrcFilesArg := ""
+	if commonSrcsList.Valid() {
+		deps = append(deps, commonSrcsList.Path())
+		commonSrcFilesArg = "--common_srcs " + commonSrcsList.String()
+	}
 
 	kaptProcessorPath := flags.processorPath.FormRepeatedClassPath("-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=")
 
@@ -168,6 +201,7 @@
 		Args: map[string]string{
 			"classpath":         flags.kotlincClasspath.FormJavaClassPath(""),
 			"kotlincFlags":      flags.kotlincFlags,
+			"commonSrcFilesArg": commonSrcFilesArg,
 			"srcJars":           strings.Join(srcJars.Strings(), " "),
 			"srcJarDir":         android.PathForModuleOut(ctx, "kapt", "srcJars").String(),
 			"kotlinBuildFile":   android.PathForModuleOut(ctx, "kapt", "build.xml").String(),
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 8f8f8ce..a5aa328 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -70,6 +70,12 @@
 	}
 }
 
+var _ android.ReplaceSourceWithPrebuilt = (*scopeDependencyTag)(nil)
+
+func (tag scopeDependencyTag) ReplaceSourceWithPrebuilt() bool {
+	return false
+}
+
 // Provides information about an api scope, e.g. public, system, test.
 type apiScope struct {
 	// The name of the api scope, e.g. public, system, test
@@ -973,7 +979,8 @@
 
 var implLibraryTag = sdkLibraryComponentTag{name: "impl-library"}
 
-func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+// Add the dependencies on the child modules in the component deps mutator.
+func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
 	for _, apiScope := range module.getGeneratedApiScopes(ctx) {
 		// Add dependencies to the stubs library
 		ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
@@ -998,7 +1005,12 @@
 			// Add dependency to the rule for generating the xml permissions file
 			ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlPermissionsModuleName())
 		}
+	}
+}
 
+// Add other dependencies as normal.
+func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+	if module.requiresRuntimeImplementationLibrary() {
 		// Only add the deps for the library if it is actually going to be built.
 		module.Library.deps(ctx)
 	}
@@ -1874,20 +1886,26 @@
 	props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
 }
 
-func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
+// Add the dependencies on the child module in the component deps mutator so that it
+// creates references to the prebuilt and not the source modules.
+func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
 	for apiScope, scopeProperties := range module.scopeProperties {
 		if len(scopeProperties.Jars) == 0 {
 			continue
 		}
 
 		// Add dependencies to the prebuilt stubs library
-		ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
+		ctx.AddVariationDependencies(nil, apiScope.stubsTag, "prebuilt_"+module.stubsLibraryModuleName(apiScope))
 
 		if len(scopeProperties.Stub_srcs) > 0 {
 			// Add dependencies to the prebuilt stubs source library
-			ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
+			ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, "prebuilt_"+module.stubsSourceModuleName(apiScope))
 		}
 	}
+}
+
+// Add other dependencies as normal.
+func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
 
 	implName := module.implLibraryModuleName()
 	if ctx.OtherModuleExists(implName) {
diff --git a/sdk/testing.go b/sdk/testing.go
index 0fc6baa..4d029e4 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -85,6 +85,7 @@
 	android.RegisterPackageBuildComponents(ctx)
 	ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+	ctx.PreArchMutators(android.RegisterComponentsMutator)
 	ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
 	ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
 
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 6786337..c019ea2 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -126,6 +126,11 @@
 	if err != nil {
 		ctx.Fatalf("Could not find modules: %v", err)
 	}
+
+	if config.Dist() {
+		f.WaitForDbDump()
+		distFile(ctx, config, f.DbPath, "module_paths")
+	}
 }
 
 func dumpListToFile(ctx Context, config Config, list []string, filePath string) (err error) {
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index 4ff9483..83b3807 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -66,6 +66,8 @@
 	outDir := config.OutDir()
 	bootstrapDir := filepath.Join(outDir, "soong", ".bootstrap")
 	miniBootstrapDir := filepath.Join(outDir, "soong", ".minibootstrap")
+	modulePathsDir := filepath.Join(outDir, ".module_paths")
+	variablesFilePath := filepath.Join(outDir, "soong", "soong.variables")
 
 	danglingRules := make(map[string]bool)
 
@@ -76,7 +78,10 @@
 			// Leaf node is not in the out directory.
 			continue
 		}
-		if strings.HasPrefix(line, bootstrapDir) || strings.HasPrefix(line, miniBootstrapDir) {
+		if strings.HasPrefix(line, bootstrapDir) ||
+			strings.HasPrefix(line, miniBootstrapDir) ||
+			strings.HasPrefix(line, modulePathsDir) ||
+			line == variablesFilePath {
 			// Leaf node is in one of Soong's bootstrap directories, which do not have
 			// full build rules in the primary build.ninja file.
 			continue