Merge "Build test1_com.android.tzdata and test3_com.android.tzdata with bazel."
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index e901b31..238d24f 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -391,6 +391,8 @@
 		"external/protobuf":/* recursive = */ false,
 		"external/python/absl-py":/* recursive = */ true,
 
+		"external/compiler-rt/lib/cfi":/* recursive = */ false,
+
 		// this BUILD file is globbed by //external/icu/icu4c/source:icu4c_test_data's "data/**/*".
 		"external/icu/icu4c/source/data/unidata/norm2":/* recursive = */ false,
 
diff --git a/android/sdk_version.go b/android/sdk_version.go
index 7ace638..1192f7d 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -28,9 +28,9 @@
 	// MinSdkVersion returns ApiLevel that corresponds to the min_sdk_version property of the current module,
 	// or from sdk_version if it is not set.
 	MinSdkVersion(ctx EarlyModuleContext) ApiLevel
-	// ReplaceMaxSdkVersionPlaceholder returns SdkSpec to replace the maxSdkVersion property of permission and
+	// ReplaceMaxSdkVersionPlaceholder returns Apilevel to replace the maxSdkVersion property of permission and
 	// uses-permission tags if it is set.
-	ReplaceMaxSdkVersionPlaceholder(ctx EarlyModuleContext) SdkSpec
+	ReplaceMaxSdkVersionPlaceholder(ctx EarlyModuleContext) ApiLevel
 	// TargetSdkVersion returns the ApiLevel that corresponds to the target_sdk_version property of the current module,
 	// or from sdk_version if it is not set.
 	TargetSdkVersion(ctx EarlyModuleContext) ApiLevel
diff --git a/apex/apex.go b/apex/apex.go
index 1f700c6..0f32f77 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -103,12 +103,13 @@
 	// to avoid mistakes. When set as true, no force-labelling.
 	Use_file_contexts_as_is *bool
 
-	// Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
-	// format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
-	// path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
-	// and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
-	// capability. If this property is not set, or a file is missing in the file, default config
-	// is used.
+	// Path to the canned fs config file for customizing file's
+	// uid/gid/mod/capabilities. The content of this file is appended to the
+	// default config, so that the custom entries are preferred. The format is
+	// /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where
+	// path_or_glob is a path or glob pattern for a file or set of files,
+	// uid/gid are numerial values of user ID and group ID, mode is octal value
+	// for the file mode, and cap is hexadecimal value for the capability.
 	Canned_fs_config *string `android:"path"`
 
 	ApexNativeDependencies
@@ -2831,7 +2832,7 @@
 	if !baseModuleIsApex {
 		panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName))
 	}
-	attrs, props := convertWithBp2build(a, ctx)
+	attrs, props, commonAttrs := convertWithBp2build(a, ctx)
 
 	// We just want the name, not module reference.
 	baseApexName := strings.TrimPrefix(baseApexModuleName, ":")
@@ -2905,7 +2906,9 @@
 		}
 	}
 
-	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs)
+	commonAttrs.Name = o.Name()
+
+	ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -3549,17 +3552,12 @@
 		return
 	}
 
-	attrs, props := convertWithBp2build(a, ctx)
-	commonAttrs := android.CommonAttributes{
-		Name: a.Name(),
-	}
-	if a.testApex {
-		commonAttrs.Testonly = proptools.BoolPtr(a.testApex)
-	}
+	attrs, props, commonAttrs := convertWithBp2build(a, ctx)
+	commonAttrs.Name = a.Name()
 	ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
 }
 
-func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) {
+func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties, android.CommonAttributes) {
 	var manifestLabelAttribute bazel.LabelAttribute
 	manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
 
@@ -3687,7 +3685,12 @@
 		Bzl_load_location: "//build/bazel/rules/apex:apex.bzl",
 	}
 
-	return attrs, props
+	commonAttrs := android.CommonAttributes{}
+	if a.testApex {
+		commonAttrs.Testonly = proptools.BoolPtr(true)
+	}
+
+	return attrs, props, commonAttrs
 }
 
 // The following conversions are based on this table where the rows are the compile_multilib
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c9665a4..05c888a 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -10105,3 +10105,45 @@
 	android.AssertStringDoesContain(t, "missing lib to trim", libs_to_trim, "libbar")
 	android.AssertStringDoesNotContain(t, "unexpected libs in the libs to trim", libs_to_trim, "libbaz")
 }
