Merge "Refactor mixed build allowlist handling"
diff --git a/android/arch.go b/android/arch.go
index a0895ed..1952b17 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -619,6 +619,12 @@
 		mctx.ModuleErrorf("%s", err.Error())
 	}
 
+	// If there are no supported targets disable the module.
+	if len(targets) == 0 {
+		base.Disable()
+		return
+	}
+
 	// If the module is using extraMultilib, decode the extraMultilib selection into
 	// a separate list of Targets.
 	var multiTargets []Target
@@ -627,6 +633,7 @@
 		if err != nil {
 			mctx.ModuleErrorf("%s", err.Error())
 		}
+		multiTargets = filterHostCross(multiTargets, targets[0].HostCross)
 	}
 
 	// Recovery is always the primary architecture, filter out any other architectures.
@@ -763,6 +770,18 @@
 	return targets
 }
 
+// filterHostCross takes a list of Targets and a hostCross value, and returns a modified list
+// that contains only Targets that have the specified HostCross.
+func filterHostCross(targets []Target, hostCross bool) []Target {
+	for i := 0; i < len(targets); i++ {
+		if targets[i].HostCross != hostCross {
+			targets = append(targets[:i], targets[i+1:]...)
+			i--
+		}
+	}
+	return targets
+}
+
 // archPropRoot is a struct type used as the top level of the arch-specific properties.  It
 // contains the "arch", "multilib", and "target" property structs.  It is used to split up the
 // property structs to limit how much is allocated when a single arch-specific property group is
@@ -1795,20 +1814,23 @@
 }
 
 // FirstTarget takes a list of Targets and a list of multilib values and returns a list of Targets
