Merge "Add `$ANDROID_HOST_OUT/apex` to the file set removed by target `installclean`."
diff --git a/android/module.go b/android/module.go
index dda526f..8076a99 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1495,6 +1495,11 @@
 	m.commonProperties.Native_bridge_supported = boolPtr(true)
 }
 
+// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
+func (m *ModuleBase) IsNativeBridgeSupported() bool {
+	return proptools.Bool(m.commonProperties.Native_bridge_supported)
+}
+
 func (m *moduleContext) InstallInData() bool {
 	return m.module.InstallInData()
 }
diff --git a/apex/apex.go b/apex/apex.go
index b32cc0f..4f79c42 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -21,6 +21,7 @@
 	"runtime"
 	"sort"
 	"strings"
+	"sync"
 
 	"android/soong/android"
 	"android/soong/cc"
@@ -98,7 +99,8 @@
 		Command: `${zip2zip} -i $in -o $out ` +
 			`apex_payload.img:apex/${abi}.img ` +
 			`apex_manifest.json:root/apex_manifest.json ` +
-			`AndroidManifest.xml:manifest/AndroidManifest.xml`,
+			`AndroidManifest.xml:manifest/AndroidManifest.xml ` +
+			`assets/NOTICE.html.gz:assets/NOTICE.html.gz`,
 		CommandDeps: []string{"${zip2zip}"},
 		Description: "app bundle",
 	}, "abi")
@@ -152,6 +154,7 @@
 		"com.android.media":              []string{"libbinder"},
 		"com.android.media.swcodec":      []string{"libbinder"},
 		"test_com.android.media.swcodec": []string{"libbinder"},
+		"com.android.vndk":               []string{"libbinder"},
 	}
 )
 
@@ -184,9 +187,14 @@
 
 	android.RegisterModuleType("apex", apexBundleFactory)
 	android.RegisterModuleType("apex_test", testApexBundleFactory)
+	android.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
 	android.RegisterModuleType("apex_defaults", defaultsFactory)
 	android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
 
+	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator).Parallel()
+		ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator).Parallel()
+	})
 	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("apex_deps", apexDepsMutator)
 		ctx.BottomUp("apex", apexMutator).Parallel()
@@ -195,6 +203,51 @@
 	})
 }
 