+
+func TestCannedFsConfig(t *testing.T) {
+	ctx := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			updatable: false,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}`)
+	mod := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+	generateFsRule := mod.Rule("generateFsConfig")
+	cmd := generateFsRule.RuleParams.Command
+
+	ensureContains(t, cmd, `( echo '/ 1000 1000 0755'; echo '/apex_manifest.json 1000 1000 0644'; echo '/apex_manifest.pb 1000 1000 0644'; ) >`)
+}
+
+func TestCannedFsConfig_HasCustomConfig(t *testing.T) {
+	ctx := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			canned_fs_config: "my_config",
+			updatable: false,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}`)
+	mod := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+	generateFsRule := mod.Rule("generateFsConfig")
+	cmd := generateFsRule.RuleParams.Command
+
+	// Ensure that canned_fs_config has "cat my_config" at the end
+	ensureContains(t, cmd, `( echo '/ 1000 1000 0755'; echo '/apex_manifest.json 1000 1000 0644'; echo '/apex_manifest.pb 1000 1000 0644'; cat my_config ) >`)
+}
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index 03fb5d4..250db7f 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -58,6 +58,7 @@
 	ctx.RegisterModuleType("cc_binary", cc.BinaryFactory)
 	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
 	ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory)
+	ctx.RegisterModuleType("apex_test", apex.TestApexBundleFactory)
 	ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	ctx.RegisterModuleType("apex", apex.BundleFactory)
@@ -706,6 +707,125 @@
 		}})
 }
 
