Merge "Add "apex_vndk" module type"
diff --git a/Android.bp b/Android.bp
index 537b58b..25038c6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -208,7 +208,6 @@
         "cc/prebuilt_test.go",
         "cc/proto_test.go",
         "cc/test_data_test.go",
-        "cc/util_test.go",
     ],
     pluginFor: ["soong_build"],
 }
diff --git a/android/mutator.go b/android/mutator.go
index 8e4343d..e76f847 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -244,8 +244,8 @@
 }
 
 func (t *topDownMutatorContext) CreateModule(factory blueprint.ModuleFactory, props ...interface{}) {
-	common := []interface{}{&t.Module().base().commonProperties}
-	t.bp.CreateModule(factory, append(common, props...)...)
+	inherited := []interface{}{&t.Module().base().commonProperties, &t.Module().base().variableProperties}
+	t.bp.CreateModule(factory, append(inherited, props...)...)
 }
 
 func (b *bottomUpMutatorContext) MutatorName() string {
diff --git a/android/util.go b/android/util.go
index e02cca1..0102442 100644
--- a/android/util.go
+++ b/android/util.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"path/filepath"
 	"reflect"
 	"regexp"
 	"runtime"
@@ -292,3 +293,29 @@
 	}
 	return strings.HasPrefix(str, pat[:i]) && strings.HasSuffix(str, pat[i+1:])
 }
+
+var shlibVersionPattern = regexp.MustCompile("(?:\\.\\d+(?:svn)?)+")
+
+// splitFileExt splits a file name into root, suffix and ext. root stands for the file name without
+// the file extension and the version number (e.g. "libexample"). suffix stands for the
+// concatenation of the file extension and the version number (e.g. ".so.1.0"). ext stands for the
+// file extension after the version numbers are trimmed (e.g. ".so").
+func SplitFileExt(name string) (string, string, string) {
+	// Extract and trim the shared lib version number if the file name ends with dot digits.
+	suffix := ""
+	matches := shlibVersionPattern.FindAllStringIndex(name, -1)
+	if len(matches) > 0 {
+		lastMatch := matches[len(matches)-1]
+		if lastMatch[1] == len(name) {
+			suffix = name[lastMatch[0]:lastMatch[1]]
+			name = name[0:lastMatch[0]]
+		}
+	}
+
+	// Extract the file name root and the file extension.
+	ext := filepath.Ext(name)
+	root := strings.TrimSuffix(name, ext)
+	suffix = ext + suffix
+
+	return root, suffix, ext
+}
diff --git a/android/util_test.go b/android/util_test.go
index 2e5eb07..1df1c5a 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -404,3 +404,68 @@
 	// b = ["foo" "bar"]
 	// c = ["foo" "baz"]
 }
+
+func TestSplitFileExt(t *testing.T) {
+	t.Run("soname with version", func(t *testing.T) {
+		root, suffix, ext := SplitFileExt("libtest.so.1.0.30")
+		expected := "libtest"
+		if root != expected {
+			t.Errorf("root should be %q but got %q", expected, root)
+		}
+		expected = ".so.1.0.30"
+		if suffix != expected {
+			t.Errorf("suffix should be %q but got %q", expected, suffix)
+		}
+		expected = ".so"
+		if ext != expected {
+			t.Errorf("ext should be %q but got %q", expected, ext)
+		}
+	})
+
+	t.Run("soname with svn version", func(t *testing.T) {
+		root, suffix, ext := SplitFileExt("libtest.so.1svn")
+		expected := "libtest"
+		if root != expected {
+			t.Errorf("root should be %q but got %q", expected, root)
+		}
+		expected = ".so.1svn"
+		if suffix != expected {
+			t.Errorf("suffix should be %q but got %q", expected, suffix)
+		}
+		expected = ".so"
+		if ext != expected {
+			t.Errorf("ext should be %q but got %q", expected, ext)
+		}
+	})
+
+	t.Run("version numbers in the middle should be ignored", func(t *testing.T) {
+		root, suffix, ext := SplitFileExt("libtest.1.0.30.so")
+		expected := "libtest.1.0.30"
+		if root != expected {
+			t.Errorf("root should be %q but got %q", expected, root)
+		}
+		expected = ".so"
+		if suffix != expected {
+			t.Errorf("suffix should be %q but got %q", expected, suffix)
+		}
+		expected = ".so"
+		if ext != expected {
+			t.Errorf("ext should be %q but got %q", expected, ext)
+		}
+	})
+
+	t.Run("no known file extension", func(t *testing.T) {
+		root, suffix, ext := SplitFileExt("test.exe")
+		expected := "test"
+		if root != expected {
+			t.Errorf("root should be %q but got %q", expected, root)
+		}
+		expected = ".exe"
+		if suffix != expected {
+			t.Errorf("suffix should be %q but got %q", expected, suffix)
+		}
+		if ext != expected {
+			t.Errorf("ext should be %q but got %q", expected, ext)
+		}
+	})
+}
diff --git a/apex/apex.go b/apex/apex.go
index 0186b85..4f79c42 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -99,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")
@@ -197,6 +198,7 @@
 	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("apex_deps", apexDepsMutator)
 		ctx.BottomUp("apex", apexMutator).Parallel()
