Merge "Remove support for removed_dex_api_filename"
diff --git a/bazel/properties.go b/bazel/properties.go
index 491a154..1ff4cd3 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -140,7 +140,6 @@
 // Return all needles in a given haystack, where needleFn is true for needles.
 func FilterLabelList(haystack LabelList, needleFn func(string) bool) LabelList {
 	var includes []Label
-
 	for _, inc := range haystack.Includes {
 		if needleFn(inc.Label) {
 			includes = append(includes, inc)
@@ -308,19 +307,19 @@
 	}
 
 	PlatformTargetMap = map[string]string{
-		TARGET_ANDROID_ARM:         "//build/bazel/platforms:android_arm",
-		TARGET_ANDROID_ARM64:       "//build/bazel/platforms:android_arm64",
-		TARGET_ANDROID_X86:         "//build/bazel/platforms:android_x86",
-		TARGET_ANDROID_X86_64:      "//build/bazel/platforms:android_x86_64",
-		TARGET_DARWIN_X86_64:       "//build/bazel/platforms:darwin_x86_64",
-		TARGET_FUCHSIA_ARM64:       "//build/bazel/platforms:fuchsia_arm64",
-		TARGET_FUCHSIA_X86_64:      "//build/bazel/platforms:fuchsia_x86_64",
-		TARGET_LINUX_X86:           "//build/bazel/platforms:linux_glibc_x86",
-		TARGET_LINUX_x86_64:        "//build/bazel/platforms:linux_glibc_x86_64",
-		TARGET_LINUX_BIONIC_ARM64:  "//build/bazel/platforms:linux_bionic_arm64",
-		TARGET_LINUX_BIONIC_X86_64: "//build/bazel/platforms:linux_bionic_x86_64",
-		TARGET_WINDOWS_X86:         "//build/bazel/platforms:windows_x86",
-		TARGET_WINDOWS_X86_64:      "//build/bazel/platforms:windows_x86_64",
+		TARGET_ANDROID_ARM:         "//build/bazel/platforms/os_arch:android_arm",
+		TARGET_ANDROID_ARM64:       "//build/bazel/platforms/os_arch:android_arm64",
+		TARGET_ANDROID_X86:         "//build/bazel/platforms/os_arch:android_x86",
+		TARGET_ANDROID_X86_64:      "//build/bazel/platforms/os_arch:android_x86_64",
+		TARGET_DARWIN_X86_64:       "//build/bazel/platforms/os_arch:darwin_x86_64",
+		TARGET_FUCHSIA_ARM64:       "//build/bazel/platforms/os_arch:fuchsia_arm64",
+		TARGET_FUCHSIA_X86_64:      "//build/bazel/platforms/os_arch:fuchsia_x86_64",
+		TARGET_LINUX_X86:           "//build/bazel/platforms/os_arch:linux_glibc_x86",
+		TARGET_LINUX_x86_64:        "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
+		TARGET_LINUX_BIONIC_ARM64:  "//build/bazel/platforms/os_arch:linux_bionic_arm64",
+		TARGET_LINUX_BIONIC_X86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64",
+		TARGET_WINDOWS_X86:         "//build/bazel/platforms/os_arch:windows_x86",
+		TARGET_WINDOWS_X86_64:      "//build/bazel/platforms/os_arch:windows_x86_64",
 		CONDITIONS_DEFAULT:         ConditionsDefaultSelectKey, // The default condition of an os select map.
 	}
 
@@ -509,7 +508,6 @@
 	X86_64 LabelList
 	Arm    LabelList
 	Arm64  LabelList
-	Common LabelList
 
 	ConditionsDefault LabelList
 }
@@ -755,7 +753,6 @@
 	X86_64 []string
 	Arm    []string
 	Arm64  []string
-	Common []string
 
 	ConditionsDefault []string
 }
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 388c8cf..6bdfc0e 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -445,7 +445,7 @@
 		return prettyPrint(propertyValue.Elem(), indent)
 	case reflect.Slice:
 		if propertyValue.Len() == 0 {
-			return "", nil
+			return "[]", nil
 		}
 
 		if propertyValue.Len() == 1 {
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 49f1f42..b87d713 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -497,7 +497,7 @@
         "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/platforms:android_arm": ["-DANDROID_ARM_SHARED"],
+        "//build/bazel/platforms/os_arch:android_arm": ["-DANDROID_ARM_SHARED"],
         "//conditions:default": [],
     }),
     shared_srcs = ["sharedonly.cpp"] + select({
@@ -844,8 +844,8 @@
     ],
     srcs = ["a.cpp"],
     version_script = select({
-        "//build/bazel/platforms:android_arm": "android_arm.map",
-        "//build/bazel/platforms:linux_bionic_arm64": "linux_bionic_arm64.map",
+        "//build/bazel/platforms/os_arch:android_arm": "android_arm.map",
+        "//build/bazel/platforms/os_arch:linux_bionic_arm64": "linux_bionic_arm64.map",
         "//conditions:default": None,
     }),
 )`},
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 833ceba..90146bb 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -850,6 +850,84 @@
 	})
 }
 
+func TestCcLibraryStaticOneArchEmpty(t *testing.T) {
+	runCcLibraryStaticTestCase(t, bp2buildTestCase{
+		description:                        "cc_library_static one arch empty",
+		moduleTypeUnderTest:                "cc_library_static",
+		moduleTypeUnderTestFactory:         cc.LibraryStaticFactory,
+		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+		depsMutators:                       []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+		filesystem: map[string]string{
+			"common.cc":       "",
+			"foo-no-arm.cc":   "",
+			"foo-excluded.cc": "",
+		},
+		blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+    name: "foo_static",
+    srcs: ["common.cc", "foo-*.cc"],
+    exclude_srcs: ["foo-excluded.cc"],
+    arch: {
+        arm: { exclude_srcs: ["foo-no-arm.cc"] },
+    },
+}`,
+		expectedBazelTargets: []string{`cc_library_static(
+    name = "foo_static",
+    copts = [
+        "-I.",
+        "-I$(BINDIR)/.",
+    ],
+    linkstatic = True,
+    srcs = ["common.cc"] + select({
+        "//build/bazel/platforms/arch:arm": [],
+        "//conditions:default": ["foo-no-arm.cc"],
+    }),
+)`},
+	})
+}
+
+func TestCcLibraryStaticOneArchEmptyOtherSet(t *testing.T) {
+	runCcLibraryStaticTestCase(t, bp2buildTestCase{
+		description:                        "cc_library_static one arch empty other set",
+		moduleTypeUnderTest:                "cc_library_static",
+		moduleTypeUnderTestFactory:         cc.LibraryStaticFactory,
+		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+		depsMutators:                       []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+		filesystem: map[string]string{
+			"common.cc":       "",
+			"foo-no-arm.cc":   "",
+			"x86-only.cc":     "",
+			"foo-excluded.cc": "",
+		},
+		blueprint: soongCcLibraryStaticPreamble + `
+cc_library_static {
+    name: "foo_static",
+    srcs: ["common.cc", "foo-*.cc"],
+    exclude_srcs: ["foo-excluded.cc"],
+    arch: {
+        arm: { exclude_srcs: ["foo-no-arm.cc"] },
+        x86: { srcs: ["x86-only.cc"] },
+    },
+}`,
+		expectedBazelTargets: []string{`cc_library_static(
+    name = "foo_static",
+    copts = [
+        "-I.",
+        "-I$(BINDIR)/.",
+    ],
+    linkstatic = True,
+    srcs = ["common.cc"] + select({
+        "//build/bazel/platforms/arch:arm": [],
+        "//build/bazel/platforms/arch:x86": [
+            "foo-no-arm.cc",
+            "x86-only.cc",
+        ],
+        "//conditions:default": ["foo-no-arm.cc"],
+    }),
+)`},
+	})
+}
+
 func TestCcLibraryStaticMultipleDepSameName(t *testing.T) {
 	runCcLibraryStaticTestCase(t, bp2buildTestCase{
 		description:                        "cc_library_static multiple dep same name panic",
@@ -1204,14 +1282,14 @@
         "//build/bazel/platforms/os:android": ["android_src.c"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/platforms:android_arm": ["android_arm_src.c"],
-        "//build/bazel/platforms:android_arm64": ["android_arm64_src.c"],
-        "//build/bazel/platforms:android_x86": ["android_x86_src.c"],
-        "//build/bazel/platforms:android_x86_64": ["android_x86_64_src.c"],
+        "//build/bazel/platforms/os_arch:android_arm": ["android_arm_src.c"],
+        "//build/bazel/platforms/os_arch:android_arm64": ["android_arm64_src.c"],
+        "//build/bazel/platforms/os_arch:android_x86": ["android_x86_src.c"],
+        "//build/bazel/platforms/os_arch:android_x86_64": ["android_x86_64_src.c"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/platforms:linux_bionic_arm64": ["linux_bionic_arm64_src.c"],
-        "//build/bazel/platforms:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
+        "//build/bazel/platforms/os_arch:linux_bionic_arm64": ["linux_bionic_arm64_src.c"],
+        "//build/bazel/platforms/os_arch:linux_bionic_x86_64": ["linux_bionic_x86_64_src.c"],
         "//conditions:default": [],
     }),
 )`},
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index c13e737..7e1a298 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -128,32 +128,55 @@
 	if !list.HasConfigurableValues() {
 		return value, []selects{}
 	}
+	var ret []selects
 
 	archSelects := map[string]reflect.Value{}
 	for arch, selectKey := range bazel.PlatformArchMap {
-		archSelects[selectKey] = reflect.ValueOf(list.GetValueForArch(arch).Includes)
+		if use, value := labelListSelectValue(selectKey, list.GetValueForArch(arch)); use {
+			archSelects[selectKey] = value
+		}
+	}
+	if len(archSelects) > 0 {
+		ret = append(ret, archSelects)
 	}
 
 	osSelects := map[string]reflect.Value{}
-	osArchSelects := make([]selects, 0)
+	osArchSelects := []selects{}
 	for _, os := range android.SortedStringKeys(bazel.PlatformOsMap) {
 		selectKey := bazel.PlatformOsMap[os]
-		osSelects[selectKey] = reflect.ValueOf(list.GetOsValueForTarget(os).Includes)
-		archSelects := make(map[string]reflect.Value)
+		if use, value := labelListSelectValue(selectKey, list.GetOsValueForTarget(os)); use {
+			osSelects[selectKey] = value
+		}
+		selects := make(map[string]reflect.Value)
 		// TODO(b/187530594): Should we also check arch=CONDITIOSN_DEFAULT? (not in AllArches)
 		for _, arch := range bazel.AllArches {
 			target := os + "_" + arch
 			selectKey := bazel.PlatformTargetMap[target]
-			archSelects[selectKey] = reflect.ValueOf(list.GetOsArchValueForTarget(os, arch).Includes)
+			if use, value := labelListSelectValue(selectKey, list.GetOsArchValueForTarget(os, arch)); use {
+				selects[selectKey] = value
+			}
 		}
-		osArchSelects = append(osArchSelects, archSelects)
+		if len(selects) > 0 {
+			osArchSelects = append(osArchSelects, selects)
+		}
 	}
+	if len(osSelects) > 0 {
+		ret = append(ret, osSelects)
+	}
+	ret = append(ret, osArchSelects...)
 
-	var selects []selects
-	selects = append(selects, archSelects)
-	selects = append(selects, osSelects)
-	selects = append(selects, osArchSelects...)
-	return value, selects
+	return value, ret
+}
+
+func labelListSelectValue(selectKey string, list bazel.LabelList) (bool, reflect.Value) {
+	if selectKey == bazel.ConditionsDefaultSelectKey || len(list.Includes) > 0 {
+		return true, reflect.ValueOf(list.Includes)
+	} else if len(list.Excludes) > 0 {
+		// if there is still an excludes -- we need to have an empty list for this select & use the
+		// value in conditions default Includes
+		return true, reflect.ValueOf([]string{})
+	}
+	return false, reflect.Zero(reflect.TypeOf([]string{}))
 }
 
 // prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 711410c..f911c42 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -266,6 +266,66 @@
 	return attrs
 }
 
+// Convenience struct to hold all attributes parsed from prebuilt properties.
+type prebuiltAttributes struct {
+	Src bazel.LabelAttribute
+}
+
+func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
+	prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
+	prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
+
+	var srcLabelAttribute bazel.LabelAttribute
+
+	if len(prebuiltLinker.properties.Srcs) > 1 {
+		ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
+	}
+
+	if len(prebuiltLinker.properties.Srcs) == 1 {
+		srcLabelAttribute.Value = android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0])
+		for arch, props := range module.GetArchProperties(ctx, &prebuiltLinkerProperties{}) {
+			if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
+				if len(prebuiltLinkerProperties.Srcs) > 1 {
+					ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for arch %s\n", arch.Name)
+				}
+				if len(prebuiltLinkerProperties.Srcs) == 1 {
+					srcLabelAttribute.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0]))
+				}
+			}
+		}
+	}
+
+	for os, targetProperties := range module.GetTargetProperties(ctx, &prebuiltLinkerProperties{}) {
+		if prebuiltLinkerProperties, ok := targetProperties.Properties.(*prebuiltLinkerProperties); ok {
+			if len(prebuiltLinkerProperties.Srcs) > 1 {
+				ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for os %s\n", os.Name)
+
+			}
+
+			if len(prebuiltLinkerProperties.Srcs) == 1 {
+				srcLabelAttribute.SetOsValueForTarget(os.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0]))
+			}
+		}
+		for arch, archProperties := range targetProperties.ArchProperties {
+			if prebuiltLinkerProperties, ok := archProperties.(*prebuiltLinkerProperties); ok {
+				if len(prebuiltLinkerProperties.Srcs) > 1 {
+					ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for os_arch %s_%s\n", os.Name, arch.Name)
+
+				}
+
+				if len(prebuiltLinkerProperties.Srcs) == 1 {
+					srcLabelAttribute.SetOsArchValueForTarget(os.Name, arch.Name, android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0]))
+				}
+			}
+
+		}
+	}
+
+	return prebuiltAttributes{
+		Src: srcLabelAttribute,
+	}
+}
+
 // Convenience struct to hold all attributes parsed from compiler properties.
 type compilerAttributes struct {
 	// Options for all languages
@@ -421,7 +481,9 @@
 		if baseCompilerProps, ok := osProps.Properties.(*BaseCompilerProperties); ok {
 			srcsList := parseSrcs(baseCompilerProps)
 			// TODO(b/186153868): add support for os-specific srcs and exclude_srcs
-			srcs.SetOsValueForTarget(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+			if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
+				srcs.SetOsValueForTarget(os.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+			}
 			copts.SetOsValueForTarget(os.Name, parseCopts(baseCompilerProps))
 			asFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Asflags))
 			conlyFlags.SetOsValueForTarget(os.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags))
@@ -431,7 +493,9 @@
 			if baseCompilerProps, ok := archProps.(*BaseCompilerProperties); ok {
 				srcsList := parseSrcs(baseCompilerProps)
 				// TODO(b/186153868): add support for os-specific srcs and exclude_srcs
-				srcs.SetOsArchValueForTarget(os.Name, arch.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+				if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
+					srcs.SetOsArchValueForTarget(os.Name, arch.Name, bazel.SubtractBazelLabelList(srcsList, baseSrcsLabelList))
+				}
 				copts.SetOsArchValueForTarget(os.Name, arch.Name, parseCopts(baseCompilerProps))
 				asFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Asflags))
 				conlyFlags.SetOsArchValueForTarget(os.Name, arch.Name, parseCommandLineFlags(baseCompilerProps.Conlyflags))
@@ -629,11 +693,20 @@
 	return relativePaths
 }
 
-// bp2BuildParseExportedIncludes creates a string list attribute contains the
-// exported included directories of a module.
 func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
 	libraryDecorator := module.linker.(*libraryDecorator)
+	return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
+}
 
+func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
+	prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
+	libraryDecorator := prebuiltLibraryLinker.libraryDecorator
+	return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
+}
+
+// bp2BuildParseExportedIncludes creates a string list attribute contains the
+// exported included directories of a module.
+func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
 	// Export_system_include_dirs and export_include_dirs are already module dir
 	// relative, so they don't need to be relativized like include_dirs, which
 	// are root-relative.
diff --git a/python/test.go b/python/test.go
index 6713189..7413782 100644
--- a/python/test.go
+++ b/python/test.go
@@ -15,6 +15,8 @@
 package python
 
 import (
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 	"android/soong/tradefed"
 )
@@ -102,6 +104,9 @@
 	binary.pythonInstaller = NewPythonInstaller("nativetest", "nativetest64")
 
 	test := &testDecorator{binaryDecorator: binary}
+	if hod == android.HostSupportedNoCross && test.testProperties.Test_options.Unit_test == nil {
+		test.testProperties.Test_options.Unit_test = proptools.BoolPtr(true)
+	}
 
 	module.bootstrapper = test
 	module.installer = test
diff --git a/rust/snapshot_utils.go b/rust/snapshot_utils.go
index e0ed1f7..943c790 100644
--- a/rust/snapshot_utils.go
+++ b/rust/snapshot_utils.go
@@ -20,12 +20,12 @@
 
 func (mod *Module) ExcludeFromVendorSnapshot() bool {
 	// TODO Rust does not yet support snapshotting
-	return true
+	return false
 }
 
 func (mod *Module) ExcludeFromRecoverySnapshot() bool {
 	// TODO Rust does not yet support snapshotting
-	return true
+	return false
 }
 
 func (mod *Module) IsSnapshotLibrary() bool {