+func TestOverrideApexTest(t *testing.T) {
+	runOverrideApexTestCase(t, Bp2buildTestCase{
+		Description:                "override_apex",
+		ModuleTypeUnderTest:        "override_apex",
+		ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+		Filesystem:                 map[string]string{},
+		Blueprint: `
+apex_key {
+	name: "com.android.apogee.key",
+	public_key: "com.android.apogee.avbpubkey",
+	private_key: "com.android.apogee.pem",
+	bazel_module: { bp2build_available: false },
+}
+
+android_app_certificate {
+	name: "com.android.apogee.certificate",
+	certificate: "com.android.apogee",
+	bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+	name: "native_shared_lib_1",
+	bazel_module: { bp2build_available: false },
+}
+
+prebuilt_etc {
+	name: "prebuilt_1",
+	bazel_module: { bp2build_available: false },
+}
+
+filegroup {
+	name: "com.android.apogee-file_contexts",
+	srcs: [
+		"com.android.apogee-file_contexts",
+	],
+	bazel_module: { bp2build_available: false },
+}
+
+cc_binary { name: "cc_binary_1", bazel_module: { bp2build_available: false } }
+sh_binary { name: "sh_binary_2", bazel_module: { bp2build_available: false } }
+
+apex_test {
+	name: "com.android.apogee",
+	manifest: "apogee_manifest.json",
+	androidManifest: "ApogeeAndroidManifest.xml",
+	file_contexts: ":com.android.apogee-file_contexts",
+	min_sdk_version: "29",
+	key: "com.android.apogee.key",
+	certificate: ":com.android.apogee.certificate",
+	updatable: false,
+	installable: false,
+	compressible: false,
+	native_shared_libs: [
+	    "native_shared_lib_1",
+	],
+	binaries: [
+		"cc_binary_1",
+		"sh_binary_2",
+	],
+	prebuilts: [
+	    "prebuilt_1",
+	],
+	bazel_module: { bp2build_available: false },
+}
+
+apex_key {
+	name: "com.google.android.apogee.key",
+	public_key: "com.google.android.apogee.avbpubkey",
+	private_key: "com.google.android.apogee.pem",
+	bazel_module: { bp2build_available: false },
+}
+
+android_app_certificate {
+	name: "com.google.android.apogee.certificate",
+	certificate: "com.google.android.apogee",
+	bazel_module: { bp2build_available: false },
+}
+
+override_apex {
+	name: "com.google.android.apogee",
+	base: ":com.android.apogee",
+	key: "com.google.android.apogee.key",
+	certificate: ":com.google.android.apogee.certificate",
+	prebuilts: [],
+	compressible: true,
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+				"android_manifest": `"ApogeeAndroidManifest.xml"`,
+				"base_apex_name":   `"com.android.apogee"`,
+				"binaries": `[
+        ":cc_binary_1",
+        ":sh_binary_2",
+    ]`,
+				"certificate":     `":com.google.android.apogee.certificate"`,
+				"file_contexts":   `":com.android.apogee-file_contexts"`,
+				"installable":     "False",
+				"key":             `":com.google.android.apogee.key"`,
+				"manifest":        `"apogee_manifest.json"`,
+				"min_sdk_version": `"29"`,
+				"native_shared_libs_32": `select({
+        "//build/bazel/platforms/arch:arm": [":native_shared_lib_1"],
+        "//build/bazel/platforms/arch:x86": [":native_shared_lib_1"],
+        "//conditions:default": [],
+    })`,
+				"native_shared_libs_64": `select({
+        "//build/bazel/platforms/arch:arm64": [":native_shared_lib_1"],
+        "//build/bazel/platforms/arch:x86_64": [":native_shared_lib_1"],
+        "//conditions:default": [],
+    })`,
+				"testonly":     "True",
+				"prebuilts":    `[]`,
+				"updatable":    "False",
+				"compressible": "True",
+			}),
+		}})
+}
+
 func TestApexBundleSimple_manifestIsEmpty_baseApexOverrideApexInDifferentAndroidBp(t *testing.T) {
 	runOverrideApexTestCase(t, Bp2buildTestCase{
 		Description:                "override_apex - manifest of base apex is empty, base apex and override_apex is in different Android.bp",
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
index d915d6b..fdda35b 100644
--- a/bp2build/bp2build_product_config.go
+++ b/bp2build/bp2build_product_config.go
@@ -85,6 +85,11 @@
 		# TODO: When we start generating the platforms for more than just the
 		# currently lunched, product, this select should have an arm for each product.
 		"@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_constraint_value": "@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_product_vars",
+		"@soong_injection//product_config_platforms/products/aosp_arm_for_testing:aosp_arm_for_testing_constraint_value": "@soong_injection//product_config_platforms/products/aosp_arm_for_testing:aosp_arm_for_testing_product_vars",
+		"@soong_injection//product_config_platforms/products/aosp_arm64_for_testing:aosp_arm64_for_testing_constraint_value": "@soong_injection//product_config_platforms/products/aosp_arm64_for_testing:aosp_arm64_for_testing_product_vars",
+		"@soong_injection//product_config_platforms/products/aosp_x86_for_testing:aosp_x86_for_testing_constraint_value": "@soong_injection//product_config_platforms/products/aosp_x86_for_testing:aosp_x86_for_testing_product_vars",
+		"@soong_injection//product_config_platforms/products/aosp_x86_64_for_testing:aosp_x86_64_for_testing_constraint_value": "@soong_injection//product_config_platforms/products/aosp_x86_64_for_testing:aosp_x86_64_for_testing_product_vars",
+		"@soong_injection//product_config_platforms/products/aosp_arm64_for_testing_no_compression:aosp_arm64_for_testing_no_compression_constraint_value": "@soong_injection//product_config_platforms/products/aosp_arm64_for_testing_no_compression:aosp_arm64_for_testing_no_compression_product_vars",
 	}),
 )
 `)),
@@ -122,5 +127,42 @@
 `)),
 	}
 
+	// Add some products for testing
+	for _, arch := range []string{"arm", "arm64", "x86", "x86_64"} {
+		result = append(result, newFile(
+			fmt.Sprintf("product_config_platforms/products/aosp_%s_for_testing", arch),
+			"BUILD",
+			fmt.Sprintf(`
+package(default_visibility=[
+    "@soong_injection//product_config_platforms:__subpackages__",
+    "@//build/bazel/product_config:__subpackages__",
+])
+load("@//build/bazel/tests/products:aosp_%s.variables.bzl", _soong_variables = "variables")
+load("@//build/bazel/product_config:android_product.bzl", "android_product")
+
+android_product(
+    name = "aosp_%s_for_testing",
+    soong_variables = _soong_variables,
+)
+`, arch, arch)))
+	}
+	result = append(result, newFile(
+		"product_config_platforms/products/aosp_arm64_for_testing_no_compression",
+		"BUILD",
+		`
+package(default_visibility=[
+    "@soong_injection//product_config_platforms:__subpackages__",
+    "@//build/bazel/product_config:__subpackages__",
+])
+load("@bazel_skylib//lib:dicts.bzl", "dicts")
+load("@//build/bazel/tests/products:aosp_arm64.variables.bzl", _soong_variables = "variables")
+load("@//build/bazel/product_config:android_product.bzl", "android_product")
+
+android_product(
+    name = "aosp_arm64_for_testing_no_compression",
+    soong_variables = dicts.add(_soong_variables, {"CompressedApex": False}),
+)
+`))
+
 	return result, nil
 }
diff --git a/cc/afdo_test.go b/cc/afdo_test.go
index 335910c..40f705b 100644
--- a/cc/afdo_test.go
+++ b/cc/afdo_test.go
@@ -180,3 +180,100 @@
 		}
 	}
 }
+
+func TestAfdoEnabledWithMultiArchs(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "foo",
+		srcs: ["test.c"],
+		afdo: true,
+		compile_multilib: "both",
+	}
+`
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/foo_arm.afdo", "TEST"),
+		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/foo_arm64.afdo", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared")
+	fooArmCFlags := fooArm.Rule("cc").Args["cFlags"]
+	if w := "-fprofile-sample-use=toolchain/pgo-profiles/sampling/foo_arm.afdo"; !strings.Contains(fooArmCFlags, w) {
+		t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArmCFlags)
+	}
+
+	fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a_shared")
+	fooArm64CFlags := fooArm64.Rule("cc").Args["cFlags"]
+	if w := "-fprofile-sample-use=toolchain/pgo-profiles/sampling/foo_arm64.afdo"; !strings.Contains(fooArm64CFlags, w) {
+		t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArm64CFlags)
+	}
+}
+
+func TestMultipleAfdoRDeps(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		static_libs: ["libFoo"],
+		afdo: true,
+	}
+
+	cc_library_shared {
+		name: "libBar",
+		srcs: ["bar.c"],
+		static_libs: ["libFoo"],
+		afdo: true,
+	}
+
+	cc_library_static {
+		name: "libFoo",
+		srcs: ["foo.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libTest.afdo", "TEST"),
+		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libBar.afdo", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	expectedCFlagLibTest := "-fprofile-sample-use=toolchain/pgo-profiles/sampling/libTest.afdo"
+	expectedCFlagLibBar := "-fprofile-sample-use=toolchain/pgo-profiles/sampling/libBar.afdo"
+
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+	libTestAfdoVariantOfLibFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
+
+	libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_shared")
+	libBarAfdoVariantOfLibFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libBar")
+
+	// Check cFlags of afdo-enabled modules and the afdo-variant of their static deps
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlagLibTest) {
+		t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
+	}
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlagLibBar) {
+		t.Errorf("Expected 'libBar' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
+	}
+
+	cFlags = libTestAfdoVariantOfLibFoo.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlagLibTest) {
+		t.Errorf("Expected 'libTestAfdoVariantOfLibFoo' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
+	}
+
+	cFlags = libBarAfdoVariantOfLibFoo.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlagLibBar) {
+		t.Errorf("Expected 'libBarAfdoVariantOfLibFoo' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
+	}
+
+	// Check dependency edges of static deps
+	if !hasDirectDep(result, libTest.Module(), libTestAfdoVariantOfLibFoo.Module()) {
+		t.Errorf("libTest missing dependency on afdo variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libBar.Module(), libBarAfdoVariantOfLibFoo.Module()) {
+		t.Errorf("libBar missing dependency on afdo variant of libFoo")
+	}
+}
diff --git a/cc/config/global.go b/cc/config/global.go
index 4d703e4..3eb4577 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -313,6 +313,8 @@
 		"device/",
 		"vendor/",
 	}