+		ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
 		ctx.BottomUp("apex_uses", apexUsesMutator).Parallel()
 	})
 }
@@ -283,6 +285,17 @@
 		mctx.CreateVariations(apexBundleName)
 	}
 }
+
+func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
+	if _, ok := mctx.Module().(*apexBundle); ok {
+		if !mctx.Config().FlattenApex() || mctx.Config().UnbundledBuild() {
+			modules := mctx.CreateLocalVariations("", "flattened")
+			modules[0].(*apexBundle).SetFlattened(false)
+			modules[1].(*apexBundle).SetFlattened(true)
+		}
+	}
+}
+
 func apexUsesMutator(mctx android.BottomUpMutatorContext) {
 	if ab, ok := mctx.Module().(*apexBundle); ok {
 		mctx.AddFarVariationDependencies(nil, usesTag, ab.properties.Uses...)
@@ -392,6 +405,10 @@
 
 	// List of APKs to package inside APEX
 	Apps []string
+
+	// To distinguish between flattened and non-flattened variants.
+	// if set true, then this variant is flattened variant.
+	Flattened bool `blueprint:"mutated"`
 }
 
 type apexTargetBundleProperties struct {
@@ -544,13 +561,14 @@
 	// list of module names that this APEX is depending on
 	externalDeps []string
 
-	flattened bool
-
 	testApex bool
 	vndkApex bool
 
 	// intermediate path for apex_manifest.json
 	manifestOut android.WritablePath
+
+	// A config value of (TARGET_FLATTEN_APEX && !TARGET_BUILD_APPS)
+	flattenedConfigValue bool
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -738,7 +756,7 @@
 			return nil, nil
 		}
 	case ".flattened":
-		if a.flattened {
+		if a.properties.Flattened {
 			flattenedApexPath := a.flattenedOutput
 			return android.Paths{flattenedApexPath}, nil
 		} else {
@@ -797,38 +815,40 @@
 	a.properties.HideFromMake = true
 }
 
-func getCopyManifestForNativeLibrary(cc *cc.Module, handleSpecialLibs bool) (fileToCopy android.Path, dirInApex string) {
+func (a *apexBundle) SetFlattened(flattened bool) {
+	a.properties.Flattened = flattened
+}
+
+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
 }
 
@@ -964,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 {
@@ -1095,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
 					}
@@ -1120,7 +1140,10 @@
 		return false
 	})
 
-	a.flattened = ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
+	a.flattenedConfigValue = ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
+	if a.flattenedConfigValue {
+		a.properties.Flattened = true
+	}
 	if a.private_key_file == nil {
 		ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.properties.Key))
 		return
@@ -1459,7 +1482,7 @@
 	})
 
 	// Install to $OUT/soong/{target,host}/.../apex
-	if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) {
+	if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) && (!a.properties.Flattened || a.flattenedConfigValue) {
 		ctx.InstallFile(a.installDir, ctx.ModuleName()+suffix, a.outputFiles[apexType])
 	}
 }
@@ -1519,20 +1542,32 @@
 		if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake {
 			continue
 		}
-		if !android.InList(fi.moduleName, moduleNames) {
-			moduleNames = append(moduleNames, fi.moduleName)
+		if a.properties.Flattened && !apexType.image() {
+			continue
 		}
+
+		var suffix string
+		if a.properties.Flattened && !a.flattenedConfigValue {
+			suffix = ".flattened"
+		}
+
+		if !android.InList(fi.moduleName, moduleNames) {
+			moduleNames = append(moduleNames, fi.moduleName+suffix)
+		}
+
 		fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
 		fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
-		fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName)
+		fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName+suffix)
 		// /apex/<name>/{lib|framework|...}
 		pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex",
 			proptools.StringDefault(a.properties.Apex_name, name), fi.installDir)