-// that contains zero or one Target for each OsType, selecting the one that matches the earliest
-// filter.
+// that contains zero or one Target for each OsType and HostCross, selecting the one that matches
+// the earliest filter.
 func FirstTarget(targets []Target, filters ...string) []Target {
 	// find the first target from each OS
 	var ret []Target
-	hasHost := false
-	set := make(map[OsType]bool)
+	type osHostCross struct {
+		os        OsType
+		hostCross bool
+	}
+	set := make(map[osHostCross]bool)
 
 	for _, filter := range filters {
 		buildTargets := filterMultilibTargets(targets, filter)
 		for _, t := range buildTargets {
-			if _, found := set[t.Os]; !found {
-				hasHost = hasHost || (t.Os.Class == Host)
-				set[t.Os] = true
+			key := osHostCross{t.Os, t.HostCross}
+			if _, found := set[key]; !found {
+				set[key] = true
 				ret = append(ret, t)
 			}
 		}
diff --git a/android/arch_test.go b/android/arch_test.go
index ad2076d..6814f8a 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -259,6 +259,27 @@
 	}
 }
 
+func (m *archTestMultiTargetsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+}
+
+func (m *archTestMultiTargetsModule) DepsMutator(ctx BottomUpMutatorContext) {
+	ctx.AddDependency(ctx.Module(), nil, m.props.Deps...)
+}
+
+func archTestMultiTargetsModuleFactory() Module {
+	m := &archTestMultiTargetsModule{}
+	m.AddProperties(&m.props)
+	InitAndroidMultiTargetsArchModule(m, HostAndDeviceSupported, MultilibCommon)
+	return m
+}
+
+type archTestMultiTargetsModule struct {
+	ModuleBase
+	props struct {
+		Deps []string
+	}
+}
+
 func (m *archTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
 }
 
@@ -277,19 +298,27 @@
 	PrepareForTestWithArchMutator,
 	FixtureRegisterWithContext(func(ctx RegistrationContext) {
 		ctx.RegisterModuleType("module", archTestModuleFactory)
+		ctx.RegisterModuleType("multi_targets_module", archTestMultiTargetsModuleFactory)
 	}),
 )
 
 func TestArchMutator(t *testing.T) {
 	var buildOSVariants []string
+	var buildOS64Variants []string
 	var buildOS32Variants []string
+	var buildOSCommonVariant string
+
 	switch runtime.GOOS {
 	case "linux":
 		buildOSVariants = []string{"linux_glibc_x86_64", "linux_glibc_x86"}
+		buildOS64Variants = []string{"linux_glibc_x86_64"}
 		buildOS32Variants = []string{"linux_glibc_x86"}
+		buildOSCommonVariant = "linux_glibc_common"
 	case "darwin":
 		buildOSVariants = []string{"darwin_x86_64"}
+		buildOS64Variants = []string{"darwin_x86_64"}
 		buildOS32Variants = nil
+		buildOSCommonVariant = "darwin_common"
 	}
 
 	bp := `
@@ -312,24 +341,46 @@
 			host_supported: true,
 			compile_multilib: "32",
 		}
+
+		module {
+			name: "first",
+			host_supported: true,
+			compile_multilib: "first",
+		}
+
+		multi_targets_module {
+			name: "multi_targets",
+			host_supported: true,
+		}
 	`
 
 	testCases := []struct {
-		name        string
-		preparer    FixturePreparer
-		fooVariants []string
-		barVariants []string
-		bazVariants []string
-		quxVariants []string
+		name          string
+		preparer      FixturePreparer
+		fooVariants   []string
+		barVariants   []string
+		bazVariants   []string
+		quxVariants   []string
+		firstVariants []string
+
+		multiTargetVariants    []string
+		multiTargetVariantsMap map[string][]string
+
+		goOS string
 	}{
 		{
-			name:        "normal",
-			preparer:    nil,
-			fooVariants: []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
-			barVariants: append(buildOSVariants, "android_arm64_armv8-a", "android_arm_armv7-a-neon"),
-			bazVariants: nil,
-			quxVariants: append(buildOS32Variants, "android_arm_armv7-a-neon"),
-		},
+			name:                "normal",
+			preparer:            nil,
+			fooVariants:         []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
+			barVariants:         append(buildOSVariants, "android_arm64_armv8-a", "android_arm_armv7-a-neon"),
+			bazVariants:         nil,
+			quxVariants:         append(buildOS32Variants, "android_arm_armv7-a-neon"),
+			firstVariants:       append(buildOS64Variants, "android_arm64_armv8-a"),
+			multiTargetVariants: []string{buildOSCommonVariant, "android_common"},
+			multiTargetVariantsMap: map[string][]string{
+				buildOSCommonVariant: buildOS64Variants,
+				"android_common":     {"android_arm64_armv8-a"},
+			}},
 		{
 			name: "host-only",
 			preparer: FixtureModifyConfig(func(config Config) {
@@ -337,10 +388,33 @@
 				config.BuildOSCommonTarget = Target{}
 				config.Targets[Android] = nil
 			}),
-			fooVariants: nil,
-			barVariants: buildOSVariants,
-			bazVariants: nil,
-			quxVariants: buildOS32Variants,
+			fooVariants:         nil,
+			barVariants:         buildOSVariants,
+			bazVariants:         nil,
+			quxVariants:         buildOS32Variants,
+			firstVariants:       buildOS64Variants,
+			multiTargetVariants: []string{buildOSCommonVariant},
+			multiTargetVariantsMap: map[string][]string{
+				buildOSCommonVariant: buildOS64Variants,
+			},
+		},
+		{
+			name: "same arch host and host cross",
+			preparer: FixtureModifyConfig(func(config Config) {
+				modifyTestConfigForMusl(config)
+				modifyTestConfigForMuslArm64HostCross(config)
+			}),
+			fooVariants:         []string{"android_arm64_armv8-a", "android_arm_armv7-a-neon"},
+			barVariants:         []string{"linux_musl_x86_64", "linux_musl_arm64", "linux_musl_x86", "android_arm64_armv8-a", "android_arm_armv7-a-neon"},
+			bazVariants:         nil,
+			quxVariants:         []string{"linux_musl_x86", "android_arm_armv7-a-neon"},
+			firstVariants:       []string{"linux_musl_x86_64", "linux_musl_arm64", "android_arm64_armv8-a"},
+			multiTargetVariants: []string{"linux_musl_common", "android_common"},
+			multiTargetVariantsMap: map[string][]string{
+				"linux_musl_common": {"linux_musl_x86_64"},
+				"android_common":    {"android_arm64_armv8-a"},
+			},
+			goOS: "linux",
 		},
 	}
 