+
+	VersionScriptFlagPrefix = "-Wl,--version-script,"
 )
 
 // BazelCcToolchainVars generates bzl file content containing variables for
@@ -401,6 +403,8 @@
 	exportedVars.ExportString("ExperimentalCStdVersion", ExperimentalCStdVersion)
 	exportedVars.ExportString("ExperimentalCppStdVersion", ExperimentalCppStdVersion)
 
+	exportedVars.ExportString("VersionScriptFlagPrefix", VersionScriptFlagPrefix)
+
 	// Everything in these lists is a crime against abstraction and dependency tracking.
 	// Do not add anything to this list.
 	commonGlobalIncludes := []string{
diff --git a/cc/linker.go b/cc/linker.go
index e49b97d..257fe86 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -15,11 +15,12 @@
 package cc
 
 import (
-	"android/soong/android"
-	"android/soong/cc/config"
 	"fmt"
 	"path/filepath"
 
+	"android/soong/android"
+	"android/soong/cc/config"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
@@ -542,13 +543,13 @@
 				ctx.PropertyErrorf("version_script", "Not supported on Darwin")
 			} else {
 				flags.Local.LdFlags = append(flags.Local.LdFlags,
-					"-Wl,--version-script,"+versionScript.String())
+					config.VersionScriptFlagPrefix+versionScript.String())
 				flags.LdFlagsDeps = append(flags.LdFlagsDeps, versionScript.Path())
 
 				if linker.sanitize.isSanitizerEnabled(cfi) {
-					cfiExportsMap := android.PathForSource(ctx, cfiExportsMapPath)
+					cfiExportsMap := android.PathForSource(ctx, cfiExportsMapPath+"/"+cfiExportsMapFilename)
 					flags.Local.LdFlags = append(flags.Local.LdFlags,
-						"-Wl,--version-script,"+cfiExportsMap.String())
+						config.VersionScriptFlagPrefix+cfiExportsMap.String())
 					flags.LdFlagsDeps = append(flags.LdFlagsDeps, cfiExportsMap)
 				}
 			}
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 5b7ba43..4470f54 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -16,7 +16,6 @@
 
 import (
 	"path/filepath"
-	"strings"
 
 	"android/soong/android"
 	"android/soong/bazel"
@@ -208,12 +207,13 @@
 			})
 
 			// TODO(b/220898484): Mainline module sdk prebuilts of stub libraries use a stub