-		if a.flattened && apexType.image() {
+		if a.properties.Flattened && apexType.image() {
 			// /system/apex/<name>/{lib|framework|...}
 			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)",
 				a.installDir.RelPathString(), name, fi.installDir))
-			fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
+			if a.flattenedConfigValue {
+				fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
+			}
 			if len(fi.symlinks) > 0 {
 				fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " "))
 			}
@@ -1584,7 +1619,7 @@
 			fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
 			fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
 			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
-		} else if fi.class == nativeSharedLib || fi.class == nativeExecutable {
+		} else if fi.class == nativeSharedLib || fi.class == nativeExecutable || fi.class == nativeTest {
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
 			if cc, ok := fi.module.(*cc.Module); ok {
 				if cc.UnstrippedOutputFile() != nil {
@@ -1612,7 +1647,11 @@
 				moduleNames = a.androidMkForFiles(w, name, moduleDir, apexType)
 			}
 
-			if a.flattened && apexType.image() {
+			if a.properties.Flattened && !a.flattenedConfigValue {
+				name = name + ".flattened"
+			}
+
+			if a.properties.Flattened && apexType.image() {
 				// Only image APEXes can be flattened.
 				fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
 				fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
@@ -1623,7 +1662,7 @@
 				fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
 				fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): .KATI_IMPLICIT_OUTPUTS :=", a.flattenedOutput.String())
 
-			} else {
+			} 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 {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 4b0cb31..66dd838 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -207,7 +207,7 @@
 		library.androidMkWriteExportedFlags(w)
 		library.androidMkWriteAdditionalDependenciesForSourceAbiDiff(w)
 
-		_, _, ext := splitFileExt(outputFile.Base())
+		_, _, ext := android.SplitFileExt(outputFile.Base())
 
 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
 
@@ -319,7 +319,7 @@
 func (library *toolchainLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
 	ret.Class = "STATIC_LIBRARIES"
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
-		_, suffix, _ := splitFileExt(outputFile.Base())
+		_, suffix, _ := android.SplitFileExt(outputFile.Base())
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
 	})
 }
@@ -334,7 +334,7 @@
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		path := installer.path.RelPathString()
 		dir, file := filepath.Split(path)
-		stem, suffix, _ := splitFileExt(file)
+		stem, suffix, _ := android.SplitFileExt(file)
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
@@ -347,7 +347,7 @@
 
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		path, file := filepath.Split(c.installPath.String())
-		stem, suffix, _ := splitFileExt(file)
+		stem, suffix, _ := android.SplitFileExt(file)
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
@@ -361,7 +361,7 @@
 
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		c.libraryDecorator.androidMkWriteExportedFlags(w)
-		_, _, ext := splitFileExt(outputFile.Base())
+		_, _, ext := android.SplitFileExt(outputFile.Base())
 
 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
 		fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
@@ -380,7 +380,7 @@
 
 		path := c.path.RelPathString()
 		dir, file := filepath.Split(path)
-		stem, suffix, ext := splitFileExt(file)
+		stem, suffix, ext := android.SplitFileExt(file)
 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
@@ -398,7 +398,7 @@
 
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		c.libraryDecorator.androidMkWriteExportedFlags(w)
-		_, _, ext := splitFileExt(outputFile.Base())
+		_, _, ext := android.SplitFileExt(outputFile.Base())
 
 		fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
 		fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
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 cd832cb..fb7fca2 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -679,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()
 }
 
@@ -690,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())
 	}
@@ -2336,6 +2340,9 @@
 		// If the device isn't compiling against the VNDK, we always
 		// use the core mode.
 		coreVariantNeeded = true