@@ -356,8 +430,21 @@
 		return ret
 	}
 
+	moduleMultiTargets := func(ctx *TestContext, name string, variant string) []string {
+		var ret []string
+		targets := ctx.ModuleForTests(name, variant).Module().MultiTargets()
+		for _, t := range targets {
+			ret = append(ret, t.String())
+		}
+		return ret
+	}
+
 	for _, tt := range testCases {
 		t.Run(tt.name, func(t *testing.T) {
+			if tt.goOS != runtime.GOOS {
+				t.Skipf("requries runtime.GOOS %s", tt.goOS)
+			}
+
 			result := GroupFixturePreparers(
 				prepareForArchTest,
 				// Test specific preparer
@@ -381,6 +468,20 @@
 			if g, w := enabledVariants(ctx, "qux"), tt.quxVariants; !reflect.DeepEqual(w, g) {
 				t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
 			}
+			if g, w := enabledVariants(ctx, "first"), tt.firstVariants; !reflect.DeepEqual(w, g) {
+				t.Errorf("want first variants:\n%q\ngot:\n%q\n", w, g)
+			}
+
+			if g, w := enabledVariants(ctx, "multi_targets"), tt.multiTargetVariants; !reflect.DeepEqual(w, g) {
+				t.Fatalf("want multi_target variants:\n%q\ngot:\n%q\n", w, g)
+			}
+
+			for _, variant := range tt.multiTargetVariants {
+				targets := moduleMultiTargets(ctx, "multi_targets", variant)
+				if g, w := targets, tt.multiTargetVariantsMap[variant]; !reflect.DeepEqual(w, g) {
+					t.Errorf("want ctx.MultiTarget() for %q:\n%q\ngot:\n%q\n", variant, w, g)
+				}
+			}
 		})
 	}
 }
diff --git a/android/config.go b/android/config.go
index a9d465e..5ca9420 100644
--- a/android/config.go
+++ b/android/config.go
@@ -742,7 +742,7 @@
 }
 
 func (c *config) MinSupportedSdkVersion() ApiLevel {
-	return uncheckedFinalApiLevel(19)
+	return uncheckedFinalApiLevel(21)
 }
 
 func (c *config) FinalApiLevels() []ApiLevel {
diff --git a/android/test_config.go b/android/test_config.go
index f36e8ba..0f88d51 100644
--- a/android/test_config.go
+++ b/android/test_config.go
@@ -118,6 +118,11 @@
 	config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
 }
 
+func modifyTestConfigForMuslArm64HostCross(config Config) {
+	config.Targets[LinuxMusl] = append(config.Targets[LinuxMusl],
+		Target{config.BuildOS, Arch{ArchType: Arm64}, NativeBridgeDisabled, "", "", true})
+}
+
 // TestArchConfig returns a Config object suitable for using for tests that
 // need to run the arch mutator.
 func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index d32e619..5cee6ac 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -134,13 +134,13 @@
 sharedLibraries = []
 rootSharedLibraries = []
 
-shared_info_tag = "@_builtins//:common/cc/experimental_cc_shared_library.bzl%CcSharedLibraryInfo"
+shared_info_tag = "//build/bazel/rules/cc:cc_library_shared.bzl%CcSharedLibraryOutputInfo"
+
 if shared_info_tag in providers(target):
   shared_info = providers(target)[shared_info_tag]
-  for lib in shared_info.linker_input.libraries:
-    path = lib.dynamic_library.path
-    rootSharedLibraries += [path]
-    sharedLibraries.append(path)
+  path = shared_info.output_file.path
+  sharedLibraries.append(path)
+  rootSharedLibraries += [path]
 else:
   for linker_input in linker_inputs:
     for library in linker_input.libraries:
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index bb59c63..5846f83 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -390,3 +390,24 @@
 		},
 	})
 }
