Merge "Stop exporting systemserverclasspath_fragment when targeting S"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index ccfad00..a5cea17 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -39,6 +39,7 @@
 	Bp2buildDefaultConfig = Bp2BuildConfig{
 		"prebuilts/runtime/mainline/platform/sdk":            Bp2BuildDefaultTrueRecursively,
 		"art/libartpalette":                                  Bp2BuildDefaultTrueRecursively,
+		"art/libartbase":                                     Bp2BuildDefaultTrueRecursively,
 		"art/libdexfile":                                     Bp2BuildDefaultTrueRecursively,
 		"art/libnativebridge":                                Bp2BuildDefaultTrueRecursively,
 		"art/runtime":                                        Bp2BuildDefaultTrueRecursively,
@@ -108,6 +109,7 @@
 		"external/eigen":                                     Bp2BuildDefaultTrueRecursively,
 		"external/erofs-utils":                               Bp2BuildDefaultTrueRecursively,
 		"external/error_prone":                               Bp2BuildDefaultTrueRecursively,
+		"external/expat":                                     Bp2BuildDefaultTrueRecursively,
 		"external/f2fs-tools":                                Bp2BuildDefaultTrue,
 		"external/flac":                                      Bp2BuildDefaultTrueRecursively,
 		"external/fmtlib":                                    Bp2BuildDefaultTrueRecursively,
@@ -146,7 +148,7 @@
 		"external/zlib":                                      Bp2BuildDefaultTrueRecursively,
 		"external/zopfli":                                    Bp2BuildDefaultTrueRecursively,
 		"external/zstd":                                      Bp2BuildDefaultTrueRecursively,
-		"frameworks/av/media/codecs/g711/decoder":            Bp2BuildDefaultTrueRecursively,
+		"frameworks/av/media/codecs":                         Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/services/minijail":                    Bp2BuildDefaultTrueRecursively,
 		"frameworks/base/media/tests/MediaDump":              Bp2BuildDefaultTrue,
 		"frameworks/base/startop/apps/test":                  Bp2BuildDefaultTrue,
@@ -280,39 +282,49 @@
 		"flatbuffer_headers",
 		"gemmlowp_headers",
 		"gl_headers",
+		"libandroid_runtime_lazy",
 		"libandroid_runtime_vm_headers",
 		"libaudioclient_aidl_conversion_util",
 		"libaudioutils_fixedfft",
+		"libbinder_headers",
 		"libbinder_headers_platform_shared",
 		"libbluetooth-types-header",
+		"libbufferhub_headers",
+		"libcodec2",
 		"libcodec2_headers",
 		"libcodec2_internal",
 		"libdmabufheap",
+		"libdvr_headers",
 		"libgsm",
 		"libgui_bufferqueue_sources",
+		"libhardware",
 		"libhardware_headers",
+		"libincfs_headers",
 		"libnativeloader-headers",
 		"libnativewindow_headers",
 		"libneuralnetworks_headers",
 		"libopus",
+		"libpdx_headers",
 		"libprocpartition",
+		"libruy_static",
 		"libserviceutils",
-		"libstagefright_amrnb_common",
-		"libstagefright_amrwbdec",
 		"libstagefright_enc_common",
 		"libstagefright_foundation_headers",
 		"libstagefright_headers",
-		"libstagefright_m4vh263dec",
-		"libstagefright_m4vh263enc",
-		"libstagefright_mp3dec_headers",
+		"libsurfaceflinger_headers",
 		"libsync",
 		"libtextclassifier_hash_headers",
 		"libtextclassifier_hash_static",
+		"libtflite_kernel_utils",
+		"libtinyxml2",
 		"libui-types",
+		"libui_headers",
 		"libvorbisidec",
 		"media_ndk_headers",
+		"media_plugin_headers",
 		"mediaswcodec.policy",
 		"mediaswcodec.xml",
+		"philox_random",
 		"philox_random_headers",
 		"server_configurable_flags",
 		"tensorflow_headers",
@@ -361,10 +373,13 @@
 		"gen-kotlin-build-file.py",                  // TODO(b/198619163) module has same name as source
 		"libgtest_ndk_c++", "libgtest_main_ndk_c++", // TODO(b/201816222): Requires sdk_version support.
 		"linkerconfig", "mdnsd", // TODO(b/202876379): has arch-variant static_executable
-		"linker",       // TODO(b/228316882): cc_binary uses link_crt
-		"libdebuggerd", // TODO(b/228314770): support product variable-specific header_libs
-		"versioner",    // TODO(b/228313961):  depends on prebuilt shared library libclang-cpp_host as a shared library, which does not supply expected providers for a shared library
-		"apexer_test",  // Requires aapt2
+		"linker",            // TODO(b/228316882): cc_binary uses link_crt
+		"libdebuggerd",      // TODO(b/228314770): support product variable-specific header_libs
+		"versioner",         // TODO(b/228313961):  depends on prebuilt shared library libclang-cpp_host as a shared library, which does not supply expected providers for a shared library
+		"libspeexresampler", // TODO(b/231995978): Filter out unknown cflags
+		"libjpeg", "libvpx", // TODO(b/233948256): Convert .asm files
+		"art_libartbase_headers", // TODO(b/236268577): Header libraries do not support export_shared_libs_headers
+		"apexer_test",            // Requires aapt2
 		"apexer_test_host_tools",
 		"host_apex_verifier",
 
@@ -383,6 +398,9 @@
 		"prebuilt_platform-robolectric-4.4-prebuilt",   // aosp/1999250, needs .aar support in Jars
 		"prebuilt_platform-robolectric-4.5.1-prebuilt", // aosp/1999250, needs .aar support in Jars
 
+		// proto support
+		"libstats_proto_host", // TODO(b/236055697): handle protos from other packages
+
 		// path property for filegroups
 		"conscrypt",                        // TODO(b/210751803), we don't handle path property for filegroups
 		"conscrypt-for-host",               // TODO(b/210751803), we don't handle path property for filegroups
@@ -451,9 +469,11 @@
 		"stats-log-api-gen",                         // depends on unconverted modules: libstats_proto_host
 		"statslog.cpp", "statslog.h", "statslog.rs", // depends on unconverted modules: stats-log-api-gen
 		"statslog_art.cpp", "statslog_art.h", "statslog_header.rs", // depends on unconverted modules: stats-log-api-gen
-		"timezone-host",       // depends on unconverted modules: art.module.api.annotations
-		"truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt
-		"truth-prebuilt",      // depends on unconverted modules: asm-7.0, guava
+		"timezone-host",         // depends on unconverted modules: art.module.api.annotations
+		"truth-host-prebuilt",   // depends on unconverted modules: truth-prebuilt
+		"truth-prebuilt",        // depends on unconverted modules: asm-7.0, guava
+		"libartbase-art-gtest",  // depends on unconverted modules: libgtest_isolated, libart, libart-compiler, libdexfile, libprofile
+		"libartbased-art-gtest", // depends on unconverted modules: libgtest_isolated, libartd, libartd-compiler, libdexfiled, libprofiled
 
 		// b/215723302; awaiting tz{data,_version} to then rename targets conflicting with srcs
 		"tzdata",
@@ -463,6 +483,8 @@
 	Bp2buildCcLibraryStaticOnlyList = []string{}
 
 	MixedBuildsDisabledList = []string{
+		"libruy_static", "libtflite_kernel_utils", // TODO(b/237315968); Depend on prebuilt stl, not from source
+
 		"art_libdexfile_dex_instruction_list_header", // breaks libart_mterp.armng, header not found
 
 		"libbrotli",               // http://b/198585397, ld.lld: error: bionic/libc/arch-arm64/generic/bionic/memmove.S:95:(.text+0x10): relocation R_AARCH64_CONDBR19 out of range: -1404176 is not in [-1048576, 1048575]; references __memcpy
diff --git a/android/androidmk.go b/android/androidmk.go
index 6b675a6..832c7df 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -945,7 +945,10 @@
 	return !module.Enabled() ||
 		module.commonProperties.HideFromMake ||
 		// Make does not understand LinuxBionic
-		module.Os() == LinuxBionic
+		module.Os() == LinuxBionic ||
+		// Make does not understand LinuxMusl, except when we are building with USE_HOST_MUSL=true
+		// and all host binaries are LinuxMusl
+		(module.Os() == LinuxMusl && module.Target().HostCross)
 }
 
 // A utility func to format LOCAL_TEST_DATA outputs. See the comments on DataPath to understand how
diff --git a/android/apex.go b/android/apex.go
index 019efdd..c53ceb3 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -836,40 +836,6 @@
 	ctx.Phony(fmt.Sprintf("%s-depsinfo", ctx.ModuleName()), d.fullListPath, d.flatListPath)
 }
 