-			// library as their source and must not be installed, but libclang_rt.* libraries
-			// have stubs because they are LLNDK libraries, but use an implementation library
-			// as their source and need to be installed.  This discrepancy should be resolved
-			// without the prefix hack below.
-			if p.hasStubsVariants() && !p.buildStubs() && !ctx.Host() &&
-				!strings.HasPrefix(ctx.baseModuleName(), "libclang_rt.") {
+			// library as their source and must not be installed, but other prebuilts like
+			// libclang_rt.* libraries set `stubs` property because they are LLNDK libraries,
+			// but use an implementation library as their source and need to be installed.
+			// This discrepancy should be resolved without the prefix hack below.
+			isModuleSdkPrebuilts := android.HasAnyPrefix(ctx.ModuleDir(), []string{
+				"prebuilts/runtime/mainline/", "prebuilts/module_sdk/"})
+			if p.hasStubsVariants() && !p.buildStubs() && !ctx.Host() && isModuleSdkPrebuilts {
 				ctx.Module().MakeUninstallable()
 			}
 
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index e3ec9d5..0c79e55 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -670,11 +670,15 @@
 }
 
 func TestPrebuiltStubNoinstall(t *testing.T) {
-	testFunc := func(t *testing.T, bp string) {
+	testFunc := func(t *testing.T, expectLibfooOnSystemLib bool, fs android.MockFS) {
 		result := android.GroupFixturePreparers(
 			prepareForPrebuiltTest,
 			android.PrepareForTestWithMakevars,
-		).RunTestWithBp(t, bp)
+			android.FixtureMergeMockFs(fs),
+		).RunTest(t)
+
+		ldRule := result.ModuleForTests("installedlib", "android_arm64_armv8-a_shared").Rule("ld")
+		android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared/libfoo.so")
 
 		installRules := result.InstallMakeRulesForTesting(t)
 		var installedlibRule *android.InstallMakeRule
@@ -691,50 +695,83 @@
 			return
 		}
 
-		android.AssertStringListDoesNotContain(t,
-			"installedlib has install dependency on stub",
-			installedlibRule.Deps,
-			"out/target/product/test_device/system/lib/stublib.so")
-		android.AssertStringListDoesNotContain(t,
-			"installedlib has order-only install dependency on stub",
-			installedlibRule.OrderOnlyDeps,
-			"out/target/product/test_device/system/lib/stublib.so")
+		if expectLibfooOnSystemLib {
+			android.AssertStringListContains(t,
+				"installedlib doesn't have install dependency on libfoo impl",
+				installedlibRule.OrderOnlyDeps,
+				"out/target/product/test_device/system/lib/libfoo.so")
+		} else {
+			android.AssertStringListDoesNotContain(t,
+				"installedlib has install dependency on libfoo stub",
+				installedlibRule.Deps,
+				"out/target/product/test_device/system/lib/libfoo.so")
+			android.AssertStringListDoesNotContain(t,
+				"installedlib has order-only install dependency on libfoo stub",
+				installedlibRule.OrderOnlyDeps,
+				"out/target/product/test_device/system/lib/libfoo.so")
+		}
 	}
 
-	const prebuiltStublibBp = `
+	prebuiltLibfooBp := []byte(`
 		cc_prebuilt_library {
-			name: "stublib",
+			name: "libfoo",
 			prefer: true,
-			srcs: ["foo.so"],
+			srcs: ["libfoo.so"],
 			stubs: {
 				versions: ["1"],
 			},
 		}
-	`
+	`)
 
-	const installedlibBp = `
+	installedlibBp := []byte(`
 		cc_library {
 			name: "installedlib",
-			shared_libs: ["stublib"],
+			shared_libs: ["libfoo"],
 		}
-	`
+	`)
 
-	t.Run("prebuilt without source", func(t *testing.T) {
-		testFunc(t, prebuiltStublibBp+installedlibBp)
+	t.Run("prebuilt stub (without source): no install", func(t *testing.T) {
+		testFunc(
+			t,
+			/*expectLibfooOnSystemLib=*/ false,
+			android.MockFS{
+				"prebuilts/module_sdk/art/current/Android.bp": prebuiltLibfooBp,
+				"Android.bp": installedlibBp,
+			},
+		)
 	})
 
-	const disabledSourceStublibBp = `
+	disabledSourceLibfooBp := []byte(`
 		cc_library {
-			name: "stublib",
+			name: "libfoo",
 			enabled: false,
 			stubs: {
 				versions: ["1"],
 			},
 		}
-	`
+	`)
 
-	t.Run("prebuilt with disabled source", func(t *testing.T) {
-		testFunc(t, disabledSourceStublibBp+prebuiltStublibBp+installedlibBp)
+	t.Run("prebuilt stub (with disabled source): no install", func(t *testing.T) {
+		testFunc(
+			t,
+			/*expectLibfooOnSystemLib=*/ false,
+			android.MockFS{
+				"prebuilts/module_sdk/art/current/Android.bp": prebuiltLibfooBp,
+				"impl/Android.bp": disabledSourceLibfooBp,
+				"Android.bp":      installedlibBp,
+			},
+		)
+	})
+
+	t.Run("prebuilt impl (with `stubs` property set): install", func(t *testing.T) {
+		testFunc(
+			t,
+			/*expectLibfooOnSystemLib=*/ true,
+			android.MockFS{
+				"impl/Android.bp": prebuiltLibfooBp,
+				"Android.bp":      installedlibBp,
+			},
+		)
 	})
 }
 
diff --git a/cc/sanitize.go b/cc/sanitize.go
index c899cc4..cc81d0e 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -62,14 +62,18 @@
 		"-fast-isel=false",
 	}
 
-	cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
-		"-fsanitize-ignorelist=external/compiler-rt/lib/cfi/cfi_blocklist.txt"}
+	cfiBlocklistPath     = "external/compiler-rt/lib/cfi"
+	cfiBlocklistFilename = "cfi_blocklist.txt"
+	cfiCflags            = []string{"-flto", "-fsanitize-cfi-cross-dso",
+		"-fsanitize-ignorelist=" + cfiBlocklistPath + "/" + cfiBlocklistFilename}
 	// -flto and -fvisibility are required by clang when -fsanitize=cfi is
 	// used, but have no effect on assembly files
 	cfiAsflags = []string{"-flto", "-fvisibility=default"}
 	cfiLdflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fsanitize=cfi",
 		"-Wl,-plugin-opt,O1"}