+
+func TestCcLibraryHeadersWholeStaticLibsReexported(t *testing.T) {
+	runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library_headers whole_static_libs is reexported",
+		ModuleTypeUnderTest:        "cc_library_headers",
+		ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+		Filesystem:                 map[string]string{},
+		Blueprint: soongCcLibraryHeadersPreamble + `
+cc_library_headers {
+		name: "foo_headers",
+		whole_static_libs: ["foo_export"],
+    bazel_module: { bp2build_available: true },
+}
+` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+				"deps": `[":foo_export"]`,
+			}),
+		},
+	})
+}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 779160c..a957246 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -23,6 +23,7 @@
 	"strings"
 
 	"android/soong/android"
+	"android/soong/multitree"
 )
 
 var (
@@ -625,6 +626,24 @@
 	androidMkWriteAllowUndefinedSymbols(p.baseLinker, entries)
 }
 
+func (a *apiLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+	entries.Class = "SHARED_LIBRARIES"
+	entries.SubName += multitree.GetApiImportSuffix()
+
+	entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+		a.libraryDecorator.androidMkWriteExportedFlags(entries)
+		src := *a.properties.Src
+		path, file := filepath.Split(src)
+		stem, suffix, ext := android.SplitFileExt(file)
+		entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
+		entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
+		entries.SetString("LOCAL_MODULE_STEM", stem)
+		entries.SetString("LOCAL_MODULE_PATH", path)
+		entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+		entries.SetString("LOCAL_SOONG_TOC", a.toc().String())
+	})
+}
+
 func androidMkWriteAllowUndefinedSymbols(linker *baseLinker, entries *android.AndroidMkEntries) {
 	allow := linker.Properties.Allow_undefined_symbols
 	if allow != nil {
diff --git a/cc/builder.go b/cc/builder.go
index c289cbd..f3faca8 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -702,8 +702,10 @@
 			sAbiDumpFile := android.ObjPathWithExt(ctx, subdir, srcFile, "sdump")
 			sAbiDumpFiles = append(sAbiDumpFiles, sAbiDumpFile)
 
-			// TODO(b/226497964): dumpRule = sAbiDumpRE if USE_RBE and RBE_ABI_DUMPER are true.
 			dumpRule := sAbiDump
+			if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ABI_DUMPER") {
+				dumpRule = sAbiDumpRE
+			}
 			ctx.Build(pctx, android.BuildParams{
 				Rule:        dumpRule,
 				Description: "header-abi-dumper " + srcFile.Rel(),
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 792a8e0..f025700 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4145,7 +4145,7 @@
 		"${config.ArmArmv7ANeonCflags}",
 		"${config.ArmGenericCflags}",
 		"-target",
-		"armv7a-linux-androideabi20",
+		"armv7a-linux-androideabi21",
 	}
 
 	expectedIncludes := []string{
@@ -4176,7 +4176,6 @@
 		"external/foo/lib32",
 		"external/foo/libandroid_arm",
 		"defaults/cc/common/ndk_libc++_shared",
-		"defaults/cc/common/ndk_libandroid_support",
 	}
 
 	conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
@@ -4269,20 +4268,20 @@
 				},
 			},
 			stl: "libc++",
-			sdk_version: "20",
+			sdk_version: "minimum",
 		}
 
 		cc_library_headers {
 			name: "libheader1",
 			export_include_dirs: ["libheader1"],
-			sdk_version: "20",
+			sdk_version: "minimum",
 			stl: "none",
 		}
 
 		cc_library_headers {
 			name: "libheader2",
 			export_include_dirs: ["libheader2"],
-			sdk_version: "20",
+			sdk_version: "minimum",
 			stl: "none",
 		}
 	`, tc.src)
@@ -4306,7 +4305,7 @@
 			cc_library {
 				name: "%s",
 				export_include_dirs: ["%s"],
-				sdk_version: "20",
+				sdk_version: "minimum",
 				stl: "none",
 			}
 		`, lib, lib)
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 970d8d1..a683f58 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -126,6 +126,7 @@
 	exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, &baseAttributes.includes)
 	linkerAttrs := baseAttributes.linkerAttributes
 	(&linkerAttrs.deps).Append(linkerAttrs.dynamicDeps)
+	(&linkerAttrs.deps).Append(linkerAttrs.wholeArchiveDeps)
 
 	attrs := &bazelCcLibraryHeadersAttributes{
 		Export_includes:          exportedIncludes.Includes,
diff --git a/cc/library_stub.go b/cc/library_stub.go
index 14d1b96..fa6c279 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -68,6 +68,9 @@
 		apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{}
 	}
 