-// TODO(b/158059172): remove minSdkVersion allowlist
-var minSdkVersionAllowlist = func(apiMap map[string]int) map[string]ApiLevel {
-	list := make(map[string]ApiLevel, len(apiMap))
-	for name, finalApiInt := range apiMap {
-		list[name] = uncheckedFinalApiLevel(finalApiInt)
-	}
-	return list
-}(map[string]int{
-	"androidx-constraintlayout_constraintlayout-solver-nodeps": 29,
-	"apache-commons-compress":                                  29,
-	"bouncycastle_ike_digests":                                 30,
-	"brotli-java":                                              29,
-	"flatbuffer_headers":                                       30,
-	"gemmlowp_headers":                                         30,
-	"ike-internals":                                            30,
-	"libbrotli":                                                30,
-	"libcrypto_static":                                         30,
-	"libeigen":                                                 30,
-	"liblz4":                                                   30,
-	"libmdnssd":                                                30,
-	"libprocpartition":                                         30,
-	"libprotobuf-java-lite":                                    30,
-	"libprotoutil":                                             30,
-	"libtextclassifier_hash_headers":                           30,
-	"libtextclassifier_hash_static":                            30,
-	"libtflite_kernel_utils":                                   30,
-	"libzstd":                                                  30,
-	"net-utils-framework-common":                               29,
-	"philox_random_headers":                                    30,
-	"philox_random":                                            30,
-	"tensorflow_headers":                                       30,
-	"xz-java":                                                  29,
-})
-
 // Function called while walking an APEX's payload dependencies.
 //
 // Return true if the `to` module should be visited, false otherwise.