+	} else if m.Target().NativeBridge == android.NativeBridgeEnabled {
+		// Skip creating vendor variants for natvie bridge modules
+		coreVariantNeeded = true
 	} else if _, ok := m.linker.(*llndkStubDecorator); ok {
 		// LL-NDK stubs only exist in the vendor variant, since the
 		// real libraries will be used in the core variant.
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/clang.go b/cc/config/clang.go
index 1f169e4..3636ae9 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -171,9 +171,6 @@
 		// Disable c++98-specific warning since Android is not concerned with C++98
 		// compatibility.
 		"-Wno-c++98-compat-extra-semi",
-
-		// Disable this warning because we don't care about behavior with older compilers.
-		"-Wno-return-std-move-in-c++11",
 	}, " "))
 
 	// Extra cflags for projects under external/ directory to disable warnings that are infeasible
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/config/vndk.go b/cc/config/vndk.go
index e754ad5..d7d8955 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -120,6 +120,8 @@
 	"libmedia_omx",
 	"libmemtrack",
 	"libnetutils",
+	"libprotobuf-cpp-full",
+	"libprotobuf-cpp-lite",
 	"libpuresoftkeymasterdevice",
 	"libradio_metadata",
 	"libselinux",
diff --git a/cc/fuzz.go b/cc/fuzz.go
index d44c02d..b0fb262 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -15,9 +15,12 @@
 package cc
 
 import (
+	"path/filepath"
+
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 	"android/soong/cc/config"
-	"github.com/google/blueprint/proptools"
 )
 
 func init() {
@@ -78,21 +81,14 @@
 }
 
 func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
-	fuzz.binaryDecorator.baseInstaller.dir = "fuzz"
-	fuzz.binaryDecorator.baseInstaller.dir64 = "fuzz"
+	fuzz.binaryDecorator.baseInstaller.dir = filepath.Join("fuzz", ctx.Target().Arch.ArchType.String())
+	fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join("fuzz", ctx.Target().Arch.ArchType.String())
 	fuzz.binaryDecorator.baseInstaller.install(ctx, file)
 }
 
 func NewFuzz(hod android.HostOrDeviceSupported) *Module {
 	module, binary := NewBinary(hod)
 
-	// TODO(mitchp): The toolchain does not currently export the x86 (32-bit)
-	// variant of libFuzzer for host. There is no way to only disable the host
-	// 32-bit variant, so we specify cc_fuzz targets as 64-bit only. This doesn't
-	// hurt anyone, as cc_fuzz is mostly for experimental targets as of this
-	// moment.
-	module.multilib = "64"
-
 	binary.baseInstaller = NewFuzzInstaller()
 	module.sanitize.SetSanitizer(fuzzer, true)
 
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 3455691..8c72b69 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -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)
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/util.go b/cc/util.go
index 7b8ad18..2f7bec2 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -104,32 +104,6 @@
 	return list
 }
 