-	cfiExportsMapPath = "build/soong/cc/config/cfi_exports.map"
+	cfiExportsMapPath      = "build/soong/cc/config"
+	cfiExportsMapFilename  = "cfi_exports.map"
+	cfiAssemblySupportFlag = "-fno-sanitize-cfi-canonical-jump-tables"
 
 	intOverflowCflags = []string{"-fsanitize-ignorelist=build/soong/cc/config/integer_overflow_blocklist.txt"}
 
@@ -388,6 +392,18 @@
 	exportedVars.ExportStringListStaticVariable("HostOnlySanitizeFlags", hostOnlySanitizeFlags)
 	exportedVars.ExportStringList("DeviceOnlySanitizeFlags", deviceOnlySanitizeFlags)
 
+	// Leave out "-flto" from the slices exported to bazel, as we will use the
+	// dedicated LTO feature for this
+	exportedVars.ExportStringList("CfiCFlags", cfiCflags[1:])
+	exportedVars.ExportStringList("CfiAsFlags", cfiAsflags[1:])
+	exportedVars.ExportStringList("CfiLdFlags", cfiLdflags[1:])
+
+	exportedVars.ExportString("CfiBlocklistPath", cfiBlocklistPath)
+	exportedVars.ExportString("CfiBlocklistFilename", cfiBlocklistFilename)
+	exportedVars.ExportString("CfiExportsMapPath", cfiExportsMapPath)
+	exportedVars.ExportString("CfiExportsMapFilename", cfiExportsMapFilename)
+	exportedVars.ExportString("CfiAssemblySupportFlag", cfiAssemblySupportFlag)
+
 	android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
 	android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
 }
@@ -810,7 +826,7 @@
 		flags.Local.CFlags = append(flags.Local.CFlags, cfiCflags...)
 		flags.Local.AsFlags = append(flags.Local.AsFlags, cfiAsflags...)
 		if Bool(s.Properties.Sanitize.Config.Cfi_assembly_support) {
-			flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-cfi-canonical-jump-tables")
+			flags.Local.CFlags = append(flags.Local.CFlags, cfiAssemblySupportFlag)
 		}
 		// Only append the default visibility flag if -fvisibility has not already been set
 		// to hidden.
diff --git a/java/aar.go b/java/aar.go
index f162a17..47e6efa 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -721,8 +721,8 @@
 	return a.SdkVersion(ctx).ApiLevel
 }
 
-func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
-	return android.SdkSpecFrom(ctx, "")
+func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
+	return android.SdkSpecFrom(ctx, "").ApiLevel
 }
 
 func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
diff --git a/java/base.go b/java/base.go
index 2d213a1..1bcff2e 100644
--- a/java/base.go
+++ b/java/base.go
@@ -490,7 +490,7 @@
 
 	sdkVersion    android.SdkSpec
 	minSdkVersion android.ApiLevel
-	maxSdkVersion android.SdkSpec
+	maxSdkVersion android.ApiLevel
 
 	sourceExtensions []string
 }
@@ -672,16 +672,20 @@
 	return j.SdkVersion(ctx).ApiLevel
 }
 
-func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
-	maxSdkVersion := proptools.StringDefault(j.deviceProperties.Max_sdk_version, "")
-	// SdkSpecFrom returns SdkSpecPrivate for this, which may be confusing.
-	// TODO(b/208456999): ideally MaxSdkVersion should be an ApiLevel and not SdkSpec.
-	return android.SdkSpecFrom(ctx, maxSdkVersion)
+func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
+	if j.deviceProperties.Max_sdk_version != nil {
+		return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version)
+	}
+	// Default is PrivateApiLevel
+	return android.SdkSpecPrivate.ApiLevel
 }
 
-func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
-	replaceMaxSdkVersionPlaceholder := proptools.StringDefault(j.deviceProperties.Replace_max_sdk_version_placeholder, "")
-	return android.SdkSpecFrom(ctx, replaceMaxSdkVersionPlaceholder)
+func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
+	if j.deviceProperties.Replace_max_sdk_version_placeholder != nil {
+		return android.ApiLevelFrom(ctx, *j.deviceProperties.Replace_max_sdk_version_placeholder)
+	}
+	// Default is PrivateApiLevel
+	return android.SdkSpecPrivate.ApiLevel
 }
 
 func (j *Module) MinSdkVersionString() string {
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index 45e6175..bc9de50 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -136,11 +136,11 @@
 							jar.minSdkVersion = s.minSdkVersion.String()
 						}
 					}
