Merge changes I4efdf333,I4abaf8e7

* changes:
  Ensure hermetic device rust_bindgen.
  Generate deps file for rust_bindgen modules.
diff --git a/android/androidmk.go b/android/androidmk.go
index 94b4b81..7e86140 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -126,6 +126,26 @@
 	}
 }
 
+func (a *AndroidMkEntries) SetPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.entryOrder = append(a.entryOrder, name)
+	}
+	a.EntryMap[name] = paths.Strings()
+}
+
+func (a *AndroidMkEntries) SetOptionalPaths(name string, paths Paths) {
+	if len(paths) > 0 {
+		a.SetPaths(name, paths)
+	}
+}
+
+func (a *AndroidMkEntries) AddPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.entryOrder = append(a.entryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
+}
+
 func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
 	if flag {
 		if _, ok := a.EntryMap[name]; !ok {
diff --git a/android/apex.go b/android/apex.go
index 47f07ca..a7570dc 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -65,9 +65,9 @@
 
 	apexModuleBase() *ApexModuleBase
 
-	// Marks that this module should be built for the specified APEXes.
+	// Marks that this module should be built for the specified APEX.
 	// Call this before apex.apexMutator is run.
-	BuildForApexes(apexes []ApexInfo)
+	BuildForApex(apex ApexInfo)
 
 	// Returns the APEXes that this module will be built for
 	ApexVariations() []ApexInfo
@@ -96,7 +96,7 @@
 	IsInstallableToApex() bool
 
 	// Mutate this module into one or more variants each of which is built
-	// for an APEX marked via BuildForApexes().
+	// for an APEX marked via BuildForApex().
 	CreateApexVariations(mctx BottomUpMutatorContext) []Module
 
 	// Tests if this module is available for the specified APEX or ":platform"
@@ -178,18 +178,15 @@
 	return nil
 }
 
-func (m *ApexModuleBase) BuildForApexes(apexes []ApexInfo) {
+func (m *ApexModuleBase) BuildForApex(apex ApexInfo) {
 	m.apexVariationsLock.Lock()
 	defer m.apexVariationsLock.Unlock()
-nextApex:
-	for _, apex := range apexes {
-		for _, v := range m.apexVariations {
-			if v.ApexName == apex.ApexName {
-				continue nextApex
-			}
+	for _, v := range m.apexVariations {
+		if v.ApexName == apex.ApexName {
+			return
 		}
-		m.apexVariations = append(m.apexVariations, apex)
 	}
+	m.apexVariations = append(m.apexVariations, apex)
 }
 
 func (m *ApexModuleBase) ApexVariations() []ApexInfo {
@@ -327,17 +324,15 @@
 // depended on by the specified APEXes. Directly depending means that a module
 // is explicitly listed in the build definition of the APEX via properties like
 // native_shared_libs, java_libs, etc.
-func UpdateApexDependency(apexes []ApexInfo, moduleName string, directDep bool) {
+func UpdateApexDependency(apex ApexInfo, moduleName string, directDep bool) {
 	apexNamesMapMutex.Lock()
 	defer apexNamesMapMutex.Unlock()
-	for _, apex := range apexes {
-		apexesForModule, ok := apexNamesMap()[moduleName]
-		if !ok {
-			apexesForModule = make(map[string]bool)
-			apexNamesMap()[moduleName] = apexesForModule
-		}
-		apexesForModule[apex.ApexName] = apexesForModule[apex.ApexName] || directDep
+	apexesForModule, ok := apexNamesMap()[moduleName]
+	if !ok {
+		apexesForModule = make(map[string]bool)
+		apexNamesMap()[moduleName] = apexesForModule
 	}
+	apexesForModule[apex.ApexName] = apexesForModule[apex.ApexName] || directDep
 }
 
 // TODO(b/146393795): remove this when b/146393795 is fixed
diff --git a/android/config.go b/android/config.go
index d680b65..cafc71b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1252,10 +1252,6 @@
 	return c.productVariables.MissingUsesLibraries
 }
 
-func (c *deviceConfig) BoardVndkRuntimeDisable() bool {
-	return Bool(c.config.productVariables.BoardVndkRuntimeDisable)
-}
-
 func (c *deviceConfig) DeviceArch() string {
 	return String(c.config.productVariables.DeviceArch)
 }
diff --git a/android/variable.go b/android/variable.go
index 2c8bd07..5826138 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -308,8 +308,6 @@
 	BoardPlatPrivateSepolicyDirs []string `json:",omitempty"`
 	BoardSepolicyM4Defs          []string `json:",omitempty"`
 
-	BoardVndkRuntimeDisable *bool `json:",omitempty"`
-
 	VendorVars map[string]map[string]string `json:",omitempty"`
 
 	Ndk_abis               *bool `json:",omitempty"`
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 10cc4b6..82a902b 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -82,9 +82,9 @@
 
 		var moduleName string
 		if linkToSystemLib {
-			moduleName = fi.moduleName
+			moduleName = fi.androidMkModuleName
 		} else {
-			moduleName = fi.moduleName + "." + apexBundleName + a.suffix
+			moduleName = fi.androidMkModuleName + "." + apexBundleName + a.suffix
 		}
 
 		if !android.InList(moduleName, moduleNames) {
@@ -250,9 +250,9 @@
 		}
 
 		// m <module_name> will build <module_name>.<apex_name> as well.
-		if fi.moduleName != moduleName && a.primaryApexType {
-			fmt.Fprintln(w, ".PHONY: "+fi.moduleName)
-			fmt.Fprintln(w, fi.moduleName+": "+moduleName)
+		if fi.androidMkModuleName != moduleName && a.primaryApexType {
+			fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName)
+			fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName)
 		}
 	}
 	return moduleNames
@@ -353,6 +353,10 @@
 				if apexType == imageApex {
 					fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
 				}
+				if len(a.lintReports) > 0 {
+					fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS :=",
+						strings.Join(a.lintReports.Strings(), " "))
+				}
 
 				if a.installedFilesFile != nil {
 					goal := "checkbuild"
diff --git a/apex/apex.go b/apex/apex.go
index d0c4e6e..1cfb583 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -669,7 +669,7 @@
 }
 
 func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
-	ctx.TopDown("apex_deps", apexDepsMutator)
+	ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
 	ctx.BottomUp("apex", apexMutator).Parallel()
 	ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
 	ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
@@ -682,33 +682,30 @@
 	if !mctx.Module().Enabled() {
 		return
 	}
-	var apexBundles []android.ApexInfo
-	var directDep bool
-	if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex {
-		apexBundles = []android.ApexInfo{{
-			ApexName:      mctx.ModuleName(),
-			MinSdkVersion: a.minSdkVersion(mctx),
-			Updatable:     a.Updatable(),
-		}}
-		directDep = true
-	} else if am, ok := mctx.Module().(android.ApexModule); ok {
-		apexBundles = am.ApexVariations()
-		directDep = false
-	}
-
-	if len(apexBundles) == 0 {
+	a, ok := mctx.Module().(*apexBundle)
+	if !ok || a.vndkApex {
 		return
 	}
-
-	cur := mctx.Module().(android.DepIsInSameApex)
-
-	mctx.VisitDirectDeps(func(child android.Module) {
-		depName := mctx.OtherModuleName(child)
-		if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() &&
-			(cur.DepIsInSameApex(mctx, child) || inAnySdk(child)) {
-			android.UpdateApexDependency(apexBundles, depName, directDep)
-			am.BuildForApexes(apexBundles)
+	apexInfo := android.ApexInfo{
+		ApexName:      mctx.ModuleName(),
+		MinSdkVersion: a.minSdkVersion(mctx),
+		Updatable:     a.Updatable(),
+	}
+	mctx.WalkDeps(func(child, parent android.Module) bool {
+		am, ok := child.(android.ApexModule)
+		if !ok || !am.CanHaveApexVariants() {
+			return false
 		}
+		if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) && !inAnySdk(child) {
+			return false
+		}
+
+		depName := mctx.OtherModuleName(child)
+		// If the parent is apexBundle, this child is directly depended.
+		_, directDep := parent.(*apexBundle)
+		android.UpdateApexDependency(apexInfo, depName, directDep)
+		am.BuildForApex(apexInfo)
+		return true
 	})
 }
 
@@ -1137,12 +1134,14 @@
 
 // apexFile represents a file in an APEX bundle
 type apexFile struct {
-	builtFile  android.Path
-	stem       string
-	moduleName string
-	installDir string
-	class      apexFileClass
-	module     android.Module
+	builtFile android.Path
+	stem      string
+	// Module name of `module` in AndroidMk. Note the generated AndroidMk module for
+	// apexFile is named something like <AndroidMk module name>.<apex name>[<apex suffix>]
+	androidMkModuleName string
+	installDir          string
+	class               apexFileClass
+	module              android.Module
 	// list of symlinks that will be created in installDir that point to this apexFile
 	symlinks      []string
 	dataPaths     []android.DataPath
@@ -1154,19 +1153,20 @@
 	hostRequiredModuleNames   []string
 
 	jacocoReportClassesFile android.Path     // only for javalibs and apps
+	lintDepSets             java.LintDepSets // only for javalibs and apps
 	certificate             java.Certificate // only for apps
 	overriddenPackageName   string           // only for apps
 
 	isJniLib bool
 }
 
-func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile {
+func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
 	ret := apexFile{
-		builtFile:  builtFile,
-		moduleName: moduleName,
-		installDir: installDir,
-		class:      class,
-		module:     module,
+		builtFile:           builtFile,
+		androidMkModuleName: androidMkModuleName,
+		installDir:          installDir,
+		class:               class,
+		module:              module,
 	}
 	if module != nil {
 		ret.moduleDir = ctx.OtherModuleDir(module)
@@ -1278,6 +1278,9 @@
 
 	// Struct holding the merged notice file paths in different formats
 	mergedNotices android.NoticeOutputs
+
+	// Optional list of lint report zip files for apexes that contain java or app modules
+	lintReports android.Paths
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -1620,7 +1623,8 @@
 	}
 
 	fileToCopy := ccMod.OutputFile().Path()
-	return newApexFile(ctx, fileToCopy, ccMod.Name(), dirInApex, nativeSharedLib, ccMod)
+	androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
+	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
 }
 
 func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile {
@@ -1630,7 +1634,8 @@
 	}
 	dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
 	fileToCopy := cc.OutputFile().Path()
-	af := newApexFile(ctx, fileToCopy, cc.Name(), dirInApex, nativeExecutable, cc)
+	androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
+	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
 	af.symlinks = cc.Symlinks()
 	af.dataPaths = cc.DataPaths()
 	return af
@@ -1639,7 +1644,7 @@
 func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
 	dirInApex := "bin"
 	fileToCopy := py.HostToolPath().Path()
-	return newApexFile(ctx, fileToCopy, py.Name(), dirInApex, pyBinary, py)
+	return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py)
 }
 func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
 	dirInApex := "bin"
@@ -1658,25 +1663,33 @@
 func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
 	dirInApex := filepath.Join("bin", sh.SubDir())
 	fileToCopy := sh.OutputFile()
-	af := newApexFile(ctx, fileToCopy, sh.Name(), dirInApex, shBinary, sh)
+	af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
 	af.symlinks = sh.Symlinks()
 	return af
 }
 
-type javaDependency interface {
+type javaModule interface {
+	android.Module
+	BaseModuleName() string
 	DexJarBuildPath() android.Path
 	JacocoReportClassesFile() android.Path
+	LintDepSets() java.LintDepSets
+
 	Stem() string
 }
 
-func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, module android.Module) apexFile {
+var _ javaModule = (*java.Library)(nil)
+var _ javaModule = (*java.SdkLibrary)(nil)
+var _ javaModule = (*java.DexImport)(nil)
+var _ javaModule = (*java.SdkLibraryImport)(nil)
+
+func apexFileForJavaLibrary(ctx android.BaseModuleContext, module javaModule) apexFile {
 	dirInApex := "javalib"
-	fileToCopy := lib.DexJarBuildPath()
-	// Remove prebuilt_ if necessary so the source and prebuilt modules have the same name.
-	name := strings.TrimPrefix(module.Name(), "prebuilt_")
-	af := newApexFile(ctx, fileToCopy, name, dirInApex, javaSharedLib, module)
-	af.jacocoReportClassesFile = lib.JacocoReportClassesFile()
-	af.stem = lib.Stem() + ".jar"
+	fileToCopy := module.DexJarBuildPath()
+	af := newApexFile(ctx, fileToCopy, module.BaseModuleName(), dirInApex, javaSharedLib, module)
+	af.jacocoReportClassesFile = module.JacocoReportClassesFile()
+	af.lintDepSets = module.LintDepSets()
+	af.stem = module.Stem() + ".jar"
 	return af
 }
 
@@ -1699,6 +1712,7 @@
 	OutputFile() android.Path
 	JacocoReportClassesFile() android.Path
 	Certificate() java.Certificate
+	BaseModuleName() string
 }) apexFile {
 	appDir := "app"
 	if aapp.Privileged() {
@@ -1706,7 +1720,7 @@
 	}
 	dirInApex := filepath.Join(appDir, aapp.InstallApkName())
 	fileToCopy := aapp.OutputFile()
-	af := newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
+	af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
 	af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
 	af.certificate = aapp.Certificate()
 
@@ -2031,7 +2045,7 @@
 			case javaLibTag:
 				switch child.(type) {
 				case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport:
-					af := apexFileForJavaLibrary(ctx, child.(javaDependency), child.(android.Module))
+					af := apexFileForJavaLibrary(ctx, child.(javaModule))
 					if !af.Ok() {
 						ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
 						return false
@@ -2054,7 +2068,7 @@
 					if ap.Privileged() {
 						appDir = "priv-app"
 					}
-					af := newApexFile(ctx, ap.OutputFile(), ap.Name(),
+					af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(),
 						filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
 					af.certificate = java.PresignedCertificate
 					filesInfo = append(filesInfo, af)
@@ -2164,7 +2178,7 @@
 						// use the name of the generated test binary (`fileToCopy`) instead of the name
 						// of the original test module (`depName`, shared by all `test_per_src`
 						// variations of that module).
-						af.moduleName = filepath.Base(af.builtFile.String())
+						af.androidMkModuleName = filepath.Base(af.builtFile.String())
 						// these are not considered transitive dep
 						af.transitiveDep = false
 						filesInfo = append(filesInfo, af)
@@ -2275,6 +2289,8 @@
 	a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
 
 	a.buildApexDependencyInfo(ctx)
+
+	a.buildLintReports(ctx)
 }
 
 // Enforce that Java deps of the apex are using stable SDKs to compile
diff --git a/apex/apex_test.go b/apex/apex_test.go
index f064338..3600614 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5179,6 +5179,57 @@
 	ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
 }
 
+func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
+	ctx, config := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["mylib"],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library_shared {
+			name: "mylib",
+			srcs: ["mylib.cpp"],
+			shared_libs: ["myotherlib"],
+			system_shared_libs: [],
+			stl: "none",
+			apex_available: [
+				"myapex",
+				"//apex_available:platform",
+			],
+		}
+
+		cc_prebuilt_library_shared {
+			name: "myotherlib",
+			srcs: ["prebuilt.so"],
+			system_shared_libs: [],
+			stl: "none",
+			apex_available: [
+				"myapex",
+				"//apex_available:platform",
+			],
+		}
+	`)
+
+	apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+	data := android.AndroidMkDataForTest(t, config, "", apexBundle)
+	var builder strings.Builder
+	data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
+	androidMk := builder.String()
+	// `myotherlib` is added to `myapex` as symlink
+	ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
+	ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n")
+	ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n")
+	// `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib`
+	ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += mylib.myapex myotherlib apex_manifest.pb.myapex apex_pubkey.myapex\n")
+}
+
 func TestApexWithJniLibs(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
diff --git a/apex/builder.go b/apex/builder.go
index a70c767..0a1ec3e 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -815,3 +815,12 @@
 		},
 	})
 }
+
+func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
+	depSetsBuilder := java.NewLintDepSetBuilder()
+	for _, fi := range a.filesInfo {
+		depSetsBuilder.Transitive(fi.lintDepSets)
+	}
+
+	a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
+}
diff --git a/cc/cc.go b/cc/cc.go
index fdf2879..57fe9ba 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2215,6 +2215,19 @@
 		depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, exporter.exportedGeneratedHeaders()...)
 	}
 
+	// For the dependency from platform to apex, use the latest stubs
+	c.apexSdkVersion = android.FutureApiLevel
+	if !c.IsForPlatform() {
+		c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion
+	}
+
+	if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
+		// In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
+		// so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
+		// (b/144430859)
+		c.apexSdkVersion = android.FutureApiLevel
+	}
+
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
 		depTag := ctx.OtherModuleDependencyTag(dep)
@@ -2303,19 +2316,6 @@
 			}
 		}
 
-		// For the dependency from platform to apex, use the latest stubs
-		c.apexSdkVersion = android.FutureApiLevel
-		if !c.IsForPlatform() {
-			c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion
-		}
-
-		if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
-			// In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
-			// so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
-			// (b/144430859)
-			c.apexSdkVersion = android.FutureApiLevel
-		}
-
 		if depTag == staticUnwinderDepTag {
 			// Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
 			if c.apexSdkVersion <= android.SdkVersion_Android10 {
diff --git a/cc/config/integer_overflow_blacklist.txt b/cc/config/integer_overflow_blocklist.txt
similarity index 100%
rename from cc/config/integer_overflow_blacklist.txt
rename to cc/config/integer_overflow_blocklist.txt
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 72ad6d7..300bc8f 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -51,7 +51,7 @@
 	}
 
 	cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
-		"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
+		"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blocklist.txt"}
 	// -flto and -fvisibility are required by clang when -fsanitize=cfi is
 	// used, but have no effect on assembly files
 	cfiAsflags = []string{"-flto", "-fvisibility=default"}
@@ -61,7 +61,7 @@
 	cfiStaticLibsMutex    sync.Mutex
 	hwasanStaticLibsMutex sync.Mutex
 
-	intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
+	intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blocklist.txt"}
 
 	minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
 		"-fno-sanitize-recover=integer,undefined"}
@@ -174,6 +174,8 @@
 
 		// value to pass to -fsanitize-blacklist
 		Blacklist *string
+		// value to pass to -fsanitize-blacklist
+		Blocklist *string
 	} `android:"arch_variant"`
 
 	SanitizerEnabled  bool     `blueprint:"mutated"`
@@ -596,6 +598,12 @@
 		flags.CFlagsDeps = append(flags.CFlagsDeps, blacklist.Path())
 	}
 
+	blocklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blocklist)
+	if blocklist.Valid() {
+		flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-blacklist="+blocklist.String())
+		flags.CFlagsDeps = append(flags.CFlagsDeps, blocklist.Path())
+	}
+
 	return flags
 }
 
diff --git a/cc/vndk.go b/cc/vndk.go
index 4adf9d2..15843c6 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -559,10 +559,6 @@
 		return
 	}
 
-	if ctx.DeviceConfig().BoardVndkRuntimeDisable() {
-		return
-	}
-
 	var snapshotOutputs android.Paths
 
 	/*
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 00baa57..1cec289 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -259,9 +259,9 @@
 
 		// If AllowMissingDependencies is enabled, the build will not have stopped when
 		// AddFarVariationDependencies was called on a missing tool, which will result in nonsensical
-		// "cmd: unknown location label ..." errors later.  Add a dummy file to the local label.  The
-		// command that uses this dummy file will never be executed because the rule will be replaced with
-		// an android.Error rule reporting the missing dependencies.
+		// "cmd: unknown location label ..." errors later.  Add a placeholder file to the local label.
+		// The command that uses this placeholder file will never be executed because the rule will be
+		// replaced with an android.Error rule reporting the missing dependencies.
 		if ctx.Config().AllowMissingDependencies() {
 			for _, tool := range g.properties.Tools {
 				if !seenTools[tool] {
@@ -292,9 +292,9 @@
 
 			// If AllowMissingDependencies is enabled, the build will not have stopped when
 			// the dependency was added on a missing SourceFileProducer module, which will result in nonsensical
-			// "cmd: label ":..." has no files" errors later.  Add a dummy file to the local label.  The
-			// command that uses this dummy file will never be executed because the rule will be replaced with
-			// an android.Error rule reporting the missing dependencies.
+			// "cmd: label ":..." has no files" errors later.  Add a placeholder file to the local label.
+			// The command that uses this placeholder file will never be executed because the rule will be
+			// replaced with an android.Error rule reporting the missing dependencies.
 			ctx.AddMissingDependencies(missingDeps)
 			addLocationLabel(in, []string{"***missing srcs " + in + "***"})
 		} else {
diff --git a/java/Android.bp b/java/Android.bp
index fd06c46..e345014 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -10,6 +10,7 @@
         "soong-dexpreopt",
         "soong-genrule",
         "soong-java-config",
+        "soong-python",
         "soong-remoteexec",
         "soong-tradefed",
     ],
diff --git a/java/androidmk.go b/java/androidmk.go
index 03994bf..25dd329 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -132,9 +132,7 @@
 					}
 					entries.SetString("LOCAL_MODULE_STEM", library.Stem())
 
-					entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveHTMLZip)
-					entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveTextZip)
-					entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", library.linter.outputs.transitiveXMLZip)
+					entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports)
 				},
 			},
 		}
@@ -394,9 +392,7 @@
 					entries.AddStrings("LOCAL_SOONG_BUILT_INSTALLED", extra.String()+":"+install)
 				}
 
-				entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveHTMLZip)
-				entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveTextZip)
-				entries.AddOptionalPath("LOCAL_SOONG_LINT_REPORTS", app.linter.outputs.transitiveXMLZip)
+				entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", app.linter.reports)
 			},
 		},
 		ExtraFooters: []android.AndroidMkExtraFootersFunc{
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 190a052..935b839 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1674,7 +1674,7 @@
 
 	impRule := android.NewRuleBuilder()
 	impCmd := impRule.Command()
-	// A dummy action that copies the ninja generated rsp file to a new location. This allows us to
+	// An action that copies the ninja generated rsp file to a new location. This allows us to
 	// add a large number of inputs to a file without exceeding bash command length limits (which
 	// would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the
 	// rsp file to be ${output}.rsp.
diff --git a/java/java.go b/java/java.go
index 367b09c..bd476bc 100644
--- a/java/java.go
+++ b/java/java.go
@@ -556,7 +556,20 @@
 }
 
 func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
-	android.InitAndroidArchModule(module, hod, android.MultilibCommon)
+	initJavaModule(module, hod, false)
+}
+
+func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
+	initJavaModule(module, hod, true)
+}
+
+func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) {
+	multilib := android.MultilibCommon
+	if multiTargets {
+		android.InitAndroidMultiTargetsArchModule(module, hod, multilib)
+	} else {
+		android.InitAndroidArchModule(module, hod, multilib)
+	}
 	android.InitDefaultableModule(module)
 }
 
@@ -575,6 +588,7 @@
 }
 
 var (
+	dataNativeBinsTag     = dependencyTag{name: "dataNativeBins"}
 	staticLibTag          = dependencyTag{name: "staticlib"}
 	libTag                = dependencyTag{name: "javalib"}
 	java9LibTag           = dependencyTag{name: "java9lib"}
@@ -1707,6 +1721,9 @@
 		j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
 		j.linter.javaLanguageLevel = flags.javaVersion.String()
 		j.linter.kotlinLanguageLevel = "1.3"
+		if j.ApexName() != "" && ctx.Config().UnbundledBuildApps() {
+			j.linter.buildModuleReportZip = true
+		}
 		j.linter.lint(ctx)
 	}
 
@@ -2190,6 +2207,11 @@
 	Test_mainline_modules []string
 }
 
+type hostTestProperties struct {
+	// list of native binary modules that should be installed alongside the test
+	Data_native_bins []string `android:"arch_variant"`
+}
+
 type testHelperLibraryProperties struct {
 	// list of compatibility suites (for example "cts", "vts") that the module should be
 	// installed into.
@@ -2215,6 +2237,12 @@
 	data       android.Paths
 }
 
+type TestHost struct {
+	Test
+
+	testHostProperties hostTestProperties
+}
+
 type TestHelperLibrary struct {
 	Library
 
@@ -2229,11 +2257,26 @@
 	testConfig android.Path
 }
 
+func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) {
+	if len(j.testHostProperties.Data_native_bins) > 0 {
+		for _, target := range ctx.MultiTargets() {
+			ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...)
+		}
+	}
+
+	j.deps(ctx)
+}
+
 func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
 		j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
+
 	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
 
+	ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
+		j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
+	})
+
 	j.Library.GenerateAndroidBuildActions(ctx)
 }
 
@@ -2374,14 +2417,15 @@
 // A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
 // compiled against the host bootclasspath.
 func TestHostFactory() android.Module {
-	module := &Test{}
+	module := &TestHost{}
 
 	module.addHostProperties()
 	module.AddProperties(&module.testProperties)
+	module.AddProperties(&module.testHostProperties)
 
 	module.Module.properties.Installable = proptools.BoolPtr(true)
 
-	InitJavaModule(module, android.HostSupported)
+	InitJavaModuleMultiTargets(module, android.HostSupported)
 	return module
 }
 
@@ -2789,6 +2833,10 @@
 	return nil
 }
 
+func (a *DexImport) LintDepSets() LintDepSets {
+	return LintDepSets{}
+}
+
 func (j *DexImport) IsInstallable() bool {
 	return true
 }
diff --git a/java/java_test.go b/java/java_test.go
index db3f187..73e6792 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -31,6 +31,7 @@
 	"android/soong/cc"
 	"android/soong/dexpreopt"
 	"android/soong/genrule"
+	"android/soong/python"
 )
 
 var buildDir string
@@ -81,6 +82,7 @@
 	ctx.RegisterModuleType("java_plugin", PluginFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+	ctx.RegisterModuleType("python_binary_host", python.PythonBinaryHostFactory)
 	RegisterDocsBuildComponents(ctx)
 	RegisterStubsBuildComponents(ctx)
 	RegisterSdkLibraryBuildComponents(ctx)
@@ -89,6 +91,7 @@
 
 	RegisterPrebuiltApisBuildComponents(ctx)
 
+	ctx.PreDepsMutators(python.RegisterPythonPreDepsMutators)
 	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
 	ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
 	ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory))
@@ -2008,3 +2011,28 @@
 		t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
 	}
 }
+
+func TestDataNativeBinaries(t *testing.T) {
+	ctx, config := testJava(t, `
+		java_test_host {
+			name: "foo",
+			srcs: ["a.java"],
+			data_native_bins: ["bin"]
+		}
+
+		python_binary_host {
+			name: "bin",
+			srcs: ["bin.py"],
+		}
+	`)
+
+	buildOS := android.BuildOs.String()
+
+	test := ctx.ModuleForTests("foo", buildOS+"_common").Module().(*TestHost)
+	entries := android.AndroidMkEntriesForTest(t, config, "", test)[0]
+	expected := []string{buildDir + "/.intermediates/bin/" + buildOS + "_x86_64_PY3/bin:bin"}
+	actual := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"]
+	if !reflect.DeepEqual(expected, actual) {
+		t.Errorf("Unexpected test data - expected: %q, actual: %q", expected, actual)
+	}
+}
diff --git a/java/lint.go b/java/lint.go
index 5d2c4f6..1bf7f69 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -69,28 +69,78 @@
 	outputs             lintOutputs
 	properties          LintProperties
 
+	reports android.Paths
+
 	buildModuleReportZip bool
 }
 
 type lintOutputs struct {
-	html android.ModuleOutPath
-	text android.ModuleOutPath
-	xml  android.ModuleOutPath
+	html android.Path
+	text android.Path
+	xml  android.Path
 
-	transitiveHTML *android.DepSet
-	transitiveText *android.DepSet
-	transitiveXML  *android.DepSet
-
-	transitiveHTMLZip android.OptionalPath
-	transitiveTextZip android.OptionalPath
-	transitiveXMLZip  android.OptionalPath
+	depSets LintDepSets
 }
 
-type lintOutputIntf interface {
+type lintOutputsIntf interface {
 	lintOutputs() *lintOutputs
 }
 
-var _ lintOutputIntf = (*linter)(nil)
+type lintDepSetsIntf interface {
+	LintDepSets() LintDepSets
+}
+
+type LintDepSets struct {
+	HTML, Text, XML *android.DepSet
+}
+
+type LintDepSetsBuilder struct {
+	HTML, Text, XML *android.DepSetBuilder
+}
+
+func NewLintDepSetBuilder() LintDepSetsBuilder {
+	return LintDepSetsBuilder{
+		HTML: android.NewDepSetBuilder(android.POSTORDER),
+		Text: android.NewDepSetBuilder(android.POSTORDER),
+		XML:  android.NewDepSetBuilder(android.POSTORDER),
+	}
+}
+
+func (l LintDepSetsBuilder) Direct(html, text, xml android.Path) LintDepSetsBuilder {
+	l.HTML.Direct(html)
+	l.Text.Direct(text)
+	l.XML.Direct(xml)
+	return l
+}
+
+func (l LintDepSetsBuilder) Transitive(depSets LintDepSets) LintDepSetsBuilder {
+	if depSets.HTML != nil {
+		l.HTML.Transitive(depSets.HTML)
+	}
+	if depSets.Text != nil {
+		l.Text.Transitive(depSets.Text)
+	}
+	if depSets.XML != nil {
+		l.XML.Transitive(depSets.XML)
+	}
+	return l
+}
+
+func (l LintDepSetsBuilder) Build() LintDepSets {
+	return LintDepSets{
+		HTML: l.HTML.Build(),
+		Text: l.Text.Build(),
+		XML:  l.XML.Build(),
+	}
+}
+
+func (l *linter) LintDepSets() LintDepSets {
+	return l.outputs.depSets
+}
+
+var _ lintDepSetsIntf = (*linter)(nil)
+
+var _ lintOutputsIntf = (*linter)(nil)
 
 func (l *linter) lintOutputs() *lintOutputs {
 	return &l.outputs
@@ -202,7 +252,7 @@
 	return projectXMLPath, configXMLPath, cacheDir, homeDir, deps
 }
 
-// generateManifest adds a command to the rule to write a dummy manifest cat contains the
+// generateManifest adds a command to the rule to write a simple manifest that contains the
 // minSdkVersion and targetSdkVersion for modules (like java_library) that don't have a manifest.
 func (l *linter) generateManifest(ctx android.ModuleContext, rule *android.RuleBuilder) android.Path {
 	manifestPath := android.PathForModuleOut(ctx, "lint", "AndroidManifest.xml")
@@ -247,16 +297,11 @@
 	text := android.PathForModuleOut(ctx, "lint-report.txt")
 	xml := android.PathForModuleOut(ctx, "lint-report.xml")
 
-	htmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(html)
-	textDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(text)
-	xmlDeps := android.NewDepSetBuilder(android.POSTORDER).Direct(xml)
+	depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
 
 	ctx.VisitDirectDepsWithTag(staticLibTag, func(dep android.Module) {
-		if depLint, ok := dep.(lintOutputIntf); ok {
-			depLintOutputs := depLint.lintOutputs()
-			htmlDeps.Transitive(depLintOutputs.transitiveHTML)
-			textDeps.Transitive(depLintOutputs.transitiveText)
-			xmlDeps.Transitive(depLintOutputs.transitiveXML)
+		if depLint, ok := dep.(lintDepSetsIntf); ok {
+			depSetsBuilder.Transitive(depLint.LintDepSets())
 		}
 	})
 
@@ -309,26 +354,35 @@
 		text: text,
 		xml:  xml,
 
-		transitiveHTML: htmlDeps.Build(),
-		transitiveText: textDeps.Build(),
-		transitiveXML:  xmlDeps.Build(),
+		depSets: depSetsBuilder.Build(),
 	}
 
 	if l.buildModuleReportZip {
-		htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
-		l.outputs.transitiveHTMLZip = android.OptionalPathForPath(htmlZip)
-		lintZip(ctx, l.outputs.transitiveHTML.ToSortedList(), htmlZip)
-
-		textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
-		l.outputs.transitiveTextZip = android.OptionalPathForPath(textZip)
-		lintZip(ctx, l.outputs.transitiveText.ToSortedList(), textZip)
-
-		xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
-		l.outputs.transitiveXMLZip = android.OptionalPathForPath(xmlZip)
-		lintZip(ctx, l.outputs.transitiveXML.ToSortedList(), xmlZip)
+		l.reports = BuildModuleLintReportZips(ctx, l.LintDepSets())
 	}
 }
 
+func BuildModuleLintReportZips(ctx android.ModuleContext, depSets LintDepSets) android.Paths {
+	htmlList := depSets.HTML.ToSortedList()
+	textList := depSets.Text.ToSortedList()
+	xmlList := depSets.XML.ToSortedList()
+
+	if len(htmlList) == 0 && len(textList) == 0 && len(xmlList) == 0 {
+		return nil
+	}
+
+	htmlZip := android.PathForModuleOut(ctx, "lint-report-html.zip")
+	lintZip(ctx, htmlList, htmlZip)
+
+	textZip := android.PathForModuleOut(ctx, "lint-report-text.zip")
+	lintZip(ctx, textList, textZip)
+
+	xmlZip := android.PathForModuleOut(ctx, "lint-report-xml.zip")
+	lintZip(ctx, xmlList, xmlZip)
+
+	return android.Paths{htmlZip, textZip, xmlZip}
+}
+
 type lintSingleton struct {
 	htmlZip android.WritablePath
 	textZip android.WritablePath
@@ -403,7 +457,7 @@
 			return
 		}
 
-		if l, ok := m.(lintOutputIntf); ok {
+		if l, ok := m.(lintOutputsIntf); ok {
 			outputs = append(outputs, l.lintOutputs())
 		}
 	})
@@ -414,7 +468,9 @@
 		var paths android.Paths
 
 		for _, output := range outputs {
-			paths = append(paths, get(output))
+			if p := get(output); p != nil {
+				paths = append(paths, p)
+			}
 		}
 
 		lintZip(ctx, paths, outputPath)
diff --git a/java/sdk.go b/java/sdk.go
index 6e67a13..5d79d1d 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -214,7 +214,7 @@
 		// "current" can be built from source and be from prebuilt SDK
 		return ctx.Config().UnbundledBuildUsePrebuiltSdks()
 	} else if s.version.isNumbered() {
-		// sanity check
+		// validation check
 		if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest {
 			panic(fmt.Errorf("prebuilt SDK is not not available for sdkKind=%q", s.kind))
 			return false
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e3ba2c7..8a8d0c9 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1996,6 +1996,15 @@
 }
 
 // to satisfy apex.javaDependency interface
+func (module *SdkLibraryImport) LintDepSets() LintDepSets {
+	if module.implLibraryModule == nil {
+		return LintDepSets{}
+	} else {
+		return module.implLibraryModule.LintDepSets()
+	}
+}
+
+// to satisfy apex.javaDependency interface
 func (module *SdkLibraryImport) Stem() string {
 	return module.BaseModuleName()
 }
diff --git a/java/testing.go b/java/testing.go
index e761743..1e725fa 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -22,6 +22,8 @@
 
 	"android/soong/android"
 	"android/soong/cc"
+	"android/soong/python"
+
 	"github.com/google/blueprint"
 )
 
@@ -85,6 +87,10 @@
 		"prebuilts/sdk/tools/core-lambda-stubs.jar":                nil,
 		"prebuilts/sdk/Android.bp":                                 []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`),
 
+		"bin.py": nil,
+		python.StubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
+		MAIN_FILE = '%main%'`),
+
 		// For java_sdk_library
 		"api/module-lib-current.txt":                        nil,
 		"api/module-lib-removed.txt":                        nil,
diff --git a/python/binary.go b/python/binary.go
index 695fa12..5a74926 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -65,7 +65,7 @@
 }
 
 var (
-	stubTemplateHost = "build/soong/python/scripts/stub_template_host.txt"
+	StubTemplateHost = "build/soong/python/scripts/stub_template_host.txt"
 )
 
 func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
diff --git a/python/builder.go b/python/builder.go
index 36baecd..dc2d1f1 100644
--- a/python/builder.go
+++ b/python/builder.go
@@ -91,7 +91,7 @@
 
 	if !embeddedLauncher {
 		// the path of stub_template_host.txt from source tree.
-		template := android.PathForSource(ctx, stubTemplateHost)
+		template := android.PathForSource(ctx, StubTemplateHost)
 		implicits = append(implicits, template)
 
 		// intermediate output path for __main__.py
diff --git a/python/python.go b/python/python.go
index a6c9e2a..479c729 100644
--- a/python/python.go
+++ b/python/python.go
@@ -30,9 +30,11 @@
 )
 
 func init() {
-	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
-	})
+	android.PreDepsMutators(RegisterPythonPreDepsMutators)
+}
+
+func RegisterPythonPreDepsMutators(ctx android.RegisterMutatorsContext) {
+	ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
 }
 
 // the version properties that apply to python libraries and binaries.
@@ -226,15 +228,20 @@
 	return func(mctx android.BottomUpMutatorContext) {
 		if base, ok := mctx.Module().(*Module); ok {
 			versionNames := []string{}
-			if base.properties.Version.Py2.Enabled != nil &&
-				*(base.properties.Version.Py2.Enabled) == true {
-				versionNames = append(versionNames, pyVersion2)
-			}
+			// PY3 is first so that we alias the PY3 variant rather than PY2 if both
+			// are available
 			if !(base.properties.Version.Py3.Enabled != nil &&
 				*(base.properties.Version.Py3.Enabled) == false) {
 				versionNames = append(versionNames, pyVersion3)
 			}
+			if base.properties.Version.Py2.Enabled != nil &&
+				*(base.properties.Version.Py2.Enabled) == true {
+				versionNames = append(versionNames, pyVersion2)
+			}
 			modules := mctx.CreateVariations(versionNames...)
+			if len(versionNames) > 0 {
+				mctx.AliasVariation(versionNames[0])
+			}
 			for i, v := range versionNames {
 				// set the actual version for Python module.
 				modules[i].(*Module).properties.Actual_version = v
diff --git a/python/python_test.go b/python/python_test.go
index 1245ca1..23db24e 100644
--- a/python/python_test.go
+++ b/python/python_test.go
@@ -301,7 +301,7 @@
 				filepath.Join("dir", "file2.py"):       nil,
 				filepath.Join("dir", "bin.py"):         nil,
 				filepath.Join("dir", "file4.py"):       nil,
-				stubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
+				StubTemplateHost: []byte(`PYTHON_BINARY = '%interpreter%'
 				MAIN_FILE = '%main%'`),
 			},
 			expectedBinaries: []pyModule{
@@ -330,9 +330,7 @@
 		t.Run(d.desc, func(t *testing.T) {
 			config := android.TestConfig(buildDir, nil, "", d.mockFiles)
 			ctx := android.NewTestContext()
-			ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-				ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
-			})
+			ctx.PreDepsMutators(RegisterPythonPreDepsMutators)
 			ctx.RegisterModuleType("python_library_host", PythonLibraryHostFactory)
 			ctx.RegisterModuleType("python_binary_host", PythonBinaryHostFactory)
 			ctx.RegisterModuleType("python_defaults", defaultsFactory)
diff --git a/rust/binary.go b/rust/binary.go
index 0d7f541..1a82c92 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -106,8 +106,7 @@
 func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
 
-	srcPath, paths := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
-	deps.SrcDeps = append(deps.SrcDeps, paths...)
+	srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
 
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	binary.unstrippedOutputFile = outputFile
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 43053b0..e8bbb35 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -51,6 +51,7 @@
 
 func init() {
 	android.RegisterModuleType("rust_bindgen", RustBindgenFactory)
+	android.RegisterModuleType("rust_bindgen_host", RustBindgenHostFactory)
 }
 
 var _ SourceProvider = (*bindgenDecorator)(nil)
@@ -157,6 +158,11 @@
 	return module.Init()
 }
 
+func RustBindgenHostFactory() android.Module {
+	module, _ := NewRustBindgen(android.HostSupported)
+	return module.Init()
+}
+
 func NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorator) {
 	module := newModule(hod, android.MultilibBoth)
 
diff --git a/rust/library.go b/rust/library.go
index 28c9792..4c6da9d 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -368,8 +368,7 @@
 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	var outputFile android.WritablePath
 
-	srcPath, paths := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
-	deps.SrcDeps = append(deps.SrcDeps, paths...)
+	srcPath, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
 
 	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
 
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 2752dc3..3dd2521 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -65,8 +65,7 @@
 	fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix()
 	outputFile := android.PathForModuleOut(ctx, fileName)
 
-	srcPath, paths := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
-	deps.SrcDeps = append(deps.SrcDeps, paths...)
+	srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
 
 	procMacro.unstrippedOutputFile = outputFile
 
diff --git a/rust/rust.go b/rust/rust.go
index 8ebd39d..78bf7ad 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -748,6 +748,8 @@
 	directProcMacroDeps := []*Module{}
 	directSharedLibDeps := [](cc.LinkableInterface){}
 	directStaticLibDeps := [](cc.LinkableInterface){}
+	directSrcProvidersDeps := []*Module{}
+	directSrcDeps := [](android.SourceFileProducer){}
 
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
@@ -781,6 +783,24 @@
 			case procMacroDepTag:
 				directProcMacroDeps = append(directProcMacroDeps, rustDep)
 				mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, depName)
+			case android.SourceDepTag:
+				// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
+				// OS/Arch variant is used.
+				var helper string
+				if ctx.Host() {
+					helper = "missing 'host_supported'?"
+				} else {
+					helper = "device module defined?"
+				}
+
+				if dep.Target().Os != ctx.Os() {
+					ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper)
+					return
+				} else if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
+					ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper)
+					return
+				}
+				directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
 			}
 
 			//Append the dependencies exportedDirs
@@ -798,6 +818,14 @@
 
 		}
 
+		if srcDep, ok := dep.(android.SourceFileProducer); ok {
+			switch depTag {
+			case android.SourceDepTag:
+				// These are usually genrules which don't have per-target variants.
+				directSrcDeps = append(directSrcDeps, srcDep)
+			}
+		}
+
 		if ccDep, ok := dep.(cc.LinkableInterface); ok {
 			//Handle C dependencies
 			if _, ok := ccDep.(*Module); !ok {
@@ -883,11 +911,22 @@
 		sharedLibDepFiles = append(sharedLibDepFiles, dep.OutputFile().Path())
 	}
 
+	var srcProviderDepFiles android.Paths
+	for _, dep := range directSrcProvidersDeps {
+		srcs, _ := dep.OutputFiles("")
+		srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
+	}
+	for _, dep := range directSrcDeps {
+		srcs := dep.Srcs()
+		srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
+	}
+
 	depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
 	depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
 	depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibDepFiles...)
 	depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...)
 	depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
+	depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
 
 	// Dedup exported flags from dependencies
 	depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 89dfb67..b3bbddb 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -291,6 +291,26 @@
 	}
 }
 
+func TestSourceProviderTargetMismatch(t *testing.T) {
+	// This might error while building the dependency tree or when calling depsToPaths() depending on the lunched
+	// target, which results in two different errors. So don't check the error, just confirm there is one.
+	testRustError(t, ".*", `
+		rust_proc_macro {
+			name: "libprocmacro",
+			srcs: [
+				"foo.rs",
+				":libbindings",
+			],
+			crate_name: "procmacro",
+		}
+		rust_bindgen {
+			name: "libbindings",
+			stem: "bindings",
+			wrapper_src: "src/any.h",
+		}
+	`)
+}
+
 // Test to make sure proc_macros use host variants when building device modules.
 func TestProcMacroDeviceDeps(t *testing.T) {
 	ctx := testRust(t, `
diff --git a/third_party/zip/zip_test.go b/third_party/zip/zip_test.go
index 7373660..559c914 100644
--- a/third_party/zip/zip_test.go
+++ b/third_party/zip/zip_test.go
@@ -219,7 +219,7 @@
 	}
 }
 
-// fakeHash32 is a dummy Hash32 that always returns 0.
+// fakeHash32 is a fake Hash32 that always returns 0.
 type fakeHash32 struct {
 	hash.Hash32
 }