+	apiLibraryDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
+	apiLibraryDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
+
 	module.Init()
 
 	return module
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index a2d4503..867c36c 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -51,6 +51,9 @@
 	// symbols, etc), default true.
 	Check_elf_files *bool
 
+	// if set, add an extra objcopy --prefix-symbols= step
+	Prefix_symbols *string
+
 	// Optionally provide an import library if this is a Windows PE DLL prebuilt.
 	// This is needed only if this library is linked by other modules in build time.
 	// Only makes sense for the Windows target.
@@ -130,6 +133,13 @@
 
 		in := android.PathForModuleSrc(ctx, srcs[0])
 
+		if String(p.prebuiltLinker.properties.Prefix_symbols) != "" {
+			prefixed := android.PathForModuleOut(ctx, "prefixed", srcs[0])
+			transformBinaryPrefixSymbols(ctx, String(p.prebuiltLinker.properties.Prefix_symbols),
+				in, flagsToBuilderFlags(flags), prefixed)
+			in = prefixed
+		}
+
 		if p.static() {
 			depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
 			ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
index 513c606..bfd5cf8 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -84,12 +84,36 @@
     ],
 }
 
+// Same as core-current-stubs-for-system-modules, but android annotations are
+// stripped.
+java_library {
+    name: "core-current-stubs-for-system-modules-no-annotations",
+    visibility: ["//development/sdk"],
+    static_libs: [
+        "core-current-stubs-for-system-modules",
+    ],
+    sdk_version: "none",
+    system_modules: "none",
+    dists: [
+        {
+            // Legacy dist location for the public file.
+            dest: "core-for-system-modules-no-annotations.jar",
+            targets: dist_targets,
+        },
+        {
+            dest: "system-modules/public/core-for-system-modules-no-annotations.jar",
+            targets: dist_targets,
+        },
+    ],
+    jarjar_rules: "jarjar-strip-annotations-rules.txt",
+}
+
 // Used when compiling higher-level code against core.current.stubs.
 java_system_modules {
     name: "core-public-stubs-system-modules",
     visibility: ["//visibility:public"],
     libs: [
-        "core-current-stubs-for-system-modules",
+        "core-current-stubs-for-system-modules-no-annotations",
     ],
 }
 
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index f56964c..adc56ac 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -141,7 +141,6 @@
 	"PLATFORM_VERSION",
 	"TARGET_PRODUCT",
 	"TARGET_BUILD_VARIANT",
-	"TARGET_BUILD_TYPE",
 	"TARGET_BUILD_APPS",
 	"TARGET_BUILD_UNBUNDLED",
 	"TARGET_ARCH",
@@ -150,18 +149,11 @@
 	"TARGET_2ND_ARCH",
 	"TARGET_2ND_ARCH_VARIANT",
 	"TARGET_2ND_CPU_VARIANT",
-	"HOST_ARCH",
-	"HOST_2ND_ARCH",
 	"HOST_OS",
 	"HOST_OS_EXTRA",
 	"HOST_CROSS_OS",
-	"HOST_CROSS_ARCH",
-	"HOST_CROSS_2ND_ARCH",
-	"HOST_BUILD_TYPE",
 	"BUILD_ID",
 	"OUT_DIR",
-	"AUX_OS_VARIANT_LIST",
-	"PRODUCT_SOONG_NAMESPACES",
 	"SOONG_SDK_SNAPSHOT_PREFER",
 	"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
 	"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
@@ -236,6 +228,13 @@
 
 		// Not used, but useful to be in the soong.log
 		"BOARD_VNDK_VERSION",
+		"TARGET_BUILD_TYPE",
+		"HOST_ARCH",
+		"HOST_2ND_ARCH",
+		"HOST_CROSS_ARCH",
+		"HOST_CROSS_2ND_ARCH",
+		"HOST_BUILD_TYPE",
+		"PRODUCT_SOONG_NAMESPACES",
 
 		"DEFAULT_WARNING_BUILD_MODULE_TYPES",
 		"DEFAULT_ERROR_BUILD_MODULE_TYPES",