+var (
+	vndkApexListKey   = android.NewOnceKey("vndkApexList")
+	vndkApexListMutex sync.Mutex
+)
+
+func vndkApexList(config android.Config) map[string]*apexBundle {
+	return config.Once(vndkApexListKey, func() interface{} {
+		return map[string]*apexBundle{}
+	}).(map[string]*apexBundle)
+}
+
+// apexVndkGatherMutator gathers "apex_vndk" modules and puts them in a map with vndk_version as a key.
+func apexVndkGatherMutator(mctx android.TopDownMutatorContext) {
+	if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
+		if ab.IsNativeBridgeSupported() {
+			mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
+		}
+		vndkVersion := proptools.StringDefault(ab.vndkProperties.Vndk_version, mctx.DeviceConfig().PlatformVndkVersion())
+		vndkApexListMutex.Lock()
+		defer vndkApexListMutex.Unlock()
+		vndkApexList := vndkApexList(mctx.Config())
+		if other, ok := vndkApexList[vndkVersion]; ok {
+			mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.Name())
+		}
+		vndkApexList[vndkVersion] = ab
+	}
+}
+
+// apexVndkAddDepsMutator adds (reverse) dependencies from vndk libs to apex_vndk modules.
+// It filters only libs with matching targets.
+func apexVndkAddDepsMutator(mctx android.BottomUpMutatorContext) {
+	if cc, ok := mctx.Module().(*cc.Module); ok && cc.IsVndkOnSystem() {
+		vndkApexList := vndkApexList(mctx.Config())
+		if ab, ok := vndkApexList[cc.VndkVersion()]; ok {
+			targetArch := cc.Target().String()
+			for _, target := range ab.MultiTargets() {
+				if target.String() == targetArch {
+					mctx.AddReverseDependency(mctx.Module(), sharedLibTag, ab.Name())
+					break
+				}
+			}
+		}
+	}
+}
+
 // Mark the direct and transitive dependencies of apex bundles so that they
 // can be built for the apex bundles.
 func apexDepsMutator(mctx android.TopDownMutatorContext) {
@@ -252,11 +305,14 @@
 type apexNativeDependencies struct {
 	// List of native libraries
 	Native_shared_libs []string
+
 	// List of native executables
 	Binaries []string
+
 	// List of native tests
 	Tests []string
 }
+
 type apexMultilibProperties struct {
 	// Native dependencies whose compile_multilib is "first"
 	First apexNativeDependencies
@@ -361,14 +417,17 @@
 		Android struct {
 			Multilib apexMultilibProperties
 		}
+
 		// Multilib properties only for host.
 		Host struct {
 			Multilib apexMultilibProperties
 		}
+
 		// Multilib properties only for host linux_bionic.
 		Linux_bionic struct {
 			Multilib apexMultilibProperties
 		}
+
 		// Multilib properties only for host linux_glibc.
 		Linux_glibc struct {
 			Multilib apexMultilibProperties
@@ -376,6 +435,11 @@
 	}
 }
 
+type apexVndkProperties struct {
+	// Indicates VNDK version of which this VNDK APEX bundles VNDK libs. Default is Platform VNDK Version.
+	Vndk_version *string
+}
+
 type apexFileClass int
 
 const (
@@ -474,6 +538,7 @@
 
 	properties       apexBundleProperties
 	targetProperties apexTargetBundleProperties
+	vndkProperties   apexVndkProperties
 
 	apexTypes apexPackaging
 
@@ -497,6 +562,7 @@
 	externalDeps []string
 
 	testApex bool
+	vndkApex bool
 
 	// intermediate path for apex_manifest.json
 	manifestOut android.WritablePath
@@ -753,38 +819,36 @@
 	a.properties.Flattened = flattened
 }
 
-func getCopyManifestForNativeLibrary(cc *cc.Module, handleSpecialLibs bool) (fileToCopy android.Path, dirInApex string) {
+func getCopyManifestForNativeLibrary(ccMod *cc.Module, config android.Config, handleSpecialLibs bool) (fileToCopy android.Path, dirInApex string) {
 	// Decide the APEX-local directory by the multilib of the library
 	// In the future, we may query this to the module.
-	switch cc.Arch().ArchType.Multilib {
+	switch ccMod.Arch().ArchType.Multilib {
 	case "lib32":
 		dirInApex = "lib"
 	case "lib64":
 		dirInApex = "lib64"
 	}
-	dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
-	if !cc.Arch().Native {
-		dirInApex = filepath.Join(dirInApex, cc.Arch().ArchType.String())
-	} else if cc.Target().NativeBridge == android.NativeBridgeEnabled {
-		dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
+	dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
+	if !ccMod.Arch().Native {
+		dirInApex = filepath.Join(dirInApex, ccMod.Arch().ArchType.String())
+	} else if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
+		dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath)
 	}
-	if handleSpecialLibs {
-		switch cc.Name() {
-		case "libc", "libm", "libdl":
-			// Special case for bionic libs. This is to prevent the bionic libs
-			// from being included in the search path /apex/com.android.apex/lib.
-			// This exclusion is required because bionic libs in the runtime APEX
-			// are available via the legacy paths /system/lib/libc.so, etc. By the
-			// init process, the bionic libs in the APEX are bind-mounted to the
-			// legacy paths and thus will be loaded into the default linker namespace.
-			// If the bionic libs are directly in /apex/com.android.apex/lib then
-			// the same libs will be again loaded to the runtime linker namespace,
-			// which will result double loading of bionic libs that isn't supported.
-			dirInApex = filepath.Join(dirInApex, "bionic")
-		}
+	if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), config) {
+		// Special case for Bionic libs and other libs installed with them. This is
+		// to prevent those libs from being included in the search path
+		// /apex/com.android.runtime/${LIB}. This exclusion is required because
+		// those libs in the Runtime APEX are available via the legacy paths in
+		// /system/lib/. By the init process, the libs in the APEX are bind-mounted
+		// to the legacy paths and thus will be loaded into the default linker
+		// namespace (aka "platform" namespace). If the libs are directly in
+		// /apex/com.android.runtime/${LIB} then the same libs will be loaded again
+		// into the runtime linker namespace, which will result in double loading of
+		// them, which isn't supported.
+		dirInApex = filepath.Join(dirInApex, "bionic")
 	}
 
-	fileToCopy = cc.OutputFile().Path()
+	fileToCopy = ccMod.OutputFile().Path()
 	return
 }
 
@@ -920,7 +984,7 @@
 					if cc.HasStubsVariants() {
 						provideNativeLibs = append(provideNativeLibs, cc.OutputFile().Path().Base())
 					}
-					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
+					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, ctx.Config(), handleSpecialLibs)
 					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
 					return true
 				} else {
@@ -1051,7 +1115,7 @@
 							// Don't track further
 							return false
 						}
-						fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
+						fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, ctx.Config(), handleSpecialLibs)
 						filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
 						return true
 					}
@@ -1087,11 +1151,12 @@
 
 	// remove duplicates in filesInfo
 	removeDup := func(filesInfo []apexFile) []apexFile {
-		encountered := make(map[android.Path]bool)
+		encountered := make(map[string]bool)
 		result := []apexFile{}
 		for _, f := range filesInfo {
-			if !encountered[f.builtFile] {
-				encountered[f.builtFile] = true
+			dest := filepath.Join(f.installDir, f.builtFile.Base())
+			if !encountered[dest] {
+				encountered[dest] = true
 				result = append(result, f)
 			}
 		}
@@ -1417,7 +1482,7 @@
 	})
 
 	// Install to $OUT/soong/{target,host}/.../apex
-	if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) && !a.properties.Flattened {
+	if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) && (!a.properties.Flattened || a.flattenedConfigValue) {
 		ctx.InstallFile(a.installDir, ctx.ModuleName()+suffix, a.outputFiles[apexType])
 	}
 }
@@ -1597,7 +1662,7 @@
 				fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
 				fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): .KATI_IMPLICIT_OUTPUTS :=", a.flattenedOutput.String())
 