-var shlibVersionPattern = regexp.MustCompile("(?:\\.\\d+(?:svn)?)+")
-
-// splitFileExt splits a file name into root, suffix and ext. root stands for the file name without
-// the file extension and the version number (e.g. "libexample"). suffix stands for the
-// concatenation of the file extension and the version number (e.g. ".so.1.0"). ext stands for the
-// file extension after the version numbers are trimmed (e.g. ".so").
-func splitFileExt(name string) (string, string, string) {
-	// Extract and trim the shared lib version number if the file name ends with dot digits.
-	suffix := ""
-	matches := shlibVersionPattern.FindAllStringIndex(name, -1)
-	if len(matches) > 0 {
-		lastMatch := matches[len(matches)-1]
-		if lastMatch[1] == len(name) {
-			suffix = name[lastMatch[0]:lastMatch[1]]
-			name = name[0:lastMatch[0]]
-		}
-	}
-
-	// Extract the file name root and the file extension.
-	ext := filepath.Ext(name)
-	root := strings.TrimSuffix(name, ext)
-	suffix = ext + suffix
-
-	return root, suffix, ext
-}
-
 // linkDirOnDevice/linkName -> target
 func makeSymlinkCmd(linkDirOnDevice string, linkName string, target string) string {
 	dir := filepath.Join("$(PRODUCT_OUT)", linkDirOnDevice)
diff --git a/cc/util_test.go b/cc/util_test.go
deleted file mode 100644
index 7c718ea..0000000
--- a/cc/util_test.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cc
-
-import (
-	"testing"
-)
-
-func TestSplitFileExt(t *testing.T) {
-	t.Run("soname with version", func(t *testing.T) {
-		root, suffix, ext := splitFileExt("libtest.so.1.0.30")
-		expected := "libtest"
-		if root != expected {
-			t.Errorf("root should be %q but got %q", expected, root)
-		}
-		expected = ".so.1.0.30"
-		if suffix != expected {
-			t.Errorf("suffix should be %q but got %q", expected, suffix)
-		}
-		expected = ".so"
-		if ext != expected {
-			t.Errorf("ext should be %q but got %q", expected, ext)
-		}
-	})
-
-	t.Run("soname with svn version", func(t *testing.T) {
-		root, suffix, ext := splitFileExt("libtest.so.1svn")
-		expected := "libtest"
-		if root != expected {
-			t.Errorf("root should be %q but got %q", expected, root)
-		}
-		expected = ".so.1svn"
-		if suffix != expected {
-			t.Errorf("suffix should be %q but got %q", expected, suffix)
-		}
-		expected = ".so"
-		if ext != expected {
-			t.Errorf("ext should be %q but got %q", expected, ext)
-		}
-	})
-
-	t.Run("version numbers in the middle should be ignored", func(t *testing.T) {
-		root, suffix, ext := splitFileExt("libtest.1.0.30.so")
-		expected := "libtest.1.0.30"
-		if root != expected {
-			t.Errorf("root should be %q but got %q", expected, root)
-		}
-		expected = ".so"
-		if suffix != expected {
-			t.Errorf("suffix should be %q but got %q", expected, suffix)
-		}
-		expected = ".so"
-		if ext != expected {
-			t.Errorf("ext should be %q but got %q", expected, ext)
-		}
-	})
-
-	t.Run("no known file extension", func(t *testing.T) {
-		root, suffix, ext := splitFileExt("test.exe")
-		expected := "test"
-		if root != expected {
-			t.Errorf("root should be %q but got %q", expected, root)
-		}
-		expected = ".exe"
-		if suffix != expected {
-			t.Errorf("suffix should be %q but got %q", expected, suffix)
-		}
-		if ext != expected {
-			t.Errorf("ext should be %q but got %q", expected, ext)
-		}
-	})
-}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 1dfe8ea..b324334 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -139,6 +139,10 @@
 	return nil
 }
 
+func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool {
+	return false
+}
+
 func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) {
 	arches := ctx.DeviceConfig().Arches()
 	if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
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/aar.go b/java/aar.go
index f5d7e97..6a883d3 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -220,14 +220,13 @@
 	manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, sdkLibraries,
 		a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode)
 
-	a.transitiveManifestPaths = append(android.Paths{manifestPath}, transitiveStaticLibManifests...)
+	// Add additional manifest files to transitive manifests.
+	additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
+	a.transitiveManifestPaths = append(android.Paths{manifestPath}, additionalManifests...)
+	a.transitiveManifestPaths = append(a.transitiveManifestPaths, transitiveStaticLibManifests...)
 