-					if s.maxSdkVersion.ApiLevel.Specified() {
-						if s.maxSdkVersion.ApiLevel.IsCurrent() {
+					if s.maxSdkVersion.Specified() {
+						if s.maxSdkVersion.IsCurrent() {
 							jar.maxSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
 						} else {
-							jar.maxSdkVersion = s.maxSdkVersion.ApiLevel.String()
+							jar.maxSdkVersion = s.maxSdkVersion.String()
 						}
 					}
 				}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index c5a957e..dbe021d 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -252,8 +252,8 @@
 	return j.SdkVersion(ctx).ApiLevel
 }
 
-func (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
-	return j.SdkVersion(ctx)
+func (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
+	return j.SdkVersion(ctx).ApiLevel
 }
 
 func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
diff --git a/java/java.go b/java/java.go
index 3707815..ebd9f5e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1613,10 +1613,15 @@
 	android.ModuleBase
 	android.DefaultableModuleBase
 
+	hiddenAPI
+	dexer
+
 	properties JavaApiLibraryProperties
 
 	stubsSrcJar android.WritablePath
 	stubsJar    android.WritablePath
+	// .dex of stubs, used for hiddenapi processing
+	dexJarFile OptionalDexJarPath
 }
 
 type JavaApiLibraryProperties struct {
@@ -1794,6 +1799,20 @@
 		Inputs(staticLibs)
 	builder.Build("merge_zips", "merge jar files")
 
+	// compile stubs to .dex for hiddenapi processing
+	dexParams := &compileDexParams{
+		flags:         javaBuilderFlags{},
+		sdkVersion:    al.SdkVersion(ctx),
+		minSdkVersion: al.MinSdkVersion(ctx),
+		classesJar:    al.stubsJar,
+		jarName:       ctx.ModuleName() + ".jar",
+	}
+	dexOutputFile := al.dexer.compileDex(ctx, dexParams)
+	uncompressed := true
+	al.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), al.stubsJar, &uncompressed)
+	dexOutputFile = al.hiddenAPIEncodeDex(ctx, dexOutputFile)
+	al.dexJarFile = makeDexJarPathFromPath(dexOutputFile)
+
 	ctx.Phony(ctx.ModuleName(), al.stubsJar)
 
 	ctx.SetProvider(JavaInfoProvider, JavaInfo{
@@ -1801,6 +1820,32 @@
 	})
 }
 
+func (al *ApiLibrary) DexJarBuildPath() OptionalDexJarPath {
+	return al.dexJarFile
+}
+
+func (al *ApiLibrary) DexJarInstallPath() android.Path {
+	return al.dexJarFile.Path()
+}
+
+func (al *ApiLibrary) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
+	return nil
+}
+
+// java_api_library constitutes the sdk, and does not build against one
+func (al *ApiLibrary) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	return android.SdkSpecNone
+}
+
+// java_api_library is always at "current". Return FutureApiLevel
+func (al *ApiLibrary) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
+	return android.FutureApiLevel
+}
+
+// implement the following interfaces for hiddenapi processing
+var _ hiddenAPIModule = (*ApiLibrary)(nil)
+var _ UsesLibraryDependency = (*ApiLibrary)(nil)
+
 //
 // Java prebuilts
 //
@@ -1898,11 +1943,12 @@
 	return j.SdkVersion(ctx).ApiLevel
 }
 
-func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
+func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
 	if j.properties.Replace_max_sdk_version_placeholder != nil {
-		return android.SdkSpecFrom(ctx, *j.properties.Replace_max_sdk_version_placeholder)
+		return android.ApiLevelFrom(ctx, *j.properties.Replace_max_sdk_version_placeholder)
 	}
-	return android.SdkSpecFrom(ctx, "")
+	// Default is PrivateApiLevel
+	return android.SdkSpecPrivate.ApiLevel
 }
 
 func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
diff --git a/java/rro.go b/java/rro.go
index 6a9ad9a..53faca0 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -182,8 +182,8 @@
 	return r.SdkVersion(ctx).ApiLevel
 }
 
-func (r *RuntimeResourceOverlay) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
-	return android.SdkSpecFrom(ctx, "")
+func (r *RuntimeResourceOverlay) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
+	return android.SdkSpecPrivate.ApiLevel
 }
 
 func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