-			} else if !a.properties.Flattened {
+			} else if !a.properties.Flattened || a.flattenedConfigValue {
 				// zip-apex is the less common type so have the name refer to the image-apex
 				// only and use {name}.zip if you want the zip-apex
 				if apexType == zipApex && a.apexTypes == both {
@@ -1630,18 +1695,9 @@
 		}}
 }
 
-func testApexBundleFactory() android.Module {
-	return ApexBundleFactory(true /*testApex*/)
-}
-
-func apexBundleFactory() android.Module {
-	return ApexBundleFactory(false /*testApex*/)
-}
-
-func ApexBundleFactory(testApex bool) android.Module {
+func newApexBundle() *apexBundle {
 	module := &apexBundle{
 		outputFiles: map[apexPackaging]android.WritablePath{},
-		testApex:    testApex,
 	}
 	module.AddProperties(&module.properties)
 	module.AddProperties(&module.targetProperties)
@@ -1653,6 +1709,39 @@
 	return module
 }
 
+func ApexBundleFactory(testApex bool) android.Module {
+	bundle := newApexBundle()
+	bundle.testApex = testApex
+	return bundle
+}
+
+func testApexBundleFactory() android.Module {
+	bundle := newApexBundle()
+	bundle.testApex = true
+	return bundle
+}
+
+func apexBundleFactory() android.Module {
+	return newApexBundle()
+}
+
+// apex_vndk creates a special variant of apex modules which contains only VNDK libraries.
+// If `vndk_version` is specified, the VNDK libraries of the specified VNDK version are gathered automatically.
+// If not specified, then the "current" versions are gathered.
+func vndkApexBundleFactory() android.Module {
+	bundle := newApexBundle()
+	bundle.vndkApex = true
+	bundle.AddProperties(&bundle.vndkProperties)
+	android.AddLoadHook(bundle, func(ctx android.LoadHookContext) {
+		ctx.AppendProperties(&struct {
+			Compile_multilib *string
+		}{
+			proptools.StringPtr("both"),
+		})
+	})
+	return bundle
+}
+
 //
 // Defaults
 //
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e2d85ae..7f36f51 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -40,8 +40,9 @@
 	return
 }
 
-func testApexError(t *testing.T, pattern, bp string) {
-	ctx, config := testApexContext(t, bp)
+func testApexError(t *testing.T, pattern, bp string, handlers ...testCustomizer) {
+	t.Helper()
+	ctx, config := testApexContext(t, bp, handlers...)
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	if len(errs) > 0 {
 		android.FailIfNoMatchingErrors(t, pattern, errs)
@@ -56,8 +57,9 @@
 	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
 }
 
-func testApex(t *testing.T, bp string) (*android.TestContext, android.Config) {
-	ctx, config := testApexContext(t, bp)
+func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
+	t.Helper()
+	ctx, config := testApexContext(t, bp, handlers...)
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	android.FailIfErrored(t, errs)
 	_, errs = ctx.PrepareBuildActions(config)
@@ -65,37 +67,52 @@
 	return ctx, config
 }
 
-func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
+type testCustomizer func(fs map[string][]byte, config android.Config)
+
+func withFiles(files map[string][]byte) testCustomizer {
+	return func(fs map[string][]byte, config android.Config) {
+		for k, v := range files {
+			fs[k] = v
+		}
+	}
+}
+
+func withTargets(targets map[android.OsType][]android.Target) testCustomizer {
+	return func(fs map[string][]byte, config android.Config) {
+		for k, v := range targets {
+			config.Targets[k] = v
+		}
+	}
+}
+
+func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
 	config := android.TestArchConfig(buildDir, nil)
 	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
 	config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
 	config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
 	config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q")
 	config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false)
+	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
 
 	ctx := android.NewTestArchContext()
 	ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apexBundleFactory))
 	ctx.RegisterModuleType("apex_test", android.ModuleFactoryAdaptor(testApexBundleFactory))
+	ctx.RegisterModuleType("apex_vndk", android.ModuleFactoryAdaptor(vndkApexBundleFactory))
 	ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory))
 	ctx.RegisterModuleType("apex_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
 	ctx.RegisterModuleType("prebuilt_apex", android.ModuleFactoryAdaptor(PrebuiltFactory))
-	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
-
-	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("apex_deps", apexDepsMutator)
-		ctx.BottomUp("apex", apexMutator)
-		ctx.BottomUp("apex_uses", apexUsesMutator)
-		ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
-		ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
-	})
 
 	ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
 	ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory))
 	ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(cc.LibraryHeaderFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(cc.PrebuiltSharedLibraryFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(cc.PrebuiltStaticLibraryFactory))
 	ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(cc.BinaryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
 	ctx.RegisterModuleType("cc_test", android.ModuleFactoryAdaptor(cc.TestFactory))
 	ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
+	ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(cc.VndkPrebuiltSharedFactory))
 	ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
 	ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory))
 	ctx.RegisterModuleType("sh_binary", android.ModuleFactoryAdaptor(android.ShBinaryFactory))
@@ -105,6 +122,7 @@
 	ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
 	ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory))
 
+	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
 	})
@@ -115,6 +133,15 @@
 		ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
 		ctx.BottomUp("version", cc.VersionMutator).Parallel()
 		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