@@ -921,15 +887,13 @@
 		}
 		if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
 			toName := ctx.OtherModuleName(to)
-			if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver.GreaterThan(minSdkVersion) {
-				ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v."+
-					"\n\nDependency path: %s\n\n"+
-					"Consider adding 'min_sdk_version: %q' to %q",
-					minSdkVersion, ctx.ModuleName(), err.Error(),
-					ctx.GetPathString(false),
-					minSdkVersion, toName)
-				return false
-			}
+			ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v."+
+				"\n\nDependency path: %s\n\n"+
+				"Consider adding 'min_sdk_version: %q' to %q",
+				minSdkVersion, ctx.ModuleName(), err.Error(),
+				ctx.GetPathString(false),
+				minSdkVersion, toName)
+			return false
 		}
 		return true
 	})
diff --git a/android/api_levels.go b/android/api_levels.go
index 41b338c..da50b19 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -54,6 +54,14 @@
 	isPreview bool
 }
 
+func (this ApiLevel) FinalInt() int {
+	if this.IsPreview() {
+		panic("Requested a final int from a non-final ApiLevel")
+	} else {
+		return this.number
+	}
+}
+
 func (this ApiLevel) FinalOrFutureInt() int {
 	if this.IsPreview() {
 		return FutureApiLevelInt
diff --git a/android/arch.go b/android/arch.go
index 382a7df..e72614c 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1825,7 +1825,9 @@
 	for _, t := range targets {
 		if _, found := set[t.Os.String()]; !found {
 			set[t.Os.String()] = true
-			ret = append(ret, commonTargetMap[t.Os.String()])
+			common := commonTargetMap[t.Os.String()]
+			common.HostCross = t.HostCross
+			ret = append(ret, common)
 		}
 	}
 
diff --git a/apex/builder.go b/apex/builder.go
index fc9bb3b..7e2b924 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -82,6 +82,11 @@
 		Description: "prepare ${out}",
 	}, "provideNativeLibs", "requireNativeLibs", "opt")
 