-	if len(transitiveStaticLibManifests) > 0 {
-		// Merge additional manifest files with app manifest.
-		additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
-		additionalManifests = append(additionalManifests, transitiveStaticLibManifests...)
-
-		a.mergedManifestFile = manifestMerger(ctx, manifestPath, additionalManifests, a.isLibrary)
+	if len(a.transitiveManifestPaths) > 1 {
+		a.mergedManifestFile = manifestMerger(ctx, a.transitiveManifestPaths[0], a.transitiveManifestPaths[1:], a.isLibrary)
 		if !a.isLibrary {
 			// Only use the merged manifest for applications.  For libraries, the transitive closure of manifests
 			// will be propagated to the final application and merged there.  The merged manifest for libraries is
diff --git a/java/app_builder.go b/java/app_builder.go
index 348c8b4..ec2f6da 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -31,31 +31,13 @@
 var (
 	Signapk = pctx.AndroidStaticRule("signapk",
 		blueprint.RuleParams{
-			Command: `${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname $signapkJniLibrary) ` +
-				`-jar $signapkCmd $flags $certificates $in $out`,
-			CommandDeps: []string{"$signapkCmd", "$signapkJniLibrary"},
+			Command: `${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` +
+				`-jar ${config.SignapkCmd} $flags $certificates $in $out`,
+			CommandDeps: []string{"${config.SignapkCmd}", "${config.SignapkJniLibrary}"},
 		},
 		"flags", "certificates")
-
-	androidManifestMerger = pctx.AndroidStaticRule("androidManifestMerger",
-		blueprint.RuleParams{
-			Command: "java -classpath $androidManifestMergerCmd com.android.manifmerger.Main merge " +
-				"--main $in --libs $libsManifests --out $out",
-			CommandDeps: []string{"$androidManifestMergerCmd"},
-			Description: "merge manifest files",
-		},
-		"libsManifests")
 )
 
-func init() {
-	pctx.SourcePathVariable("androidManifestMergerCmd", "prebuilts/devtools/tools/lib/manifest-merger.jar")
-	pctx.HostBinToolVariable("aaptCmd", "aapt")
-	pctx.HostJavaToolVariable("signapkCmd", "signapk.jar")
-	// TODO(ccross): this should come from the signapk dependencies, but we don't have any way
-	// to express host JNI dependencies yet.
-	pctx.HostJNIToolVariable("signapkJniLibrary", "libconscrypt_openjdk_jni")
-}
-
 var combineApk = pctx.AndroidStaticRule("combineApk",
 	blueprint.RuleParams{
 		Command:     `${config.MergeZipsCmd} $out $in`,
diff --git a/java/config/config.go b/java/config/config.go
index 6be83c3..ce62b93 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -141,27 +141,66 @@
 
 	pctx.HostJavaToolVariable("JacocoCLIJar", "jacoco-cli.jar")
 
-	hostBinToolVariableWithPrebuilt := func(name, prebuiltDir, tool string) {
-		pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
-			if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
-				return filepath.Join(prebuiltDir, runtime.GOOS, "bin", tool)
-			} else {
-				return pctx.HostBinToolPath(ctx, tool).String()
-			}
-		})
-	}
-
-	hostBinToolVariableWithPrebuilt("Aapt2Cmd", "prebuilts/sdk/tools", "aapt2")
-
 	pctx.HostBinToolVariable("ManifestCheckCmd", "manifest_check")
 	pctx.HostBinToolVariable("ManifestFixerCmd", "manifest_fixer")
 
 	pctx.HostBinToolVariable("ManifestMergerCmd", "manifest-merger")
 
-	pctx.HostBinToolVariable("ZipAlign", "zipalign")
-
 	pctx.HostBinToolVariable("Class2Greylist", "class2greylist")
 	pctx.HostBinToolVariable("HiddenAPI", "hiddenapi")
+
+	hostBinToolVariableWithSdkToolsPrebuilt("Aapt2Cmd", "aapt2")
+	hostBinToolVariableWithBuildToolsPrebuilt("AidlCmd", "aidl")
+	hostBinToolVariableWithBuildToolsPrebuilt("ZipAlign", "zipalign")
+
+	hostJavaToolVariableWithSdkToolsPrebuilt("SignapkCmd", "signapk")
+	// TODO(ccross): this should come from the signapk dependencies, but we don't have any way
+	// to express host JNI dependencies yet.
+	hostJNIToolVariableWithSdkToolsPrebuilt("SignapkJniLibrary", "libconscrypt_openjdk_jni")
+}
+
+func hostBinToolVariableWithSdkToolsPrebuilt(name, tool string) {
+	pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
+		if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+			return filepath.Join("prebuilts/sdk/tools", runtime.GOOS, "bin", tool)
+		} else {
+			return pctx.HostBinToolPath(ctx, tool).String()
+		}
+	})
+}
+
+func hostJavaToolVariableWithSdkToolsPrebuilt(name, tool string) {
+	pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
+		if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+			return filepath.Join("prebuilts/sdk/tools/lib", tool+".jar")
+		} else {
+			return pctx.HostJavaToolPath(ctx, tool+".jar").String()
+		}
+	})
+}
+
+func hostJNIToolVariableWithSdkToolsPrebuilt(name, tool string) {
+	pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
+		if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+			ext := ".so"
+			if runtime.GOOS == "darwin" {
+				ext = ".dylib"
+			}
+			return filepath.Join("prebuilts/sdk/tools", runtime.GOOS, "lib64", tool+ext)
+		} else {
+			return pctx.HostJNIToolPath(ctx, tool).String()
+		}
+	})
+}
+
+func hostBinToolVariableWithBuildToolsPrebuilt(name, tool string) {
+	pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
+		if ctx.Config().UnbundledBuild() || ctx.Config().IsPdkBuild() {
+			return filepath.Join("prebuilts/build-tools", ctx.Config().PrebuiltOS(), "bin", tool)
+		} else {
+			return pctx.HostBinToolPath(ctx, tool).String()
+		}
+	})
 }
 
 // JavaCmd returns a SourcePath object with the path to the java command.