+		ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator)
+		ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator)
+	})
+	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.TopDown("apex_deps", apexDepsMutator)
+		ctx.BottomUp("apex", apexMutator)
+		ctx.BottomUp("apex_uses", apexUsesMutator)
+		ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
+		ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
 	})
 
 	ctx.Register()
@@ -132,6 +159,7 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		toolchain_library {
@@ -146,6 +174,7 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		toolchain_library {
@@ -153,6 +182,7 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		toolchain_library {
@@ -160,6 +190,23 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
+		}
+
+		toolchain_library {
+			name: "libclang_rt.builtins-x86_64-android",
+			src: "",
+			vendor_available: true,
+			recovery_available: true,
+			native_bridge_supported: true,
+		}
+
+		toolchain_library {
+			name: "libclang_rt.builtins-i686-android",
+			src: "",
+			vendor_available: true,
+			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		cc_object {
@@ -167,6 +214,7 @@
 			stl: "none",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		cc_object {
@@ -174,6 +222,7 @@
 			stl: "none",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		cc_object {
@@ -189,20 +238,23 @@
 		llndk_library {
 			name: "libc",
 			symbol_file: "",
+			native_bridge_supported: true,
 		}
 
 		llndk_library {
 			name: "libm",
 			symbol_file: "",
+			native_bridge_supported: true,
 		}
 
 		llndk_library {
 			name: "libdl",
 			symbol_file: "",
+			native_bridge_supported: true,
 		}
 	`
 
-	ctx.MockFileSystem(map[string][]byte{
+	fs := map[string][]byte{
 		"Android.bp":                                        []byte(bp),
 		"build/make/target/product/security":                nil,
 		"apex_manifest.json":                                nil,
@@ -238,7 +290,13 @@
 		"frameworks/base/api/current.txt":            nil,
 		"build/make/core/proguard.flags":             nil,
 		"build/make/core/proguard_basic_keeps.flags": nil,
-	})
+	}
+
+	for _, handler := range handlers {
+		handler(fs, config)
+	}
+
+	ctx.MockFileSystem(fs)
 
 	return ctx, config
 }
@@ -1210,6 +1268,252 @@
 	ensureContains(t, cFlags, "-Imy_include")
 }
 
+func TestVndkApexCurrent(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		cc_library {
+			name: "libvndksp",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+				support_system_process: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`)
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
+	ensureContains(t, copyCmds, "image.apex/lib/libvndksp.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndksp.so")
+}
+
+func TestVndkApexWithPrebuilt(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_prebuilt_library_shared {
+			name: "libvndkshared",
+			srcs: ["libvndkshared.so"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`, withFiles(map[string][]byte{
+		"libvndkshared.so": nil,
+	}))
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndkshared.so")
+}
+
+func TestVndkApexVersion(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex_v27",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			vndk_version: "27",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		vndk_prebuilt_shared {
+			name: "libvndk27",
+			version: "27",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			srcs: ["libvndk27.so"],
+		}
+	`, withFiles(map[string][]byte{
+		"libvndk27.so": nil,
+	}))
+
+	apexRule := ctx.ModuleForTests("myapex_v27", "android_common_myapex_v27").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndk27.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndk27.so")
+	ensureNotContains(t, copyCmds, "image.apex/lib/libvndk.so")
+}
+
+func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
+	testApexError(t, `module "myapex_v27.*" .*: vndk_version: 27 is already defined in "myapex_v27.*"`, `
+		apex_vndk {
+			name: "myapex_v27",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			vndk_version: "27",
+		}
+		apex_vndk {
+			name: "myapex_v27_other",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			vndk_version: "27",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		vndk_prebuilt_shared {
+			name: "libvndk",
+			version: "27",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			srcs: ["libvndk.so"],
+		}
+	`, withFiles(map[string][]byte{
+		"libvndk.so": nil,
+	}))
+}
+
+func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			native_bridge_supported: true,
+			host_supported: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`, withTargets(map[android.OsType][]android.Target{
+		android.Android: []android.Target{
+			{Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+			{Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+			{Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm64", NativeBridgeRelativePath: "x86_64"},
+			{Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm", NativeBridgeRelativePath: "x86"},
+		},
+	}))
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
+
+	// apex
+	ensureNotContains(t, copyCmds, "image.apex/lib/x86/libvndk.so")
+	ensureNotContains(t, copyCmds, "image.apex/lib64/x86_64/libvndk.so")
+}
+
+func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
+	testApexError(t, `module "myapex" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			native_bridge_supported: true,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			native_bridge_supported: true,
+			host_supported: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`)
+}
+
 func TestDependenciesInApexManifest(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
diff --git a/cc/binary.go b/cc/binary.go
index 17e729c..0d69405 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -454,7 +454,7 @@
 	// The original path becomes a symlink to the corresponding file in the
 	// runtime APEX.
 	translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled || !ctx.Arch().Native
-	if installToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexName() == "" && !ctx.inRecovery() {
+	if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexName() == "" && !ctx.inRecovery() {
 		if ctx.Device() && isBionic(ctx.baseModuleName()) {
 			binary.installSymlinkToRuntimeApex(ctx, file)
 		}
diff --git a/cc/cc.go b/cc/cc.go
index f97ef5a..fb7fca2 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -478,6 +478,19 @@
 	return ""
 }
 
+// IsVndkOnSystem returns true if a module is supposed to be a vndk library provided by system to vendor
+func (c *Module) IsVndkOnSystem() bool {
+	if linker, ok := c.linker.(libraryInterface); ok {
+		return linker.shared() && c.isVndk() && c.useVndk() && !c.isVndkExt()
+	}
+
+	return false
+}
+
+func (c *Module) VndkVersion() string {
+	return c.vndkVersion()
+}
+
 func (c *Module) Init() android.Module {
 	c.AddProperties(&c.Properties, &c.VendorProperties)
 	if c.compiler != nil {
@@ -666,6 +679,10 @@
 }
 
 func (c *Module) nativeCoverage() bool {
+	// Bug: http://b/137883967 - native-bridge modules do not currently work with coverage
+	if c.Target().NativeBridge == android.NativeBridgeEnabled {
+		return false
+	}
 	return c.linker != nil && c.linker.nativeCoverage()
 }
 
@@ -677,7 +694,7 @@
 	return false
 }
 
-func installToBootstrap(name string, config android.Config) bool {
+func InstallToBootstrap(name string, config android.Config) bool {
 	if name == "libclang_rt.hwasan-aarch64-android" {
 		return inList("hwaddress", config.SanitizeDevice())
 	}
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index cd7c410..d37e486 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -236,6 +236,7 @@
 		"cortex-a72":     "${config.ArmClangCortexA53Cflags}",
 		"cortex-a73":     "${config.ArmClangCortexA53Cflags}",
 		"cortex-a75":     "${config.ArmClangCortexA55Cflags}",
+		"cortex-a76":     "${config.ArmClangCortexA55Cflags}",
 		"krait":          "${config.ArmClangKraitCflags}",
 		"kryo":           "${config.ArmClangKryoCflags}",
 		"kryo385":        "${config.ArmClangCortexA53Cflags}",
diff --git a/cc/config/global.go b/cc/config/global.go
index d873494..1bbc6f0 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -123,8 +123,8 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r365631"
-	ClangDefaultShortVersion = "9.0.6"
+	ClangDefaultVersion      = "clang-r365631b"
+	ClangDefaultShortVersion = "9.0.7"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
diff --git a/cc/library.go b/cc/library.go
index 9178a52..c402ea0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -88,6 +88,16 @@
 	// set the name of the output
 	Stem *string `android:"arch_variant"`
 
+	// set suffix of the name of the output
+	Suffix *string `android:"arch_variant"`
+
+	Target struct {
+		Vendor struct {
+			// set suffix of the name of the output
+			Suffix *string `android:"arch_variant"`
+		}
+	}
+
 	// Names of modules to be overridden. Listed modules can only be other shared libraries
 	// (in Make or Soong).
 	// This does not completely prevent installation of the overridden libraries, but if both
@@ -549,7 +559,7 @@
 	androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer)
 }
 
-func (library *libraryDecorator) getLibName(ctx ModuleContext) string {
+func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string {
 	name := library.libName
 	if name == "" {
 		name = String(library.Properties.Stem)
@@ -558,6 +568,16 @@
 		}
 	}
 
+	suffix := ""
+	if ctx.useVndk() {
+		suffix = String(library.Properties.Target.Vendor.Suffix)
+	}
+	if suffix == "" {
+		suffix = String(library.Properties.Suffix)
+	}
+
+	name += suffix
+
 	if ctx.isVndkExt() {
 		name = ctx.getVndkExtendsModuleName()
 	}
@@ -1013,8 +1033,8 @@
 			// The original path becomes a symlink to the corresponding file in the
 			// runtime APEX.
 			translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled || !ctx.Arch().Native
-			if installToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && !translatedArch && !ctx.inRecovery() {
-				if ctx.Device() && isBionic(ctx.baseModuleName()) {
+			if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && !translatedArch && !ctx.inRecovery() {
+				if ctx.Device() {
 					library.installSymlinkToRuntimeApex(ctx, file)
 				}
 				library.baseInstaller.subDir = "bootstrap"
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index dc6c43a..8c72b69 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -19,8 +19,8 @@
 )
 
 func init() {
-	android.RegisterModuleType("cc_prebuilt_library_shared", prebuiltSharedLibraryFactory)
-	android.RegisterModuleType("cc_prebuilt_library_static", prebuiltStaticLibraryFactory)
+	android.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
+	android.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
 	android.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
 }
 
@@ -97,7 +97,7 @@
 
 		if p.shared() {
 			p.unstrippedOutputFile = in
-			libName := ctx.baseModuleName() + flags.Toolchain.ShlibSuffix()
+			libName := p.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
 			if p.needsStrip(ctx) {
 				stripped := android.PathForModuleOut(ctx, "stripped", libName)
 				p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
@@ -131,7 +131,7 @@
 
 // cc_prebuilt_library_shared installs a precompiled shared library that are
 // listed in the srcs property in the device's directory.
-func prebuiltSharedLibraryFactory() android.Module {
+func PrebuiltSharedLibraryFactory() android.Module {
 	module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported)
 	return module.Init()
 }
@@ -158,7 +158,7 @@
 
 // cc_prebuilt_library_static installs a precompiled static library that are
 // listed in the srcs property in the device's directory.
-func prebuiltStaticLibraryFactory() android.Module {
+func PrebuiltStaticLibraryFactory() android.Module {
 	module, _ := NewPrebuiltStaticLibrary(android.HostAndDeviceSupported)
 	return module.Init()
 }
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 98d78e8..edcd26e 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -72,8 +72,8 @@
 
 	ctx := CreateTestContext(bp, fs, android.Android)
 
-	ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(prebuiltSharedLibraryFactory))
-	ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(prebuiltStaticLibraryFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(PrebuiltSharedLibraryFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(PrebuiltStaticLibraryFactory))
 	ctx.RegisterModuleType("cc_prebuilt_binary", android.ModuleFactoryAdaptor(prebuiltBinaryFactory))
 
 	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
diff --git a/cc/strip.go b/cc/strip.go
index f3e3374..7e560ec 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -27,7 +27,6 @@
 		Keep_symbols                 *bool    `android:"arch_variant"`
 		Keep_symbols_list            []string `android:"arch_variant"`
 		Keep_symbols_and_debug_frame *bool    `android:"arch_variant"`
-		Use_gnu_strip                *bool    `android:"arch_variant"`
 	} `android:"arch_variant"`
 }
 
@@ -54,9 +53,6 @@
 		} else if !Bool(stripper.StripProperties.Strip.All) {
 			flags.stripKeepMiniDebugInfo = true
 		}
-		if Bool(stripper.StripProperties.Strip.Use_gnu_strip) {
-			flags.stripUseGnuStrip = true
-		}
 		if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo && !isStaticLib {
 			flags.stripAddGnuDebuglink = true
 		}
diff --git a/cc/test.go b/cc/test.go
index 1a0d44f..a5a3680 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -317,6 +317,10 @@
 	var configs []tradefed.Config
 	if Bool(test.Properties.Require_root) {
 		configs = append(configs, tradefed.Preparer{"com.android.tradefed.targetprep.RootTargetPreparer", nil})
+	} else {
+		var options []tradefed.Option
+		options = append(options, tradefed.Option{"force-root", "false"})
+		configs = append(configs, tradefed.Preparer{"com.android.tradefed.targetprep.RootTargetPreparer", options})
 	}
 	if Bool(test.Properties.Disable_framework) {
 		var options []tradefed.Option
diff --git a/cc/testing.go b/cc/testing.go
index 5a3993c..a0b1634 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -253,7 +253,7 @@
 	ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
 	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
-	ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(vndkPrebuiltSharedFactory))
+	ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(VndkPrebuiltSharedFactory))
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("image", ImageMutator).Parallel()
 		ctx.BottomUp("link", LinkageMutator).Parallel()
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index da357ed..b324334 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -206,11 +206,11 @@
 //            },
 //        },
 //    }
-func vndkPrebuiltSharedFactory() android.Module {
+func VndkPrebuiltSharedFactory() android.Module {
 	module := vndkPrebuiltSharedLibrary()
 	return module.Init()
 }
 
 func init() {
-	android.RegisterModuleType("vndk_prebuilt_shared", vndkPrebuiltSharedFactory)
+	android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
 }
diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go
index 27179cb..a9be612 100644
--- a/cmd/merge_zips/merge_zips.go
+++ b/cmd/merge_zips/merge_zips.go
@@ -417,7 +417,7 @@
 	}
 	oldOlderMiz := miz.older
 	if oldOlderMiz.newer != miz {
-		panic(fmt.Errorf("broken list between %p:%#v and %p:%#v", miz, oldOlderMiz))
+		panic(fmt.Errorf("broken list between %p:%#v and %p:%#v", miz, miz, oldOlderMiz, oldOlderMiz))
 	}
 	miz.older = olderMiz
 	olderMiz.older = oldOlderMiz
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 9eaa1b6..5deac5e 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -17,7 +17,6 @@
 import (
 	"fmt"
 	"path/filepath"
-	"runtime"
 	"strings"
 
 	"github.com/google/blueprint/proptools"
@@ -687,13 +686,6 @@
 }
 
 func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
-	var date string
-	if runtime.GOOS == "darwin" {
-		date = `date -r`
-	} else {
-		date = `date -d @`
-	}
-
 	// Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources.  For modules with 1.9
 	// sources, droiddoc will get sources produced by metalava which will have already stripped out the
 	// 1.9 language features.
@@ -704,7 +696,7 @@
 		FlagWithArg("-doclet ", "com.google.doclava.Doclava").
 		FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
 		FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
-		FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
+		FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
 
 	if String(d.properties.Custom_template) == "" {
 		// TODO: This is almost always droiddoc-templates-sdk
diff --git a/java/proto.go b/java/proto.go
index 22a3eed..f5c233c 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -82,6 +82,7 @@
 			typeToPlugin = "javamicro"
 		case "nano":
 			flags.proto.OutTypeFlag = "--javanano_out"
+			typeToPlugin = "javanano"
 		case "lite":
 			flags.proto.OutTypeFlag = "--java_out"
 			flags.proto.OutParams = append(flags.proto.OutParams, "lite")
diff --git a/rust/rust.go b/rust/rust.go
index 62ccfc7..7cc0b2c 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -334,17 +334,19 @@
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
 		depTag := ctx.OtherModuleDependencyTag(dep)
-		if dep.Target().Os != ctx.Os() {
-			ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
-			return
-		}
-		if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
-			ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
-			return
-		}
 
 		if rustDep, ok := dep.(*Module); ok {
 			//Handle Rust Modules
+
+			if rustDep.Target().Os != ctx.Os() {
+				ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
+				return
+			}
+			if rustDep.Target().Arch.ArchType != ctx.Arch().ArchType {
+				ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
+				return
+			}
+
 			linkFile := rustDep.outputFile
 			if !linkFile.Valid() {
 				ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
@@ -393,8 +395,17 @@
 			}
 
 		} else if ccDep, ok := dep.(*cc.Module); ok {
-
 			//Handle C dependencies
+
+			if ccDep.Target().Os != ctx.Os() {
+				ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
+				return
+			}
+			if ccDep.Target().Arch.ArchType != ctx.Arch().ArchType {
+				ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
+				return
+			}
+
 			linkFile := ccDep.OutputFile()
 			linkPath := linkPathFromFilePath(linkFile.Path())
 			libName := libNameFromFilePath(linkFile.Path())
diff --git a/scripts/strip.sh b/scripts/strip.sh
index 52f9366..f987d98 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -29,7 +29,6 @@
 #   --keep-mini-debug-info
 #   --keep-symbols
 #   --keep-symbols-and-debug-frame
-#   --use-gnu-strip
 #   --remove-build-id
 
 set -o pipefail
@@ -44,86 +43,55 @@
         --keep-mini-debug-info          Keep compressed debug info in out-file
         --keep-symbols                  Keep symbols in out-file
         --keep-symbols-and-debug-frame  Keep symbols and .debug_frame in out-file
-        --use-gnu-strip                 Use strip/objcopy instead of llvm-{strip,objcopy}
         --remove-build-id               Remove the gnu build-id section in out-file
 EOF
     exit 1
 }
 
-# Without --use-gnu-strip, GNU strip is replaced with llvm-strip to work around
-# old GNU strip bug on lld output files, b/80093681.
-# Similary, calls to objcopy are replaced with llvm-objcopy,
-# with some exceptions.
-
 do_strip() {
-    # ${CROSS_COMPILE}strip --strip-all does not strip .ARM.attributes,
+    # GNU strip --strip-all does not strip .ARM.attributes,
     # so we tell llvm-strip to keep it too.
-    if [ -z "${use_gnu_strip}" ]; then
-        "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes "${infile}" -o "${outfile}.tmp"
-    else
-        "${CROSS_COMPILE}strip" --strip-all "${infile}" -o "${outfile}.tmp"
-    fi
+    "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes "${infile}" -o "${outfile}.tmp"
 }
 
 do_strip_keep_symbols_and_debug_frame() {
-    REMOVE_SECTIONS=`"${CROSS_COMPILE}readelf" -S "${infile}" | awk '/.debug_/ {if ($2 != ".debug_frame") {print "--remove-section " $2}}' | xargs`
-    if [ -z "${use_gnu_strip}" ]; then
-        "${CLANG_BIN}/llvm-objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
-    else
-        "${CROSS_COMPILE}objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
-    fi
+    REMOVE_SECTIONS=`"${CLANG_BIN}/llvm-readelf" -S "${infile}" | awk '/.debug_/ {if ($2 != ".debug_frame") {print "--remove-section " $2}}' | xargs`
+    "${CLANG_BIN}/llvm-objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
 }
 
 do_strip_keep_symbols() {
-    REMOVE_SECTIONS=`"${CROSS_COMPILE}readelf" -S "${infile}" | awk '/.debug_/ {print "--remove-section " $2}' | xargs`
-    if [ -z "${use_gnu_strip}" ]; then
-        "${CLANG_BIN}/llvm-objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
-    else
-        "${CROSS_COMPILE}objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
-    fi
+    REMOVE_SECTIONS=`"${CLANG_BIN}/llvm-readelf" -S "${infile}" | awk '/.debug_/ {print "--remove-section " $2}' | xargs`
+    "${CLANG_BIN}/llvm-objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
 }
 
 do_strip_keep_symbol_list() {
     echo "${symbols_to_keep}" | tr ',' '\n' > "${outfile}.symbolList"
 
-    if [ -z "${use_gnu_strip}" ]; then
-        KEEP_SYMBOLS="--strip-unneeded-symbol=.* --keep-symbols="
-        KEEP_SYMBOLS+="${outfile}.symbolList"
-        "${CLANG_BIN}/llvm-objcopy" --regex "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
-    else
-        KEEP_SYMBOLS="--strip-unneeded-symbol=* --keep-symbols="
-        KEEP_SYMBOLS+="${outfile}.symbolList"
-        "${CROSS_COMPILE}objcopy" -w "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
-    fi
+    KEEP_SYMBOLS="--strip-unneeded-symbol=.* --keep-symbols="
+    KEEP_SYMBOLS+="${outfile}.symbolList"
+    "${CLANG_BIN}/llvm-objcopy" --regex "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
 }
 
 do_strip_keep_mini_debug_info() {
     rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
     local fail=
-    if [ -z "${use_gnu_strip}" ]; then
-        "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true
-    else
-        "${CROSS_COMPILE}strip" --strip-all -R .comment "${infile}" -o "${outfile}.tmp" || fail=true
-    fi
+    "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true
+
     if [ -z $fail ]; then
-        # Current prebult llvm-objcopy does not support the following flags:
-        #    --only-keep-debug --rename-section --keep-symbols
-        # For the following use cases, ${CROSS_COMPILE}objcopy does fine with lld linked files,
-        # except the --add-section flag.
+        # Current prebult llvm-objcopy does not support --only-keep-debug flag,
+        # and cannot process object files that are produced with the flag. Use
+        # GNU objcopy instead for now. (b/141010852)
         "${CROSS_COMPILE}objcopy" --only-keep-debug "${infile}" "${outfile}.debug"
-        "${CROSS_COMPILE}nm" -D "${infile}" --format=posix --defined-only 2> /dev/null | awk '{ print $1 }' | sort >"${outfile}.dynsyms"
-        "${CROSS_COMPILE}nm" "${infile}" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }' | sort > "${outfile}.funcsyms"
+        "${CLANG_BIN}/llvm-nm" -D "${infile}" --format=posix --defined-only 2> /dev/null | awk '{ print $1 }' | sort >"${outfile}.dynsyms"
+        "${CLANG_BIN}/llvm-nm" "${infile}" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }' | sort > "${outfile}.funcsyms"
         comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols"
         echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty.
         "${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo"
         "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo"
         "${CROSS_COMPILE}objcopy" --rename-section saved_debug_frame=.debug_frame "${outfile}.mini_debuginfo"
         "${XZ}" "${outfile}.mini_debuginfo"
-        if [ -z "${use_gnu_strip}" ]; then
-            "${CLANG_BIN}/llvm-objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
-        else
-            "${CROSS_COMPILE}objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
-        fi
+
+        "${CLANG_BIN}/llvm-objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
         rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
     else
         cp -f "${infile}" "${outfile}.tmp"
@@ -131,19 +99,11 @@
 }
 
 do_add_gnu_debuglink() {
-    if [ -z "${use_gnu_strip}" ]; then
-        "${CLANG_BIN}/llvm-objcopy" --add-gnu-debuglink="${infile}" "${outfile}.tmp"
-    else
-        "${CROSS_COMPILE}objcopy" --add-gnu-debuglink="${infile}" "${outfile}.tmp"
-    fi
+    "${CLANG_BIN}/llvm-objcopy" --add-gnu-debuglink="${infile}" "${outfile}.tmp"
 }
 
 do_remove_build_id() {
-    if [ -z "${use_gnu_strip}" ]; then
-        "${CLANG_BIN}/llvm-strip" --remove-section=.note.gnu.build-id "${outfile}.tmp" -o "${outfile}.tmp.no-build-id"
-    else
-        "${CROSS_COMPILE}strip" --remove-section=.note.gnu.build-id "${outfile}.tmp" -o "${outfile}.tmp.no-build-id"
-    fi
+    "${CLANG_BIN}/llvm-strip" --remove-section=.note.gnu.build-id "${outfile}.tmp" -o "${outfile}.tmp.no-build-id"
     rm -f "${outfile}.tmp"
     mv "${outfile}.tmp.no-build-id" "${outfile}.tmp"
 }
@@ -161,7 +121,6 @@
                 keep-symbols) keep_symbols=true ;;
                 keep-symbols-and-debug-frame) keep_symbols_and_debug_frame=true ;;
                 remove-build-id) remove_build_id=true ;;
-                use-gnu-strip) use_gnu_strip=true ;;
                 *) echo "Unknown option --${OPTARG}"; usage ;;
             esac;;
         ?) usage ;;
@@ -234,18 +193,13 @@
 rm -f "${outfile}"
 mv "${outfile}.tmp" "${outfile}"
 
-if [ -z "${use_gnu_strip}" ]; then
-  USED_STRIP_OBJCOPY="${CLANG_BIN}/llvm-strip ${CLANG_BIN}/llvm-objcopy"
-else
-  USED_STRIP_OBJCOPY="${CROSS_COMPILE}strip"
-fi
-
 cat <<EOF > "${depsfile}"
 ${outfile}: \
   ${infile} \
-  ${CROSS_COMPILE}nm \
   ${CROSS_COMPILE}objcopy \
-  ${CROSS_COMPILE}readelf \
-  ${USED_STRIP_OBJCOPY}
+  ${CLANG_BIN}/llvm-nm \
+  ${CLANG_BIN}/llvm-objcopy \
+  ${CLANG_BIN}/llvm-readelf \
+  ${CLANG_BIN}/llvm-strip
 
 EOF
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 786e7d3..e44600e 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -118,9 +118,6 @@
 	"ld.gold":    Forbidden,
 	"pkg-config": Forbidden,
 
-	// These are currently Linux-only toybox tools (but can be switched now).
-	"date": LinuxOnlyPrebuilt,
-
 	// These are toybox tools that only work on Linux.
 	"pgrep": LinuxOnlyPrebuilt,
 	"pkill": LinuxOnlyPrebuilt,