+	stripCommentsApexManifestRule = pctx.StaticRule("stripCommentsApexManifestRule", blueprint.RuleParams{
+		Command:     `sed '/^\s*\/\//d' $in > $out`,
+		Description: "strip lines starting with // ${in}=>${out}",
+	})
+
 	stripApexManifestRule = pctx.StaticRule("stripApexManifestRule", blueprint.RuleParams{
 		Command:     `rm -f $out && ${conv_apex_manifest} strip $in -o $out`,
 		CommandDeps: []string{"${conv_apex_manifest}"},
@@ -205,10 +210,17 @@
 		optCommands = append(optCommands, "-a jniLibs "+strings.Join(jniLibs, " "))
 	}
 
+	manifestJsonCommentsStripped := android.PathForModuleOut(ctx, "apex_manifest_comments_stripped.json")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   stripCommentsApexManifestRule,
+		Input:  src,
+		Output: manifestJsonCommentsStripped,
+	})
+
 	manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json")
 	ctx.Build(pctx, android.BuildParams{
 		Rule:   apexManifestRule,
-		Input:  src,
+		Input:  manifestJsonCommentsStripped,
 		Output: manifestJsonFullOut,
 		Args: map[string]string{
 			"provideNativeLibs": strings.Join(provideNativeLibs, " "),
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index be10e86..36c46a4 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -18,6 +18,7 @@
 	"android/soong/android"
 	"android/soong/cc"
 	"android/soong/genrule"
+	"fmt"
 
 	"testing"
 )
@@ -204,8 +205,8 @@
         ":whole_static_lib_1",
         ":whole_static_lib_2",
     ]`,
-        "sdk_version": `"current"`,
-        "min_sdk_version": `"29"`,
+				"sdk_version":     `"current"`,
+				"min_sdk_version": `"29"`,
 			}),
 		},
 	})
@@ -1489,3 +1490,72 @@
 		},
 	})
 }
+
+func TestCcLibraryStaticStl(t *testing.T) {
+	testCases := []struct {
+		desc string
+		prop string
+		attr attrNameToString
+	}{
+		{
+			desc: "c++_shared deduped to libc++",
+			prop: `stl: "c++_shared",`,
+			attr: attrNameToString{
+				"stl": `"libc++"`,
+			},
+		},
+		{
+			desc: "libc++ to libc++",
+			prop: `stl: "libc++",`,
+			attr: attrNameToString{
+				"stl": `"libc++"`,
+			},
+		},
+		{
+			desc: "c++_static to libc++_static",
+			prop: `stl: "c++_static",`,
+			attr: attrNameToString{
+				"stl": `"libc++_static"`,
+			},
+		},
+		{
+			desc: "libc++_static to libc++_static",
+			prop: `stl: "libc++_static",`,
+			attr: attrNameToString{
+				"stl": `"libc++_static"`,
+			},
+		},
+		{
+			desc: "system to system",
+			prop: `stl: "system",`,
+			attr: attrNameToString{
+				"stl": `"system"`,
+			},
+		},
+		{
+			desc: "none to none",
+			prop: `stl: "none",`,
+			attr: attrNameToString{
+				"stl": `"none"`,
+			},
+		},
+		{
+			desc: "empty to empty",
+			attr: attrNameToString{},
+		},
+	}
+	for _, tc := range testCases {
+		t.Run(tc.desc, func(*testing.T) {
+			runCcLibraryStaticTestCase(t, bp2buildTestCase{
+				blueprint: fmt.Sprintf(`cc_library_static {
+	name: "foo",
+	include_build_directory: false,
+	%s
+}`, tc.prop),
+				expectedBazelTargets: []string{
+					makeBazelTarget("cc_library_static", "foo", tc.attr),
+				},
+			})
+		})
+	}
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index d891007..fa30d09 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -376,7 +376,8 @@
 				return
 			}
 			if ca.stl == nil {
-				ca.stl = stlProps.Stl
+				stl := deduplicateStlInput(*stlProps.Stl)
+				ca.stl = &stl
 			} else if ca.stl != stlProps.Stl {
 				ctx.ModuleErrorf("Unsupported conversion: module with different stl for different variants: %s and %s", *ca.stl, stlProps.Stl)
 			}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 8e0813d..86472a2 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -710,8 +710,13 @@
 			// Host sanitizers only link symbols in the final executable, so
 			// there will always be undefined symbols in intermediate libraries.
 			_, flags.Global.LdFlags = removeFromList("-Wl,--no-undefined", flags.Global.LdFlags)
+		}
 
-			// non-Bionic toolchain prebuilts are missing UBSan's vptr and function san
+		if !ctx.toolchain().Bionic() {
+			// non-Bionic toolchain prebuilts are missing UBSan's vptr and function san.
+			// Musl toolchain prebuilts have vptr and function sanitizers, but enabling them
+			// implicitly enables RTTI which causes RTTI mismatch issues with dependencies.
+
 			flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize=vptr,function")
 		}
 
diff --git a/cc/stl.go b/cc/stl.go
index 0f2a878..85a06da 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -25,6 +25,16 @@
 	return family
 }
 
+func deduplicateStlInput(stl string) string {
+	switch stl {
+	case "c++_shared":
+		return "libc++"
+	case "c++_static":
+		return "libc++_static"
+	}
+	return stl
+}
+
 func getNdkStlFamilyAndLinkType(m LinkableInterface) (string, string) {
 	stl := m.SelectedStl()
 	switch stl {
@@ -66,18 +76,18 @@
 		} else if ctx.header() {
 			s = "none"
 		}
+		if s == "none" {
+			return ""
+		}
+		s = deduplicateStlInput(s)
 		if ctx.useSdk() && ctx.Device() {
 			switch s {
 			case "", "system":
 				return "ndk_system"
-			case "c++_shared", "c++_static":
-				return "ndk_lib" + s
 			case "libc++":
 				return "ndk_libc++_shared"
 			case "libc++_static":
 				return "ndk_libc++_static"
-			case "none":
-				return ""
 			default:
 				ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", s)
 				return ""
@@ -87,8 +97,6 @@
 			case "libc++", "libc++_static", "":
 				// Only use static libc++ for Windows.
 				return "libc++_static"
-			case "none":
-				return ""
 			default:
 				ctx.ModuleErrorf("stl: %q is not a supported STL for windows", s)
 				return ""
@@ -97,12 +105,6 @@
 			switch s {
 			case "libc++", "libc++_static":
 				return s
-			case "c++_shared":
-				return "libc++"
-			case "c++_static":
-				return "libc++_static"
-			case "none":
-				return ""
 			case "", "system":
 				if ctx.static() {
 					return "libc++_static"
diff --git a/java/base.go b/java/base.go
index db10411..c399c40 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1485,11 +1485,30 @@
 	}
 
 	if ctx.Device() {
-		lintSDKVersion := func(sdkSpec android.SdkSpec) android.ApiLevel {
+		lintSDKVersion := func(sdkSpec android.SdkSpec) int {
 			if v := sdkSpec.ApiLevel; !v.IsPreview() {
-				return v
+				return v.FinalInt()
 			} else {
-				return ctx.Config().DefaultAppTargetSdk(ctx)
+				// When running metalava, we pass --version-codename. When that value
+				// is not REL, metalava will add 1 to the --current-version argument.
+				// On old branches, PLATFORM_SDK_VERSION is the latest version (for that
+				// branch) and the codename is REL, except potentially on the most
+				// recent non-master branch. On that branch, it goes through two other
+				// phases before it gets to the phase previously described:
+				//  - PLATFORM_SDK_VERSION has not been updated yet, and the codename
+				//    is not rel. This happens for most of the internal branch's life
+				//    while the branch has been cut but is still under active development.
+				//  - PLATFORM_SDK_VERSION has been set, but the codename is still not
+				//    REL. This happens briefly during the release process. During this
+				//    state the code to add --current-version is commented out, and then
+				//    that commenting out is reverted after the codename is set to REL.
+				// On the master branch, the PLATFORM_SDK_VERSION always represents a
+				// prior version and the codename is always non-REL.
+				//
+				// We need to add one here to match metalava adding 1. Technically
+				// this means that in the state described in the second bullet point
+				// above, this number is 1 higher than it should be.
+				return ctx.Config().PlatformSdkVersion().FinalInt() + 1
 			}
 		}
 
diff --git a/java/fuzz.go b/java/fuzz.go
index b306991..d0f369f 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -171,6 +171,10 @@
 			return
 		}
 
+		if javaFuzzModule.Target().HostCross {
+			return
+		}
+
 		fuzzModuleValidator := fuzz.FuzzModule{
 			javaFuzzModule.ModuleBase,
 			javaFuzzModule.DefaultableModuleBase,
diff --git a/java/lint.go b/java/lint.go
index 22c9ec4..e276345 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"sort"
+	"strconv"
 	"strings"
 
 	"github.com/google/blueprint/proptools"
@@ -75,9 +76,9 @@
 	extraLintCheckJars      android.Paths
 	test                    bool
 	library                 bool
-	minSdkVersion           android.ApiLevel
-	targetSdkVersion        android.ApiLevel
-	compileSdkVersion       android.ApiLevel
+	minSdkVersion           int
+	targetSdkVersion        int
+	compileSdkVersion       int
 	compileSdkKind          android.SdkKind
 	javaLanguageLevel       string
 	kotlinLanguageLevel     string
@@ -299,8 +300,8 @@
 		Text(`echo "<?xml version='1.0' encoding='utf-8'?>" &&`).
 		Text(`echo "<manifest xmlns:android='http://schemas.android.com/apk/res/android'" &&`).
 		Text(`echo "    android:versionCode='1' android:versionName='1' >" &&`).
-		Textf(`echo "  <uses-sdk android:minSdkVersion='%s' android:targetSdkVersion='%s'/>" &&`,
-			l.minSdkVersion.String(), l.targetSdkVersion.String()).
+		Textf(`echo "  <uses-sdk android:minSdkVersion='%d' android:targetSdkVersion='%d'/>" &&`,
+			l.minSdkVersion, l.targetSdkVersion).
 		Text(`echo "</manifest>"`).
 		Text(") >").Output(manifestPath)
 
@@ -325,7 +326,7 @@
 		return
 	}
 
-	if l.minSdkVersion.CompareTo(l.compileSdkVersion) == -1 {
+	if l.minSdkVersion != l.compileSdkVersion {
 		l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, updatabilityChecks...)
 		_, filtered := android.FilterList(l.properties.Lint.Warning_checks, updatabilityChecks)
 		if len(filtered) != 0 {
@@ -427,7 +428,7 @@
 		FlagWithOutput("--html ", html).
 		FlagWithOutput("--text ", text).
 		FlagWithOutput("--xml ", xml).
-		FlagWithArg("--compile-sdk-version ", l.compileSdkVersion.String()).
+		FlagWithArg("--compile-sdk-version ", strconv.Itoa(l.compileSdkVersion)).
 		FlagWithArg("--java-language-level ", l.javaLanguageLevel).
 		FlagWithArg("--kotlin-language-level ", l.kotlinLanguageLevel).
 		FlagWithArg("--url ", fmt.Sprintf(".=.,%s=out", android.PathForOutput(ctx).String())).
diff --git a/rust/bindgen.go b/rust/bindgen.go
index b4626a0..4d723d6 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -41,10 +41,25 @@
 
 	//TODO(b/160803703) Use a prebuilt bindgen instead of the built bindgen.
 	_ = pctx.HostBinToolVariable("bindgenCmd", "bindgen")
+	_ = pctx.VariableFunc("bindgenHostPrebuiltTag", func(ctx android.PackageVarContext) string {
+		if ctx.Config().UseHostMusl() {
+			// This is a hack to use the glibc bindgen binary until we have a musl version checked in.
+			return "linux-x86"
+		} else {
+			return "${config.HostPrebuiltTag}"
+		}
+	})
+	_ = pctx.VariableFunc("bindgenClangLibdir", func(ctx android.PackageVarContext) string {
+		if ctx.Config().UseHostMusl() {
+			return "musl/lib64/"
+		} else {
+			return "lib64/"
+		}
+	})
 	_ = pctx.SourcePathVariable("bindgenClang",
-		"${cc_config.ClangBase}/${config.HostPrebuiltTag}/${bindgenClangVersion}/bin/clang")
+		"${cc_config.ClangBase}/${bindgenHostPrebuiltTag}/${bindgenClangVersion}/bin/clang")
 	_ = pctx.SourcePathVariable("bindgenLibClang",
-		"${cc_config.ClangBase}/${config.HostPrebuiltTag}/${bindgenClangVersion}/lib64/")
+		"${cc_config.ClangBase}/${bindgenHostPrebuiltTag}/${bindgenClangVersion}/${bindgenClangLibdir}")
 
 	//TODO(ivanlozano) Switch this to RuleBuilder
 	bindgen = pctx.AndroidStaticRule("bindgen",
diff --git a/rust/compiler.go b/rust/compiler.go
index bcd58c8..bf6a488 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -371,8 +371,9 @@
 
 	if !Bool(compiler.Properties.No_stdlibs) {
 		for _, stdlib := range config.Stdlibs {
-			// If we're building for the build host, use the prebuilt stdlibs
-			if ctx.Target().Os == android.Linux || ctx.Target().Os == android.Darwin {
+			// If we're building for the build host, use the prebuilt stdlibs, unless the host
+			// is linux_bionic which doesn't have prebuilts.
+			if ctx.Host() && !ctx.Target().HostCross && ctx.Target().Os != android.LinuxBionic {
 				stdlib = "prebuilt_" + stdlib
 			}
 			deps.Stdlibs = append(deps.Stdlibs, stdlib)
diff --git a/rust/config/Android.bp b/rust/config/Android.bp
index 7757c79..ba40cb0 100644
--- a/rust/config/Android.bp
+++ b/rust/config/Android.bp
@@ -11,6 +11,7 @@
     ],
     srcs: [
         "arm_device.go",
+        "arm_linux_host.go",
         "arm64_device.go",
         "global.go",
         "lints.go",
diff --git a/rust/config/arm_linux_host.go b/rust/config/arm_linux_host.go
new file mode 100644
index 0000000..22bdaee
--- /dev/null
+++ b/rust/config/arm_linux_host.go
@@ -0,0 +1,147 @@
+// Copyright 2022 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 config
+
+import (
+	"strings"
+
+	"android/soong/android"
+)
+
+var (
+	linuxArmRustflags   = []string{}
+	linuxArmLinkflags   = []string{}
+	linuxArm64Rustflags = []string{}
+	linuxArm64Linkflags = []string{}
+)
+
+func init() {
+	registerToolchainFactory(android.LinuxMusl, android.Arm64, linuxMuslArm64ToolchainFactory)
+	registerToolchainFactory(android.LinuxMusl, android.Arm, linuxMuslArmToolchainFactory)
+
+	pctx.StaticVariable("LinuxToolchainArmRustFlags", strings.Join(linuxArmRustflags, " "))
+	pctx.StaticVariable("LinuxToolchainArmLinkFlags", strings.Join(linuxArmLinkflags, " "))
+	pctx.StaticVariable("LinuxToolchainArm64RustFlags", strings.Join(linuxArm64Rustflags, " "))
+	pctx.StaticVariable("LinuxToolchainArm64LinkFlags", strings.Join(linuxArm64Linkflags, " "))
+}
+
+// Base 64-bit linux rust toolchain
+type toolchainLinuxArm64 struct {
+	toolchain64Bit
+}
+
+func (toolchainLinuxArm64) Supported() bool {
+	return true
+}
+
+func (toolchainLinuxArm64) Bionic() bool {
+	return false
+}
+
+func (t *toolchainLinuxArm64) Name() string {
+	return "arm64"
+}
+
+func (t *toolchainLinuxArm64) ToolchainLinkFlags() string {
+	// Prepend the lld flags from cc_config so we stay in sync with cc
+	return "${cc_config.LinuxLldflags} ${cc_config.LinuxArm64Lldflags} " +
+		"${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainArm64LinkFlags}"
+}
+
+func (t *toolchainLinuxArm64) ToolchainRustFlags() string {
+	return "${config.LinuxToolchainRustFlags} ${config.LinuxToolchainArm64RustFlags}"
+}
+
+// Specialization of the 64-bit linux rust toolchain for musl.  Adds the musl rust triple and
+// linker flags to avoid using the host sysroot.
+type toolchainLinuxMuslArm64 struct {
+	toolchainLinuxArm64
+}
+
+func (t *toolchainLinuxMuslArm64) RustTriple() string {
+	return "aarch64-unknown-linux-musl"
+}
+
+func (t *toolchainLinuxMuslArm64) ToolchainLinkFlags() string {
+	return t.toolchainLinuxArm64.ToolchainLinkFlags() + " " + "${config.LinuxMuslToolchainLinkFlags}"
+}
+
+func (t *toolchainLinuxMuslArm64) ToolchainRustFlags() string {
+	return t.toolchainLinuxArm64.ToolchainRustFlags() + " " + "${config.LinuxMuslToolchainRustFlags}"
+}
+
+func linuxMuslArm64ToolchainFactory(arch android.Arch) Toolchain {
+	return toolchainLinuxMuslArm64Singleton
+}
+
+// Base 32-bit linux rust toolchain
+type toolchainLinuxArm struct {
+	toolchain32Bit
+}
+
+func (toolchainLinuxArm) Supported() bool {
+	return true
+}
+
+func (toolchainLinuxArm) Bionic() bool {
+	return false
+}
+
+func (t *toolchainLinuxArm) Name() string {
+	return "arm"
+}
+
+func (toolchainLinuxArm) LibclangRuntimeLibraryArch() string {
+	return "arm"
+}
+
+func (toolchainLinuxArm64) LibclangRuntimeLibraryArch() string {
+	return "arm64"
+}
+
+func (t *toolchainLinuxArm) ToolchainLinkFlags() string {
+	// Prepend the lld flags from cc_config so we stay in sync with cc
+	return "${cc_config.LinuxLldflags} ${cc_config.LinuxArmLldflags} " +
+		"${config.LinuxToolchainLinkFlags} ${config.LinuxToolchainArmLinkFlags}"
+}
+
+func (t *toolchainLinuxArm) ToolchainRustFlags() string {
+	return "${config.LinuxToolchainRustFlags} ${config.LinuxToolchainArmRustFlags}"
+}
+
+// Specialization of the 32-bit linux rust toolchain for musl.  Adds the musl rust triple and
+// linker flags to avoid using the host sysroot.
+type toolchainLinuxMuslArm struct {
+	toolchainLinuxArm
+}
+
+func (t *toolchainLinuxMuslArm) RustTriple() string {
+	return "arm-unknown-linux-musleabihf"
+}
+
+func (t *toolchainLinuxMuslArm) ToolchainLinkFlags() string {
+	return t.toolchainLinuxArm.ToolchainLinkFlags() + " " + "${config.LinuxMuslToolchainLinkFlags}"
+}
+
+func (t *toolchainLinuxMuslArm) ToolchainRustFlags() string {
+	return t.toolchainLinuxArm.ToolchainRustFlags() + " " + "${config.LinuxMuslToolchainRustFlags}"
+}
+
+func linuxMuslArmToolchainFactory(arch android.Arch) Toolchain {
+	return toolchainLinuxMuslArmSingleton
+}
+
+var toolchainLinuxMuslArm64Singleton Toolchain = &toolchainLinuxMuslArm64{}
+var toolchainLinuxMuslArmSingleton Toolchain = &toolchainLinuxMuslArm{}
diff --git a/rust/config/global.go b/rust/config/global.go
index e9751fd..3ef0ecb 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -78,7 +78,13 @@
 
 func init() {
 	pctx.SourcePathVariable("RustDefaultBase", RustDefaultBase)
-	pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
+	pctx.VariableConfigMethod("HostPrebuiltTag", func(config android.Config) string {
+		if config.UseHostMusl() {
+			return "linux-musl-x86"
+		} else {
+			return config.PrebuiltOS()
+		}
+	})
 
 	pctx.VariableFunc("RustBase", func(ctx android.PackageVarContext) string {
 		if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" {
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 536fcbd..a3c5cb5 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -174,7 +174,7 @@
 	}
 
 	// Enable Memtag for all components in the include paths (for Aarch64 only)
-	if ctx.Arch().ArchType == android.Arm64 {
+	if ctx.Arch().ArchType == android.Arm64 && ctx.Os().Bionic() {
 		if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
 			if s.Memtag_heap == nil {
 				s.Memtag_heap = proptools.BoolPtr(true)
@@ -200,7 +200,7 @@
 	}
 
 	// HWASan requires AArch64 hardware feature (top-byte-ignore).
-	if ctx.Arch().ArchType != android.Arm64 {
+	if ctx.Arch().ArchType != android.Arm64 || !ctx.Os().Bionic() {
 		s.Hwaddress = nil
 	}
 
@@ -215,7 +215,7 @@
 	}
 
 	// Memtag_heap is only implemented on AArch64.
-	if ctx.Arch().ArchType != android.Arm64 {
+	if ctx.Arch().ArchType != android.Arm64 || !ctx.Os().Bionic() {
 		s.Memtag_heap = nil
 	}
 
@@ -234,7 +234,7 @@
 	}
 	if Bool(sanitize.Properties.Sanitize.Fuzzer) {
 		flags.RustFlags = append(flags.RustFlags, fuzzerFlags...)
-		if ctx.Arch().ArchType == android.Arm64 {
+		if ctx.Arch().ArchType == android.Arm64 && ctx.Os().Bionic() {
 			flags.RustFlags = append(flags.RustFlags, hwasanFlags...)
 		} else {
 			flags.RustFlags = append(flags.RustFlags, asanFlags...)
@@ -282,13 +282,13 @@
 		var deps []string
 
 		if mod.IsSanitizerEnabled(cc.Asan) ||
-			(mod.IsSanitizerEnabled(cc.Fuzzer) && mctx.Arch().ArchType != android.Arm64) {
+			(mod.IsSanitizerEnabled(cc.Fuzzer) && (mctx.Arch().ArchType != android.Arm64 || !mctx.Os().Bionic())) {
 			variations = append(variations,
 				blueprint.Variation{Mutator: "link", Variation: "shared"})
 			depTag = cc.SharedDepTag()
 			deps = []string{config.LibclangRuntimeLibrary(mod.toolchain(mctx), "asan")}
 		} else if mod.IsSanitizerEnabled(cc.Hwasan) ||
-			(mod.IsSanitizerEnabled(cc.Fuzzer) && mctx.Arch().ArchType == android.Arm64) {
+			(mod.IsSanitizerEnabled(cc.Fuzzer) && mctx.Arch().ArchType == android.Arm64 && mctx.Os().Bionic()) {
 			// TODO(b/204776996): HWASan for static Rust binaries isn't supported yet.
 			if binary, ok := mod.compiler.(binaryInterface); ok {
 				if binary.staticallyLinked() {