diff --git a/java/config/makevars.go b/java/config/makevars.go
index ead298a..c40f4fc 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -82,4 +82,17 @@
 	ctx.Strict("HIDDENAPI", "${HiddenAPI}")
 
 	ctx.Strict("DEX_FLAGS", "${DexFlags}")
+
+	ctx.Strict("AIDL", "${AidlCmd}")
+	ctx.Strict("AAPT2", "${Aapt2Cmd}")
+	ctx.Strict("ZIPALIGN", "${ZipAlign}")
+	ctx.Strict("SIGNAPK_JAR", "${SignapkCmd}")
+	ctx.Strict("SIGNAPK_JNI_LIBRARY_PATH", "${SignapkJniLibrary}")
+
+	ctx.Strict("SOONG_ZIP", "${SoongZipCmd}")
+	ctx.Strict("MERGE_ZIPS", "${MergeZipsCmd}")
+	ctx.Strict("ZIP2ZIP", "${Zip2ZipCmd}")
+
+	ctx.Strict("ZIPTIME", "${Ziptime}")
+
 }
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/gen.go b/java/gen.go
index 532a22c..a69e9a2 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -23,7 +23,6 @@
 )
 
 func init() {
-	pctx.HostBinToolVariable("aidlCmd", "aidl")
 	pctx.HostBinToolVariable("syspropCmd", "sysprop_java")
 	pctx.SourcePathVariable("logtagsCmd", "build/make/tools/java-event-log-tags.py")
 	pctx.SourcePathVariable("mergeLogtagsCmd", "build/make/tools/merge-event-log-tags.py")
@@ -33,8 +32,8 @@
 var (
 	aidl = pctx.AndroidStaticRule("aidl",
 		blueprint.RuleParams{
-			Command:     "$aidlCmd -d$depFile $aidlFlags $in $out",
-			CommandDeps: []string{"$aidlCmd"},
+			Command:     "${config.AidlCmd} -d$depFile $aidlFlags $in $out",
+			CommandDeps: []string{"${config.AidlCmd}"},
 		},
 		"depFile", "aidlFlags")
 
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/androidmk.go b/rust/androidmk.go
index c9056e1..107959f 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -18,7 +18,6 @@
 	"fmt"
 	"io"
 	"path/filepath"
-	"regexp"
 	"strings"
 
 	"android/soong/android"
@@ -119,37 +118,9 @@
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		path := compiler.path.RelPathString()
 		dir, file := filepath.Split(path)
-		stem, suffix, _ := splitFileExt(file)
+		stem, suffix, _ := android.SplitFileExt(file)
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
 	})
 }
-
-//TODO: splitFileExt copied from cc/util.go; move this to android/util.go and refactor usages.
-
-// splitFileExt splits a file name into root, suffix and ext. root stands for the file name without
-// the file extension and the version number (e.g. "libexample"). suffix stands for the
-// concatenation of the file extension and the version number (e.g. ".so.1.0"). ext stands for the
-// file extension after the version numbers are trimmed (e.g. ".so").
-var shlibVersionPattern = regexp.MustCompile("(?:\\.\\d+(?:svn)?)+")
-
-func splitFileExt(name string) (string, string, string) {
-	// Extract and trim the shared lib version number if the file name ends with dot digits.
-	suffix := ""
-	matches := shlibVersionPattern.FindAllStringIndex(name, -1)
-	if len(matches) > 0 {
-		lastMatch := matches[len(matches)-1]
-		if lastMatch[1] == len(name) {
-			suffix = name[lastMatch[0]:lastMatch[1]]
-			name = name[0:lastMatch[0]]
-		}
-	}
-
-	// Extract the file name root and the file extension.
-	ext := filepath.Ext(name)
-	root := strings.TrimSuffix(name, ext)
-	suffix = ext + suffix
-
-	return root, suffix, ext
-}
diff --git a/rust/config/global.go b/rust/config/global.go
index 2e08a8c..7f9f993 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -22,7 +22,7 @@
 var pctx = android.NewPackageContext("android/soong/rust/config")
 
 var (
-	RustDefaultVersion = "1.35.0"
+	RustDefaultVersion = "1.37.0"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2018"
 	Stdlibs            = []string{
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 4362746..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,