diff --git a/rust/Android.bp b/rust/Android.bp
index 3fd68e5..b01a94a 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -42,6 +42,7 @@
         "toolchain_library.go",
     ],
     testSrcs: [
+        "afdo_test.go",
         "benchmark_test.go",
         "binary_test.go",
         "bindgen_test.go",
diff --git a/rust/afdo_test.go b/rust/afdo_test.go
new file mode 100644
index 0000000..fa20eef
--- /dev/null
+++ b/rust/afdo_test.go
@@ -0,0 +1,76 @@
+// Copyright 2023 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 rust
+
+import (
+	"android/soong/android"
+	"fmt"
+	"strings"
+	"testing"
+)
+
+func TestAfdoEnabled(t *testing.T) {
+	bp := `
+	rust_binary {
+		name: "foo",
+		srcs: ["foo.rs"],
+		afdo: true,
+	}
+`
+	result := android.GroupFixturePreparers(
+		prepareForRustTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/foo.afdo", ""),
+		rustMockedFiles.AddToFixture(),
+	).RunTestWithBp(t, bp)
+
+	foo := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+
+	expectedCFlag := fmt.Sprintf(afdoFlagFormat, "toolchain/pgo-profiles/sampling/foo.afdo")
+
+	if !strings.Contains(foo.Args["rustcFlags"], expectedCFlag) {
+		t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", expectedCFlag, foo.Args["rustcFlags"])
+	}
+}
+
+func TestAfdoEnabledWithMultiArchs(t *testing.T) {
+	bp := `
+	rust_binary {
+		name: "foo",
+		srcs: ["foo.rs"],
+		afdo: true,
+		compile_multilib: "both",
+	}
+`
+	result := android.GroupFixturePreparers(
+		prepareForRustTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/foo_arm.afdo", ""),
+		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/foo_arm64.afdo", ""),
+		rustMockedFiles.AddToFixture(),
+	).RunTestWithBp(t, bp)
+
+	fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon").Rule("rustc")
+	fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+
+	expectedCFlagArm := fmt.Sprintf(afdoFlagFormat, "toolchain/pgo-profiles/sampling/foo_arm.afdo")
+	expectedCFlagArm64 := fmt.Sprintf(afdoFlagFormat, "toolchain/pgo-profiles/sampling/foo_arm64.afdo")
+
+	if !strings.Contains(fooArm.Args["rustcFlags"], expectedCFlagArm) {
+		t.Errorf("Expected 'fooArm' to enable afdo, but did not find %q in cflags %q", expectedCFlagArm, fooArm.Args["rustcFlags"])
+	}
+
+	if !strings.Contains(fooArm64.Args["rustcFlags"], expectedCFlagArm64) {
+		t.Errorf("Expected 'fooArm64' to enable afdo, but did not find %q in cflags %q", expectedCFlagArm64, fooArm64.Args["rustcFlags"])
+	}
+}
diff --git a/tests/apex_cc_module_arch_variant_tests.sh b/tests/apex_cc_module_arch_variant_tests.sh
index b0cade1..1f5e003 100755
--- a/tests/apex_cc_module_arch_variant_tests.sh
+++ b/tests/apex_cc_module_arch_variant_tests.sh
@@ -56,12 +56,12 @@
 
 # Number of CppCompile actions with arch variant flag
 actions_with_arch_variant_num=$(call_bazel aquery --config=bp2build --config=ci --config=android \
-  'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex))' | grep -c \'-march=$ARCH_VARIANT_CFLAG\')
+  'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' | grep -c \'-march=$ARCH_VARIANT_CFLAG\')
 
 # Number of all CppCompile actions
 all_cppcompile_actions_num=0
 aquery_summary=$(call_bazel aquery --config=bp2build --config=ci --config=android --output=summary \
-  'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex))' \
+  'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' \
   | egrep -o '.*opt-ST.*: ([0-9]+)$' \
   | cut -d: -f2 -)
 
@@ -82,7 +82,7 @@
 then
   # Number of CppCompiler actions with cpu variant flag
   actions_with_cpu_variant_num=$(call_bazel aquery --config=bp2build --config=ci --config=android \
-    'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex))' | grep -c "\-mcpu=$CPU_VARIANT_CFLAG")
+    'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' | grep -c "\-mcpu=$CPU_VARIANT_CFLAG")
 
   if [ $actions_with_cpu_variant_num -eq $all_cppcompile_actions_num ]
   then
@@ -91,4 +91,4 @@
     echo "Error: number of CppCompile actions with cpu variant set: actual=$actions_with_cpu_variant_num, expected=$all_cppcompile_actions_num"
     exit 1
   fi
-fi
\ No newline at end of file
+fi
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
index 5007078..e350323 100755
--- a/tests/apex_comparison_tests.sh
+++ b/tests/apex_comparison_tests.sh
@@ -66,10 +66,10 @@
 call_bazel build --config=bp2build --config=ci --config=android \
   //packages/modules/adb/apex:com.android.adbd \
   //system/timezone/apex:com.android.tzdata \
-  //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex
+  //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal
 BAZEL_ADBD="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //packages/modules/adb/apex:com.android.adbd))"
 BAZEL_TZDATA="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //system/timezone/apex:com.android.tzdata))"
-BAZEL_MINIMAL="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex))"
+BAZEL_MINIMAL="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))"
 
 # # Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg.
 call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs //system/apex/tools:deapexer
diff --git a/tests/lib.sh b/tests/lib.sh
index 2bcb630..26608b8 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -91,6 +91,7 @@
   symlink_directory prebuilts/go
   symlink_directory prebuilts/build-tools
   symlink_directory prebuilts/clang/host
+  symlink_directory external/compiler-rt
   symlink_directory external/go-cmp
   symlink_directory external/golang-protobuf
   symlink_directory external/starlark-go