Merge "Darwin/Mac OS host rust compilation fixes" into main
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index 6927765..d2ddfdf 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -14,6 +14,7 @@
         "soong-bazel",
         "soong-android",
         "soong-java",
+        "soong-rust",
     ],
     srcs: [
         "aconfig_declarations.go",
@@ -24,6 +25,7 @@
         "init.go",
         "java_aconfig_library.go",
         "testing.go",
+        "rust_aconfig_library.go",
     ],
     testSrcs: [
         "aconfig_declarations_test.go",
diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go
index 565d185..d1d1578 100644
--- a/aconfig/aconfig_declarations.go
+++ b/aconfig/aconfig_declarations.go
@@ -17,8 +17,9 @@
 import (
 	"android/soong/android"
 	"fmt"
-	"github.com/google/blueprint"
 	"strings"
+
+	"github.com/google/blueprint"
 )
 
 type DeclarationsModule struct {
diff --git a/aconfig/init.go b/aconfig/init.go
index 37167aa..cfbd79d 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -16,6 +16,7 @@
 
 import (
 	"android/soong/android"
+
 	"github.com/google/blueprint"
 )
 
@@ -70,6 +71,20 @@
 			},
 		}, "gendir")
 
+	rustRule = pctx.AndroidStaticRule("rust_aconfig_library",
+		blueprint.RuleParams{
+			Command: `rm -rf ${gendir}` +
+				` && mkdir -p ${gendir}` +
+				` && ${aconfig} create-rust-lib` +
+				`    --mode ${mode}` +
+				`    --cache ${in}` +
+				`    --out ${gendir}`,
+			CommandDeps: []string{
+				"$aconfig",
+				"$soong_zip",
+			},
+		}, "gendir", "mode")
+
 	// For all_aconfig_declarations
 	allDeclarationsRule = pctx.AndroidStaticRule("all_aconfig_declarations_dump",
 		blueprint.RuleParams{
@@ -92,5 +107,6 @@
 	ctx.RegisterModuleType("aconfig_value_set", ValueSetFactory)
 	ctx.RegisterModuleType("cc_aconfig_library", CcAconfigLibraryFactory)
 	ctx.RegisterModuleType("java_aconfig_library", JavaDeclarationsLibraryFactory)
+	ctx.RegisterModuleType("rust_aconfig_library", RustAconfigLibraryFactory)
 	ctx.RegisterParallelSingletonType("all_aconfig_declarations", AllAconfigDeclarationsFactory)
 }
diff --git a/aconfig/rust_aconfig_library.go b/aconfig/rust_aconfig_library.go
new file mode 100644
index 0000000..8b16372
--- /dev/null
+++ b/aconfig/rust_aconfig_library.go
@@ -0,0 +1,83 @@
+package aconfig
+
+import (
+	"android/soong/android"
+	"android/soong/rust"
+	"fmt"
+
+	"github.com/google/blueprint"
+)
+
+type rustDeclarationsTagType struct {
+	blueprint.BaseDependencyTag
+}
+
+var rustDeclarationsTag = rustDeclarationsTagType{}
+
+type RustAconfigLibraryProperties struct {
+	// name of the aconfig_declarations module to generate a library for
+	Aconfig_declarations string
+}
+
+type aconfigDecorator struct {
+	*rust.BaseSourceProvider
+
+	Properties RustAconfigLibraryProperties
+}
+
+func NewRustAconfigLibrary(hod android.HostOrDeviceSupported) (*rust.Module, *aconfigDecorator) {
+	aconfig := &aconfigDecorator{
+		BaseSourceProvider: rust.NewSourceProvider(),
+		Properties:         RustAconfigLibraryProperties{},
+	}
+
+	module := rust.NewSourceProviderModule(android.HostAndDeviceSupported, aconfig, false, false)
+	return module, aconfig
+}
+
+// rust_aconfig_library generates aconfig rust code from the provided aconfig declaration. This module type will
+// create library variants that can be used as a crate dependency by adding it to the rlibs, dylibs, and rustlibs
+// properties of other modules.
+func RustAconfigLibraryFactory() android.Module {
+	module, _ := NewRustAconfigLibrary(android.HostAndDeviceSupported)
+	return module.Init()
+}
+
+func (a *aconfigDecorator) SourceProviderProps() []interface{} {
+	return append(a.BaseSourceProvider.SourceProviderProps(), &a.Properties)
+}
+
+func (a *aconfigDecorator) GenerateSource(ctx rust.ModuleContext, deps rust.PathDeps) android.Path {
+	generatedDir := android.PathForModuleGen(ctx)
+	generatedSource := android.PathForModuleGen(ctx, "src", "lib.rs")
+
+	declarationsModules := ctx.GetDirectDepsWithTag(rustDeclarationsTag)
+
+	if len(declarationsModules) != 1 {
+		panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
+	}
+	declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:  rustRule,
+		Input: declarations.IntermediatePath,
+		Outputs: []android.WritablePath{
+			generatedSource,
+		},
+		Description: "rust_aconfig_library",
+		Args: map[string]string{
+			"gendir": generatedDir.String(),
+			// TODO: Add test mode
+			"mode": "production",
+		},
+	})
+	a.BaseSourceProvider.OutputFiles = android.Paths{generatedSource}
+	return generatedSource
+}
+
+func (a *aconfigDecorator) SourceProviderDeps(ctx rust.DepsContext, deps rust.Deps) rust.Deps {
+	deps = a.BaseSourceProvider.SourceProviderDeps(ctx, deps)
+	deps.Rustlibs = append(deps.Rustlibs, "libflags_rust")
+	ctx.AddDependency(ctx.Module(), rustDeclarationsTag, a.Properties.Aconfig_declarations)
+	return deps
+}
diff --git a/aconfig/rust_aconfig_library_test.go b/aconfig/rust_aconfig_library_test.go
new file mode 100644
index 0000000..17385c3
--- /dev/null
+++ b/aconfig/rust_aconfig_library_test.go
@@ -0,0 +1,60 @@
+package aconfig
+
+import (
+	"android/soong/android"
+	"android/soong/rust"
+	"fmt"
+	"testing"
+)
+
+func TestRustAconfigLibrary(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithAconfigBuildComponents,
+		rust.PrepareForTestWithRustIncludeVndk,
+		android.PrepareForTestWithArchMutator,
+		android.PrepareForTestWithDefaults,
+		android.PrepareForTestWithPrebuilts,
+	).
+		ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
+		RunTestWithBp(t, fmt.Sprintf(`
+			rust_library {
+				name: "libflags_rust", // test mock
+				crate_name: "flags_rust",
+				srcs: ["lib.rs"],
+			}
+			aconfig_declarations {
+				name: "my_aconfig_declarations",
+				package: "com.example.package",
+				srcs: ["foo.aconfig"],
+			}
+
+			rust_aconfig_library {
+				name: "libmy_rust_aconfig_library",
+				crate_name: "my_rust_aconfig_library",
+				aconfig_declarations: "my_aconfig_declarations",
+			}
+		`))
+
+	sourceVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_source")
+	rule := sourceVariant.Rule("rust_aconfig_library")
+	android.AssertStringEquals(t, "rule must contain production mode", rule.Args["mode"], "production")
+
+	dylibVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_dylib")
+	rlibRlibStdVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_rlib_rlib-std")
+	rlibDylibStdVariant := result.ModuleForTests("libmy_rust_aconfig_library", "android_arm64_armv8-a_rlib_dylib-std")
+
+	variants := []android.TestingModule{
+		dylibVariant,
+		rlibDylibStdVariant,
+		rlibRlibStdVariant,
+	}
+
+	for _, variant := range variants {
+		android.AssertStringEquals(
+			t,
+			"dylib variant builds from generated rust code",
+			"out/soong/.intermediates/libmy_rust_aconfig_library/android_arm64_armv8-a_source/gen/src/lib.rs",
+			variant.Rule("rustc").Inputs[0].RelativeToTop().String(),
+		)
+	}
+}
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index d37dc02..b921e41 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -439,6 +439,7 @@
 		"external/bazelbuild-rules_java":/* recursive = */ true,
 		"external/bazelbuild-rules_license":/* recursive = */ true,
 		"external/bazelbuild-rules_go":/* recursive = */ true,
+		"external/bazelbuild-rules_python":/* recursive = */ true,
 		"external/bazelbuild-kotlin-rules":/* recursive = */ true,
 		"external/bazel-skylib":/* recursive = */ true,
 		"external/protobuf":/* recursive = */ false,
@@ -479,6 +480,32 @@
 	}
 
 	Bp2buildModuleAlwaysConvertList = []string{
+		// ext
+		"tagsoup",
+
+		// framework-res
+		"remote-color-resources-compile-public",
+		"remote-color-resources-compile-colors",
+
+		// framework-minus-apex
+		"android.mime.types.minimized",
+		"debian.mime.types.minimized",
+		"framework-javastream-protos",
+		"libview-inspector-annotation-processor",
+
+		// services
+		"apache-commons-math",
+		"cbor-java",
+		"icu4j_calendar_astronomer",
+		"json",
+		"remote-color-resources-compile-public",
+		"statslog-art-java-gen",
+		"statslog-framework-java-gen",
+
+		"AndroidCommonLint",
+		"ImmutabilityAnnotation",
+		"ImmutabilityAnnotationProcessorHostLibrary",
+
 		"libidmap2_policies",
 		"libSurfaceFlingerProp",
 		"toolbox_input_labels",
@@ -937,7 +964,6 @@
 		"libdebuggerd_handler",                                       // depends on unconverted module libdebuggerd_handler_core
 		"libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd
 		"libdexfiled",                                             // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
-		"libfastdeploy_host",                                      // depends on unconverted modules: libandroidfw, libusb, AdbWinApi
 		"libgmock_main_ndk",                                       // depends on unconverted modules: libgtest_ndk_c++
 		"libgmock_ndk",                                            // depends on unconverted modules: libgtest_ndk_c++
 		"libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libnativetesthelper_jni, libgmock_ndk
@@ -991,8 +1017,6 @@
 		"svcenc", "svcdec",
 
 		// Failing host cc_tests
-		"libprocinfo_test",
-		"ziparchive-tests",
 		"gtest_isolated_tests",
 		"libunwindstack_unit_test",
 		"power_tests", // failing test on server, but not on host
@@ -1011,7 +1035,7 @@
 		"libnativebridge6-test-case",
 		"libnativebridge6prezygotefork",
 
-		"libandroidfw_tests", "aapt2_tests", // failing due to data path issues
+		"libandroidfw_tests", // failing due to data path issues
 
 		// error: overriding commands for target
 		// `out/host/linux-x86/nativetest64/gmock_tests/gmock_tests__cc_runner_test',
@@ -1098,7 +1122,6 @@
 		"memunreachable_binder_test", // depends on unconverted modules: libbinder
 		"memunreachable_test",
 		"metadata_tests",
-		"minijail0_cli_unittest_gtest",
 		"mpeg2dec",
 		"mvcdec",
 		"ns_hidden_child_helper",
@@ -1110,14 +1133,12 @@
 		"rappor-tests", // depends on unconverted modules: jsr305, guava
 		"scudo_unit_tests",
 		"stats-log-api-gen-test", // depends on unconverted modules: libstats_proto_host
-		"syscall_filter_unittest_gtest",
 		"thread_exit_cb_helper",
 		"tls_properties_helper",
 		"ulp",
 		"vec_test",
 		"yuvconstants",
 		"yuvconvert",
-		"zipalign_tests",
 
 		// cc_test_library
 		"clang_diagnostic_tests",
@@ -1525,6 +1546,10 @@
 		"libart_generated_headers",
 		"libart-runtime-gtest",
 		"libartd-runtime-gtest",
+		"libart-unstripped",
+
+		// depends on libart-unstripped and new module type llvm_prebuilt_build_tool
+		"check_cfi",
 	}
 
 	// Bazel prod-mode allowlist. Modules in this list are built by Bazel
diff --git a/android/bazel.go b/android/bazel.go
index 0d2c777..df30ff2 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -22,6 +22,7 @@
 
 	"android/soong/ui/metrics/bp2build_metrics_proto"
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android/allowlists"
@@ -426,8 +427,23 @@
 	return ModuleIncompatibility
 }
 
+func isGoModule(module blueprint.Module) bool {
+	if _, ok := module.(*bootstrap.GoPackage); ok {
+		return true
+	}
+	if _, ok := module.(*bootstrap.GoBinary); ok {
+		return true
+	}
+	return false
+}
+
 // ConvertedToBazel returns whether this module has been converted (with bp2build or manually) to Bazel.
 func convertedToBazel(ctx BazelConversionContext, module blueprint.Module) bool {
+	// Special-case bootstrap_go_package and bootstrap_go_binary
+	// These do not implement Bazelable, but have been converted
+	if isGoModule(module) {
+		return true
+	}
 	b, ok := module.(Bazelable)
 	if !ok {
 		return false
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index fd4b5ef..fda8a22 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -22,6 +22,7 @@
 	"os"
 	"path"
 	"path/filepath"
+	"regexp"
 	"runtime"
 	"sort"
 	"strings"
@@ -1054,9 +1055,23 @@
 
 func GetBazelSandwichCqueryRequests(config Config) ([]cqueryKey, error) {
 	result := make([]cqueryKey, 0, len(allowlists.BazelSandwichTargets))
+	labelRegex := regexp.MustCompile("^@?//([a-zA-Z0-9/_-]+):[a-zA-Z0-9_-]+$")
 	// Note that bazel "targets" are different from soong "targets", the bazel targets are
 	// synonymous with soong modules, and soong targets are a configuration a module is built in.
 	for _, target := range allowlists.BazelSandwichTargets {
+		match := labelRegex.FindStringSubmatch(target.Label)
+		if match == nil {
+			return nil, fmt.Errorf("invalid label, must match `^@?//([a-zA-Z0-9/_-]+):[a-zA-Z0-9_-]+$`: %s", target.Label)
+		}
+		if _, err := os.Stat(absolutePath(match[1])); err != nil {
+			if os.IsNotExist(err) {
+				// Ignore bazel sandwich targets that don't exist.
+				continue
+			} else {
+				return nil, err
+			}
+		}
+
 		var soongTarget Target
 		if target.Host {
 			soongTarget = config.BuildOSTarget
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 7568543..b08a4ca 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -431,7 +431,7 @@
 
 func BazelModuleLabel(ctx BazelConversionPathContext, module blueprint.Module) string {
 	// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
-	if !convertedToBazel(ctx, module) {
+	if !convertedToBazel(ctx, module) || isGoModule(module) {
 		return bp2buildModuleLabel(ctx, module)
 	}
 	b, _ := module.(Bazelable)
diff --git a/android/config.go b/android/config.go
index 72ff224..5c8b20b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -190,6 +190,12 @@
 	return String(c.config.productVariables.DeviceMaxPageSizeSupported)
 }
 
+// PageSizeAgnostic returns true when AOSP is page size agnostic,
+// othersise it returns false.
+func (c Config) PageSizeAgnostic() bool {
+	return Bool(c.config.productVariables.DevicePageSizeAgnostic)
+}
+
 // The release version passed to aconfig, derived from RELEASE_VERSION
 func (c Config) ReleaseVersion() string {
 	return c.config.productVariables.ReleaseVersion
@@ -414,6 +420,12 @@
 	return nil
 }
 
+type productVariableStarlarkRepresentation struct {
+	soongType   string
+	selectable  bool
+	archVariant bool
+}
+
 func saveToBazelConfigFile(config *ProductVariables, outDir string) error {
 	dir := filepath.Join(outDir, bazel.SoongInjectionDirName, "product_config")
 	err := createDirIfNonexistent(dir, os.ModePerm)
@@ -421,32 +433,39 @@
 		return fmt.Errorf("Could not create dir %s: %s", dir, err)
 	}
 
-	nonArchVariantProductVariables := []string{}
-	archVariantProductVariables := []string{}
+	allProductVariablesType := reflect.TypeOf((*ProductVariables)(nil)).Elem()
+	productVariablesInfo := make(map[string]productVariableStarlarkRepresentation)
 	p := variableProperties{}
 	t := reflect.TypeOf(p.Product_variables)
 	for i := 0; i < t.NumField(); i++ {
 		f := t.Field(i)
-		nonArchVariantProductVariables = append(nonArchVariantProductVariables, strings.ToLower(f.Name))
-		if proptools.HasTag(f, "android", "arch_variant") {
-			archVariantProductVariables = append(archVariantProductVariables, strings.ToLower(f.Name))
+		archVariant := proptools.HasTag(f, "android", "arch_variant")
+		if mainProductVariablesStructField, ok := allProductVariablesType.FieldByName(f.Name); ok {
+			productVariablesInfo[f.Name] = productVariableStarlarkRepresentation{
+				soongType:   stringRepresentationOfSimpleType(mainProductVariablesStructField.Type),
+				selectable:  true,
+				archVariant: archVariant,
+			}
+		} else {
+			panic("Unknown variable " + f.Name)
 		}
 	}
 
-	nonArchVariantProductVariablesJson := starlark_fmt.PrintStringList(nonArchVariantProductVariables, 0)
-	if err != nil {
-		return fmt.Errorf("cannot marshal product variable data: %s", err.Error())
-	}
-
-	archVariantProductVariablesJson := starlark_fmt.PrintStringList(archVariantProductVariables, 0)
-	if err != nil {
-		return fmt.Errorf("cannot marshal arch variant product variable data: %s", err.Error())
-	}
-
 	err = pathtools.WriteFileIfChanged(filepath.Join(dir, "product_variable_constants.bzl"), []byte(fmt.Sprintf(`
-product_var_constraints = %s
-arch_variant_product_var_constraints = %s
-`, nonArchVariantProductVariablesJson, archVariantProductVariablesJson)), 0644)
+# product_var_constant_info is a map of product variables to information about them. The fields are:
+# - soongType: The type of the product variable as it appears in soong's ProductVariables struct.
+#              examples are string, bool, int, *bool, *string, []string, etc. This may be an overly
+#              conservative estimation of the type, for example a *bool could oftentimes just be a
+#              bool that defaults to false.
+# - selectable: if this product variable can be selected on in Android.bp/build files. This means
+#               it's listed in the "variableProperties" soong struct. Currently all variables in
+#               this list are selectable because we only need the selectable ones at the moment,
+#               but the list may be expanded later.
+# - archVariant: If the variable is tagged as arch variant in the "variableProperties" struct.
+product_var_constant_info = %s
+product_var_constraints = [k for k, v in product_var_constant_info.items() if v.selectable]
+arch_variant_product_var_constraints = [k for k, v in product_var_constant_info.items() if v.selectable and v.archVariant]
+`, starlark_fmt.PrintAny(productVariablesInfo, 0))), 0644)
 	if err != nil {
 		return fmt.Errorf("Could not write .bzl config file %s", err)
 	}
@@ -459,6 +478,23 @@
 	return nil
 }
 
+func stringRepresentationOfSimpleType(ty reflect.Type) string {
+	switch ty.Kind() {
+	case reflect.String:
+		return "string"
+	case reflect.Bool:
+		return "bool"
+	case reflect.Int:
+		return "int"
+	case reflect.Slice:
+		return "[]" + stringRepresentationOfSimpleType(ty.Elem())
+	case reflect.Pointer:
+		return "*" + stringRepresentationOfSimpleType(ty.Elem())
+	default:
+		panic("unimplemented type: " + ty.Kind().String())
+	}
+}
+
 // NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
 // use the android package.
 func NullConfig(outDir, soongOutDir string) Config {
diff --git a/android/filegroup.go b/android/filegroup.go
index 3b86655..6cc9232 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -24,6 +24,7 @@
 	"android/soong/ui/metrics/bp2build_metrics_proto"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 )
 
 func init() {
@@ -141,8 +142,14 @@
 			attrs)
 	} else {
 		if fg.ShouldConvertToProtoLibrary(ctx) {
+			pkgToSrcs := partitionSrcsByPackage(ctx.ModuleDir(), bazel.MakeLabelList(srcs.Value.Includes))
+			if len(pkgToSrcs) > 1 {
+				ctx.ModuleErrorf("TODO: Add bp2build support for multiple package .protosrcs in filegroup")
+				return
+			}
+			pkg := SortedKeys(pkgToSrcs)[0]
 			attrs := &ProtoAttrs{
-				Srcs:                srcs,
+				Srcs:                bazel.MakeLabelListAttribute(pkgToSrcs[pkg]),
 				Strip_import_prefix: fg.properties.Path,
 			}
 
@@ -151,13 +158,39 @@
 				// TODO(b/246997908): we can remove this tag if we could figure out a solution for this bug.
 				"manual",
 			}
+			if pkg != ctx.ModuleDir() {
+				// Since we are creating the proto_library in a subpackage, create an import_prefix relative to the current package
+				if rel, err := filepath.Rel(ctx.ModuleDir(), pkg); err != nil {
+					ctx.ModuleErrorf("Could not get relative path for %v %v", pkg, err)
+				} else if rel != "." {
+					attrs.Import_prefix = &rel
+					// Strip the package prefix
+					attrs.Strip_import_prefix = proptools.StringPtr("")
+				}
+			}
+
 			ctx.CreateBazelTargetModule(
 				bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
 				CommonAttributes{
-					Name: fg.Name() + convertedProtoLibrarySuffix,
+					Name: fg.Name() + "_proto",
+					Dir:  proptools.StringPtr(pkg),
 					Tags: bazel.MakeStringListAttribute(tags),
 				},
 				attrs)
+
+			// Create an alias in the current dir. The actual target might exist in a different package, but rdeps
+			// can reliabily use this alias
+			ctx.CreateBazelTargetModule(
+				bazel.BazelTargetModuleProperties{Rule_class: "alias"},
+				CommonAttributes{
+					Name: fg.Name() + convertedProtoLibrarySuffix,
+					// TODO(b/246997908): we can remove this tag if we could figure out a solution for this bug.
+					Tags: bazel.MakeStringListAttribute(tags),
+				},
+				&bazelAliasAttributes{
+					Actual: bazel.MakeLabelAttribute("//" + pkg + ":" + fg.Name() + "_proto"),
+				},
+			)
 		}
 
 		// TODO(b/242847534): Still convert to a filegroup because other unconverted
diff --git a/android/module.go b/android/module.go
index 4c781f6..19502ba 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1021,6 +1021,11 @@
 	Applicable_licenses bazel.LabelListAttribute
 
 	Testonly *bool
+
+	// Dir is neither a Soong nor Bazel target attribute
+	// If set, the bazel target will be created in this directory
+	// If unset, the bazel target will default to be created in the directory of the visited soong module
+	Dir *string
 }
 
 // constraintAttributes represents Bazel attributes pertaining to build constraints,
@@ -1373,15 +1378,15 @@
 		}
 	}
 
-	productConfigEnabledLabels := []bazel.Label{}
+	productConfigEnabledAttribute := bazel.LabelListAttribute{}
 	// TODO(b/234497586): Soong config variables and product variables have different overriding behavior, we
 	// should handle it correctly
 	if !proptools.BoolDefault(enabledProperty.Value, true) && !neitherHostNorDevice {
 		// If the module is not enabled by default, then we can check if a
 		// product variable enables it
-		productConfigEnabledLabels = productVariableConfigEnableLabels(ctx)
+		productConfigEnabledAttribute = productVariableConfigEnableAttribute(ctx)
 
-		if len(productConfigEnabledLabels) > 0 {
+		if len(productConfigEnabledAttribute.ConfigurableValues) > 0 {
 			// In this case, an existing product variable configuration overrides any
 			// module-level `enable: false` definition
 			newValue := true
@@ -1389,10 +1394,6 @@
 		}
 	}
 
-	productConfigEnabledAttribute := bazel.MakeLabelListAttribute(bazel.LabelList{
-		productConfigEnabledLabels, nil,
-	})
-
 	platformEnabledAttribute, err := enabledProperty.ToLabelListAttribute(
 		bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil},
 		bazel.LabelList{[]bazel.Label{}, nil})
@@ -1423,31 +1424,35 @@
 
 // Check product variables for `enabled: true` flag override.
 // Returns a list of the constraint_value targets who enable this override.
-func productVariableConfigEnableLabels(ctx *topDownMutatorContext) []bazel.Label {
+func productVariableConfigEnableAttribute(ctx *topDownMutatorContext) bazel.LabelListAttribute {
+	result := bazel.LabelListAttribute{}
 	productVariableProps := ProductVariableProperties(ctx, ctx.Module())
-	productConfigEnablingTargets := []bazel.Label{}
-	const propName = "Enabled"
-	if productConfigProps, exists := productVariableProps[propName]; exists {
+	if productConfigProps, exists := productVariableProps["Enabled"]; exists {
 		for productConfigProp, prop := range productConfigProps {
 			flag, ok := prop.(*bool)
 			if !ok {
-				ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
+				ctx.ModuleErrorf("Could not convert product variable enabled property")
 			}
 
-			if *flag {
+			if flag == nil {
+				// soong config var is not used to set `enabled`. nothing to do.
+				continue
+			} else if *flag {
 				axis := productConfigProp.ConfigurationAxis()
-				targetLabel := axis.SelectKey(productConfigProp.SelectKey())
-				productConfigEnablingTargets = append(productConfigEnablingTargets, bazel.Label{
-					Label: targetLabel,
-				})
+				result.SetSelectValue(axis, bazel.ConditionsDefaultConfigKey, bazel.MakeLabelList([]bazel.Label{{Label: "@platforms//:incompatible"}}))
+				result.SetSelectValue(axis, productConfigProp.SelectKey(), bazel.LabelList{Includes: []bazel.Label{}})
+			} else if scp, isSoongConfigProperty := productConfigProp.(SoongConfigProperty); isSoongConfigProperty && scp.value == bazel.ConditionsDefaultConfigKey {
+				// productVariableConfigEnableAttribute runs only if `enabled: false` is set at the top-level outside soong_config_variables
+				// conditions_default { enabled: false} is a no-op in this case
+				continue
 			} else {
 				// TODO(b/210546943): handle negative case where `enabled: false`
-				ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943", proptools.PropertyNameForField(propName))
+				ctx.ModuleErrorf("`enabled: false` is not currently supported for configuration variables. See b/210546943")
 			}
 		}
 	}
 
-	return productConfigEnablingTargets
+	return result
 }
 
 // A ModuleBase object contains the properties that are common to all Android
diff --git a/android/mutator.go b/android/mutator.go
index 2ec051e..6bcac93 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -17,6 +17,7 @@
 import (
 	"android/soong/bazel"
 	"android/soong/ui/metrics/bp2build_metrics_proto"
+	"path/filepath"
 
 	"github.com/google/blueprint"
 )
@@ -757,6 +758,27 @@
 	mod.base().addBp2buildInfo(info)
 }
 
+// Returns the directory in which the bazel target will be generated
+// If ca.Dir is not nil, use that
+// Otherwise default to the directory of the soong module
+func dirForBazelTargetGeneration(t *topDownMutatorContext, ca *CommonAttributes) string {
+	dir := t.OtherModuleDir(t.Module())
+	if ca.Dir != nil {
+		dir = *ca.Dir
+		// Restrict its use to dirs that contain an Android.bp file.
+		// There are several places in bp2build where we use the existence of Android.bp/BUILD on the filesystem
+		// to curate a compatible label for src files (e.g. headers for cc).
+		// If we arbritrarily create BUILD files, then it might render those curated labels incompatible.
+		if exists, _, _ := t.Config().fs.Exists(filepath.Join(dir, "Android.bp")); !exists {
+			t.ModuleErrorf("Cannot use ca.Dir to create a BazelTarget in dir: %v since it does not contain an Android.bp file", dir)
+		}
+
+		// Set ca.Dir to nil so that it does not get emitted to the BUILD files
+		ca.Dir = nil
+	}
+	return dir
+}
+
 func (t *topDownMutatorContext) CreateBazelConfigSetting(
 	csa bazel.ConfigSettingAttributes,
 	ca CommonAttributes,
@@ -851,7 +873,7 @@
 	constraintAttributes := commonAttrs.fillCommonBp2BuildModuleAttrs(t, enabledProperty)
 	mod := t.Module()
 	info := bp2buildInfo{
-		Dir:             t.OtherModuleDir(mod),
+		Dir:             dirForBazelTargetGeneration(t, &commonAttrs),
 		BazelProps:      bazelProps,
 		CommonAttrs:     commonAttrs,
 		ConstraintAttrs: constraintAttributes,
diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
index e5edf91..aeae20f 100644
--- a/android/prebuilt_build_tool.go
+++ b/android/prebuilt_build_tool.go
@@ -102,6 +102,10 @@
 // prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use
 // in genrules with the "tools" property.
 func prebuiltBuildToolFactory() Module {
+	return NewPrebuiltBuildTool()
+}
+
+func NewPrebuiltBuildTool() Module {
 	module := &prebuiltBuildTool{}
 	module.AddProperties(&module.properties)
 	InitSingleSourcePrebuiltModule(module, &module.properties, "Src")
diff --git a/android/proto.go b/android/proto.go
index cebbd59..49b3733 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -15,6 +15,7 @@
 package android
 
 import (
+	"path/filepath"
 	"strings"
 
 	"android/soong/bazel"
@@ -156,12 +157,12 @@
 // Bp2buildProtoInfo contains information necessary to pass on to language specific conversion.
 type Bp2buildProtoInfo struct {
 	Type       *string
-	Name       string
 	Proto_libs bazel.LabelList
 }
 
 type ProtoAttrs struct {
 	Srcs                bazel.LabelListAttribute
+	Import_prefix       *string
 	Strip_import_prefix *string
 	Deps                bazel.LabelListAttribute
 }
@@ -172,6 +173,35 @@
 	"external/protobuf/src": "//external/protobuf:libprotobuf-proto",
 }
 
+// Partitions srcs by the pkg it is in
+// srcs has been created using `TransformSubpackagePaths`
+// This function uses existence of Android.bp/BUILD files to create a label that is compatible with the package structure of bp2build workspace
+func partitionSrcsByPackage(currentDir string, srcs bazel.LabelList) map[string]bazel.LabelList {
+	getPackageFromLabel := func(label string) string {
+		// Remove any preceding //
+		label = strings.TrimPrefix(label, "//")
+		split := strings.Split(label, ":")
+		if len(split) == 1 {
+			// e.g. foo.proto
+			return currentDir
+		} else if split[0] == "" {
+			// e.g. :foo.proto
+			return currentDir
+		} else {
+			return split[0]
+		}
+	}
+
+	pkgToSrcs := map[string]bazel.LabelList{}
+	for _, src := range srcs.Includes {
+		pkg := getPackageFromLabel(src.Label)
+		list := pkgToSrcs[pkg]
+		list.Add(&src)
+		pkgToSrcs[pkg] = list
+	}
+	return pkgToSrcs
+}
+
 // Bp2buildProtoProperties converts proto properties, creating a proto_library and returning the
 // information necessary for language-specific handling.
 func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, m *ModuleBase, srcs bazel.LabelListAttribute) (Bp2buildProtoInfo, bool) {
@@ -197,54 +227,78 @@
 		}
 	}
 
-	info.Name = m.Name() + "_proto"
+	name := m.Name() + "_proto"
+
+	depsFromFilegroup := protoLibraries
+	var canonicalPathFromRoot bool
 
 	if len(directProtoSrcs.Includes) > 0 {
-		attrs := ProtoAttrs{
-			Srcs: bazel.MakeLabelListAttribute(directProtoSrcs),
-		}
-		attrs.Deps.Append(bazel.MakeLabelListAttribute(protoLibraries))
+		pkgToSrcs := partitionSrcsByPackage(ctx.ModuleDir(), directProtoSrcs)
+		for _, pkg := range SortedStringKeys(pkgToSrcs) {
+			srcs := pkgToSrcs[pkg]
+			attrs := ProtoAttrs{
+				Srcs: bazel.MakeLabelListAttribute(srcs),
+			}
+			attrs.Deps.Append(bazel.MakeLabelListAttribute(depsFromFilegroup))
 
-		for axis, configToProps := range m.GetArchVariantProperties(ctx, &ProtoProperties{}) {
-			for _, rawProps := range configToProps {
-				var props *ProtoProperties
-				var ok bool
-				if props, ok = rawProps.(*ProtoProperties); !ok {
-					ctx.ModuleErrorf("Could not cast ProtoProperties to expected type")
-				}
-				if axis == bazel.NoConfigAxis {
-					info.Type = props.Proto.Type
-
-					if !proptools.BoolDefault(props.Proto.Canonical_path_from_root, canonicalPathFromRootDefault) {
-						// an empty string indicates to strips the package path
-						path := ""
-						attrs.Strip_import_prefix = &path
+			for axis, configToProps := range m.GetArchVariantProperties(ctx, &ProtoProperties{}) {
+				for _, rawProps := range configToProps {
+					var props *ProtoProperties
+					var ok bool
+					if props, ok = rawProps.(*ProtoProperties); !ok {
+						ctx.ModuleErrorf("Could not cast ProtoProperties to expected type")
 					}
+					if axis == bazel.NoConfigAxis {
+						info.Type = props.Proto.Type
 
-					for _, dir := range props.Proto.Include_dirs {
-						if dep, ok := includeDirsToProtoDeps[dir]; ok {
-							attrs.Deps.Add(bazel.MakeLabelAttribute(dep))
-						} else {
-							ctx.PropertyErrorf("Could not find the proto_library target for include dir", dir)
+						canonicalPathFromRoot = proptools.BoolDefault(props.Proto.Canonical_path_from_root, canonicalPathFromRootDefault)
+						if !canonicalPathFromRoot {
+							// an empty string indicates to strips the package path
+							path := ""
+							attrs.Strip_import_prefix = &path
 						}
+
+						for _, dir := range props.Proto.Include_dirs {
+							if dep, ok := includeDirsToProtoDeps[dir]; ok {
+								attrs.Deps.Add(bazel.MakeLabelAttribute(dep))
+							} else {
+								ctx.PropertyErrorf("Could not find the proto_library target for include dir", dir)
+							}
+						}
+					} else if props.Proto.Type != info.Type && props.Proto.Type != nil {
+						ctx.ModuleErrorf("Cannot handle arch-variant types for protos at this time.")
 					}
-				} else if props.Proto.Type != info.Type && props.Proto.Type != nil {
-					ctx.ModuleErrorf("Cannot handle arch-variant types for protos at this time.")
 				}
 			}
+
+			tags := ApexAvailableTagsWithoutTestApexes(ctx.(TopDownMutatorContext), ctx.Module())
+
+			moduleDir := ctx.ModuleDir()
+			if !canonicalPathFromRoot {
+				// Since we are creating the proto_library in a subpackage, set the import_prefix relative to the current package
+				if rel, err := filepath.Rel(moduleDir, pkg); err != nil {
+					ctx.ModuleErrorf("Could not get relative path for %v %v", pkg, err)
+				} else if rel != "." {
+					attrs.Import_prefix = &rel
+				}
+			}
+
+			ctx.CreateBazelTargetModule(
+				bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
+				CommonAttributes{Name: name, Dir: proptools.StringPtr(pkg), Tags: tags},
+				&attrs,
+			)
+
+			l := ""
+			if pkg == moduleDir { // same package that the original module lives in
+				l = ":" + name
+			} else {
+				l = "//" + pkg + ":" + name
+			}
+			protoLibraries.Add(&bazel.Label{
+				Label: l,
+			})
 		}
-
-		tags := ApexAvailableTagsWithoutTestApexes(ctx.(TopDownMutatorContext), ctx.Module())
-
-		ctx.CreateBazelTargetModule(
-			bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
-			CommonAttributes{Name: info.Name, Tags: tags},
-			&attrs,
-		)
-
-		protoLibraries.Add(&bazel.Label{
-			Label: ":" + info.Name,
-		})
 	}
 
 	info.Proto_libs = protoLibraries
diff --git a/android/variable.go b/android/variable.go
index 7fb81b9..664ead7 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -95,10 +95,6 @@
 			Cflags []string
 		}
 
-		Device_page_size_agnostic struct {
-			Cflags []string `android:"arch_variant"`
-		} `android:"arch_variant"`
-
 		Override_rs_driver struct {
 			Cflags []string
 		}
@@ -160,10 +156,6 @@
 			}
 		}
 
-		Pdk struct {
-			Enabled *bool `android:"arch_variant"`
-		} `android:"arch_variant"`
-
 		Uml struct {
 			Cppflags []string
 		}
@@ -231,6 +223,7 @@
 	DeviceCurrentApiLevelForVendorModules *string  `json:",omitempty"`
 	DeviceSystemSdkVersions               []string `json:",omitempty"`
 	DeviceMaxPageSizeSupported            *string  `json:",omitempty"`
+	DevicePageSizeAgnostic                *bool    `json:",omitempty"`
 
 	RecoverySnapshotVersion *string `json:",omitempty"`
 
@@ -286,7 +279,6 @@
 	Safestack                    *bool    `json:",omitempty"`
 	HostStaticBinaries           *bool    `json:",omitempty"`
 	Binder32bit                  *bool    `json:",omitempty"`
-	Device_page_size_agnostic    *bool    `json:",omitempty"`
 	UseGoma                      *bool    `json:",omitempty"`
 	UseRBE                       *bool    `json:",omitempty"`
 	UseRBEJAVAC                  *bool    `json:",omitempty"`
@@ -531,6 +523,7 @@
 		DeviceSecondaryCpuVariant:  stringPtr("generic"),
 		DeviceSecondaryAbi:         []string{"armeabi-v7a", "armeabi"},
 		DeviceMaxPageSizeSupported: stringPtr("4096"),
+		DevicePageSizeAgnostic:     boolPtr(false),
 
 		AAPTConfig:          []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
 		AAPTPreferredConfig: stringPtr("xhdpi"),
@@ -543,7 +536,6 @@
 		Safestack:                    boolPtr(false),
 		TrimmedApex:                  boolPtr(false),
 		Build_from_text_stub:         boolPtr(false),
-		Device_page_size_agnostic:    boolPtr(false),
 
 		BootJars:     ConfiguredJarList{apexes: []string{}, jars: []string{}},
 		ApexBootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
diff --git a/apex/apex.go b/apex/apex.go
index b26d1d2..8c21d3d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1685,6 +1685,7 @@
 	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
 		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
 	}
+	dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
 	fileToCopy := android.OutputFileForModule(ctx, rustm, "")
 	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
 	af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
@@ -1704,6 +1705,7 @@
 	if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
 		dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
 	}
+	dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
 	fileToCopy := android.OutputFileForModule(ctx, rustm, "")
 	androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
 	return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 9dba08e..bd19cb5 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2794,7 +2794,7 @@
 			name: "myapex",
 			key: "myapex.key",
 			native_shared_libs: ["mylib"],
-			binaries: ["mybin"],
+			binaries: ["mybin", "mybin.rust"],
 			prebuilts: ["myetc"],
 			compile_multilib: "both",
 			updatable: false,
@@ -2829,6 +2829,13 @@
 			stl: "none",
 			apex_available: [ "myapex" ],
 		}
+
+		rust_binary {
+			name: "mybin.rust",
+			srcs: ["foo.rs"],
+			relative_install_path: "rust_subdir",
+			apex_available: [ "myapex" ],
+		}
 	`)
 
 	generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("generateFsConfig")
@@ -2847,6 +2854,7 @@
 	ensureContains(t, cmd, "/bin ")
 	ensureContains(t, cmd, "/bin/foo ")
 	ensureContains(t, cmd, "/bin/foo/bar ")
+	ensureContains(t, cmd, "/bin/rust_subdir ")
 }
 
 func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
diff --git a/bazel/configurability.go b/bazel/configurability.go
index d962a1d..671e5c1 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -67,7 +67,7 @@
 
 	ConditionsDefaultSelectKey = "//conditions:default"
 
-	productVariableBazelPackage = "//build/bazel/product_variables"
+	productVariableBazelPackage = "//build/bazel/product_config/config_settings"
 
 	AndroidAndInApex = "android-in_apex"
 	AndroidPlatform  = "system"
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index 84c7ea2..2383247 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -1555,7 +1555,7 @@
 				"file_contexts": `":foo-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 				"min_sdk_version": `select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": "30",
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": "30",
         "//conditions:default": "31",
     })`,
 				"package_name": `"pkg_name"`,
@@ -1564,7 +1564,7 @@
 				"file_contexts":  `":foo-file_contexts"`,
 				"manifest":       `"apex_manifest.json"`,
 				"min_sdk_version": `select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": "30",
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": "30",
         "//conditions:default": "31",
     })`,
 				"package_name": `"override_pkg_name"`,
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index cfe52db..5f7b382 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -15,7 +15,6 @@
 package bp2build
 
 import (
-	"android/soong/starlark_import"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -24,6 +23,7 @@
 	"android/soong/android"
 	"android/soong/bazel"
 	"android/soong/shared"
+	"android/soong/starlark_import"
 )
 
 func deleteFilesExcept(ctx *CodegenContext, rootOutputPath android.OutputPath, except []BazelFile) {
@@ -67,6 +67,8 @@
 // writing .bzl files that are equivalent to Android.bp files that are capable
 // of being built with Bazel.
 func Codegen(ctx *CodegenContext) *CodegenMetrics {
+	ctx.Context().BeginEvent("Codegen")
+	defer ctx.Context().EndEvent("Codegen")
 	// This directory stores BUILD files that could be eventually checked-in.
 	bp2buildDir := android.PathForOutput(ctx, "bp2build")
 
@@ -79,7 +81,10 @@
 		fmt.Printf("ERROR: Encountered %d error(s): \nERROR: %s", len(errs), strings.Join(errMsgs, "\n"))
 		os.Exit(1)
 	}
-	bp2buildFiles := CreateBazelFiles(ctx.Config(), nil, res.buildFileToTargets, ctx.mode)
+	var bp2buildFiles []BazelFile
+	ctx.Context().EventHandler.Do("CreateBazelFile", func() {
+		bp2buildFiles = CreateBazelFiles(nil, res.buildFileToTargets, ctx.mode)
+	})
 	injectionFiles, additionalBp2buildFiles, err := CreateSoongInjectionDirFiles(ctx, res.metrics)
 	if err != nil {
 		fmt.Printf("%s\n", err.Error())
@@ -111,7 +116,7 @@
 func CreateSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) {
 	var ret []BazelFile
 
-	productConfigInjectionFiles, productConfigBp2BuildDirFiles, err := CreateProductConfigFiles(ctx)
+	productConfigInjectionFiles, productConfigBp2BuildDirFiles, err := CreateProductConfigFiles(ctx, metrics)
 	if err != nil {
 		return nil, nil, err
 	}
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
index 2513af8..e8c2ef7 100644
--- a/bp2build/bp2build_product_config.go
+++ b/bp2build/bp2build_product_config.go
@@ -2,6 +2,7 @@
 
 import (
 	"android/soong/android"
+	"android/soong/android/soongconfig"
 	"android/soong/starlark_import"
 	"encoding/json"
 	"fmt"
@@ -15,7 +16,8 @@
 )
 
 func CreateProductConfigFiles(
-	ctx *CodegenContext) ([]BazelFile, []BazelFile, error) {
+	ctx *CodegenContext,
+	metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) {
 	cfg := &ctx.config
 	targetProduct := "unknown"
 	if cfg.HasDeviceProduct() {
@@ -51,11 +53,24 @@
 		"{VARIANT}", targetBuildVariant,
 		"{PRODUCT_FOLDER}", currentProductFolder)
 
-	platformMappingContent, err := platformMappingContent(productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}"), &productVariables)
+	platformMappingContent, err := platformMappingContent(
+		productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}"),
+		&productVariables,
+		ctx.Config().Bp2buildSoongConfigDefinitions,
+		metrics.convertedModulePathMap)
 	if err != nil {
 		return nil, nil, err
 	}
 
+	productsForTestingMap, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
+	if err != nil {
+		return nil, nil, err
+	}
+	productsForTesting := android.SortedKeys(productsForTestingMap)
+	for i := range productsForTesting {
+		productsForTesting[i] = fmt.Sprintf("  \"@//build/bazel/tests/products:%s\",", productsForTesting[i])
+	}
+
 	injectionDirFiles := []BazelFile{
 		newFile(
 			currentProductFolder,
@@ -110,9 +125,8 @@
 # currently lunched product, they should all be listed here
 product_labels = [
   "@soong_injection//product_config_platforms:mixed_builds_product-{VARIANT}",
-  "@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}"
-]
-`)),
+  "@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}",
+`)+strings.Join(productsForTesting, "\n")+"\n]\n"),
 		newFile(
 			"product_config_platforms",
 			"common.bazelrc",
@@ -121,6 +135,7 @@
 build --platforms @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
 
 build:android --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}
+build:linux_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86
 build:linux_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
 build:linux_bionic_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_bionic_x86_64
 build:linux_musl_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86
@@ -148,20 +163,37 @@
 	return injectionDirFiles, bp2buildDirFiles, nil
 }
 
-func platformMappingContent(mainProductLabel string, mainProductVariables *android.ProductVariables) (string, error) {
+func platformMappingContent(
+	mainProductLabel string,
+	mainProductVariables *android.ProductVariables,
+	soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
+	convertedModulePathMap map[string]string) (string, error) {
 	productsForTesting, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
 	if err != nil {
 		return "", err
 	}
 	var result strings.Builder
+
+	mergedConvertedModulePathMap := make(map[string]string)
+	for k, v := range convertedModulePathMap {
+		mergedConvertedModulePathMap[k] = v
+	}
+	additionalModuleNamesToPackages, err := starlark_import.GetStarlarkValue[map[string]string]("additional_module_names_to_packages")
+	if err != nil {
+		return "", err
+	}
+	for k, v := range additionalModuleNamesToPackages {
+		mergedConvertedModulePathMap[k] = v
+	}
+
 	result.WriteString("platforms:\n")
-	platformMappingSingleProduct(mainProductLabel, mainProductVariables, &result)
+	platformMappingSingleProduct(mainProductLabel, mainProductVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
 	for product, productVariablesStarlark := range productsForTesting {
 		productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
 		if err != nil {
 			return "", err
 		}
-		platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables, &result)
+		platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
 	}
 	return result.String(), nil
 }
@@ -180,7 +212,12 @@
 	"_windows_x86_64",
 }
 
-func platformMappingSingleProduct(label string, productVariables *android.ProductVariables, result *strings.Builder) {
+func platformMappingSingleProduct(
+	label string,
+	productVariables *android.ProductVariables,
+	soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
+	convertedModulePathMap map[string]string,
+	result *strings.Builder) {
 	targetBuildVariant := "user"
 	if proptools.Bool(productVariables.Eng) {
 		targetBuildVariant = "eng"
@@ -188,33 +225,98 @@
 		targetBuildVariant = "userdebug"
 	}
 
+	platform_sdk_version := -1
+	if productVariables.Platform_sdk_version != nil {
+		platform_sdk_version = *productVariables.Platform_sdk_version
+	}
+
+	defaultAppCertificateFilegroup := "//build/bazel/utils:empty_filegroup"
+	if proptools.String(productVariables.DefaultAppCertificate) != "" {
+		defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":android_certificate_directory"
+	}
+
 	for _, suffix := range bazelPlatformSuffixes {
 		result.WriteString("  ")
 		result.WriteString(label)
 		result.WriteString(suffix)
 		result.WriteString("\n")
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:always_use_prebuilt_sdks=%t\n", proptools.Bool(productVariables.Always_use_prebuilt_sdks)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:arc=%t\n", proptools.Bool(productVariables.Arc)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:binder32bit=%t\n", proptools.Bool(productVariables.Binder32bit)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_from_text_stub=%t\n", proptools.Bool(productVariables.Build_from_text_stub)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ",")))
-		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:certificate_overrides=%s\n", strings.Join(productVariables.CertificateOverrides, ",")))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ",")))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:cfi_include_paths=%s\n", strings.Join(productVariables.CFIIncludePaths, ",")))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:compressed_apex=%t\n", proptools.Bool(productVariables.CompressedApex)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:debuggable=%t\n", proptools.Bool(productVariables.Debuggable)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:default_app_certificate=%s\n", proptools.String(productVariables.DefaultAppCertificate)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:default_app_certificate_filegroup=%s\n", defaultAppCertificateFilegroup))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_abi=%s\n", strings.Join(productVariables.DeviceAbi, ",")))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_max_page_size_supported=%s\n", proptools.String(productVariables.DeviceMaxPageSizeSupported)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_name=%s\n", proptools.String(productVariables.DeviceName)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_page_size_agnostic=%t\n", proptools.Bool(productVariables.DevicePageSizeAgnostic)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:device_product=%s\n", proptools.String(productVariables.DeviceProduct)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:enforce_vintf_manifest=%t\n", proptools.Bool(productVariables.Enforce_vintf_manifest)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:eng=%t\n", proptools.Bool(productVariables.Eng)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:malloc_not_svelte=%t\n", proptools.Bool(productVariables.Malloc_not_svelte)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:malloc_pattern_fill_contents=%t\n", proptools.Bool(productVariables.Malloc_pattern_fill_contents)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:malloc_zero_contents=%t\n", proptools.Bool(productVariables.Malloc_zero_contents)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:manifest_package_name_overrides=%s\n", strings.Join(productVariables.ManifestPackageNameOverrides, ",")))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:native_coverage=%t\n", proptools.Bool(productVariables.Native_coverage)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:platform_sdk_version=%d\n", platform_sdk_version))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:safestack=%t\n", proptools.Bool(productVariables.Safestack)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:target_build_variant=%s\n", targetBuildVariant))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:treble_linker_namespaces=%t\n", proptools.Bool(productVariables.Treble_linker_namespaces)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:tidy_checks=%s\n", proptools.String(productVariables.TidyChecks)))
+		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:uml=%t\n", proptools.Bool(productVariables.Uml)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:unbundled_build=%t\n", proptools.Bool(productVariables.Unbundled_build)))
 		result.WriteString(fmt.Sprintf("    --//build/bazel/product_config:unbundled_build_apps=%s\n", strings.Join(productVariables.Unbundled_build_apps, ",")))
+
+		for _, override := range productVariables.CertificateOverrides {
+			parts := strings.SplitN(override, ":", 2)
+			if apexPath, ok := convertedModulePathMap[parts[0]]; ok {
+				if overrideCertPath, ok := convertedModulePathMap[parts[1]]; ok {
+					result.WriteString(fmt.Sprintf("    --%s:%s_certificate_override=%s:%s\n", apexPath, parts[0], overrideCertPath, parts[1]))
+				}
+			}
+		}
+
+		for namespace, namespaceContents := range productVariables.VendorVars {
+			for variable, value := range namespaceContents {
+				key := namespace + "__" + variable
+				_, hasBool := soongConfigDefinitions.BoolVars[key]
+				_, hasString := soongConfigDefinitions.StringVars[key]
+				_, hasValue := soongConfigDefinitions.ValueVars[key]
+				if !hasBool && !hasString && !hasValue {
+					// Not all soong config variables are defined in Android.bp files. For example,
+					// prebuilt_bootclasspath_fragment uses soong config variables in a nonstandard
+					// way, that causes them to be present in the soong.variables file but not
+					// defined in an Android.bp file. There's also nothing stopping you from setting
+					// a variable in make that doesn't exist in soong. We only generate build
+					// settings for the ones that exist in soong, so skip all others.
+					continue
+				}
+				if hasBool && hasString || hasBool && hasValue || hasString && hasValue {
+					panic(fmt.Sprintf("Soong config variable %s:%s appears to be of multiple types. bool? %t, string? %t, value? %t", namespace, variable, hasBool, hasString, hasValue))
+				}
+				if hasBool {
+					// Logic copied from soongConfig.Bool()
+					value = strings.ToLower(value)
+					if value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" {
+						value = "true"
+					} else {
+						value = "false"
+					}
+				}
+				result.WriteString(fmt.Sprintf("    --//build/bazel/product_config/soong_config_variables:%s=%s\n", strings.ToLower(key), value))
+			}
+		}
 	}
 }
 
@@ -225,12 +327,20 @@
 		field := productVarsReflect.Field(i)
 		fieldType := productVarsReflect.Type().Field(i)
 		name := fieldType.Name
-		if name == "BootJars" || name == "ApexBootJars" || name == "VendorVars" ||
-			name == "VendorSnapshotModules" || name == "RecoverySnapshotModules" {
+		if name == "BootJars" || name == "ApexBootJars" || name == "VendorSnapshotModules" ||
+			name == "RecoverySnapshotModules" {
 			// These variables have more complicated types, and we don't need them right now
 			continue
 		}
 		if _, ok := in[name]; ok {
+			if name == "VendorVars" {
+				vendorVars, err := starlark_import.Unmarshal[map[string]map[string]string](in[name])
+				if err != nil {
+					return result, err
+				}
+				field.Set(reflect.ValueOf(vendorVars))
+				continue
+			}
 			switch field.Type().Kind() {
 			case reflect.Bool:
 				val, err := starlark_import.Unmarshal[bool](in[name])
@@ -282,5 +392,9 @@
 		}
 	}
 
+	result.Native_coverage = proptools.BoolPtr(
+		proptools.Bool(result.GcovCoverage) ||
+			proptools.Bool(result.ClangCoverage))
+
 	return result, nil
 }
diff --git a/bp2build/bp2build_product_config_test.go b/bp2build/bp2build_product_config_test.go
index 3dd53ce..02d83b4 100644
--- a/bp2build/bp2build_product_config_test.go
+++ b/bp2build/bp2build_product_config_test.go
@@ -69,6 +69,7 @@
 			t.Error(err)
 			continue
 		}
+		testCase.result.Native_coverage = proptools.BoolPtr(false)
 		if !reflect.DeepEqual(testCase.result, productVariables) {
 			expected, err := json.Marshal(testCase.result)
 			if err != nil {
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 09a9d04..6ca4bb4 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -29,6 +29,7 @@
 	"android/soong/bazel"
 	"android/soong/starlark_fmt"
 	"android/soong/ui/metrics/bp2build_metrics_proto"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/proptools"
@@ -94,16 +95,16 @@
 // statements (use LoadStatements for that), since the targets are usually not
 // adjacent to the load statements at the top of the BUILD file.
 func (targets BazelTargets) String() string {
-	var res string
+	var res strings.Builder
 	for i, target := range targets {
 		if target.ruleClass != "package" {
-			res += target.content
+			res.WriteString(target.content)
 		}
 		if i != len(targets)-1 {
-			res += "\n\n"
+			res.WriteString("\n\n")
 		}
 	}
-	return res
+	return res.String()
 }
 
 // LoadStatements return the string representation of the sorted and deduplicated
@@ -653,6 +654,8 @@
 }
 
 func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (conversionResults, []error) {
+	ctx.Context().BeginEvent("GenerateBazelTargets")
+	defer ctx.Context().EndEvent("GenerateBazelTargets")
 	buildFileToTargets := make(map[string]BazelTargets)
 
 	// Simple metrics tracking for bp2build
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index e127fd5..8ee0439 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -640,7 +640,10 @@
 }`,
 			ExpectedBazelTargets: []string{
 				MakeBazelTargetNoRestrictions("custom", "foo", AttrNameToString{
-					"target_compatible_with": `["//build/bazel/product_variables:unbundled_build"]`,
+					"target_compatible_with": `select({
+        "//build/bazel/product_config/config_settings:unbundled_build": [],
+        "//conditions:default": ["@platforms//:incompatible"],
+    })`,
 				}),
 			},
 		},
@@ -1946,3 +1949,46 @@
 	actual, _ := prettyPrintAttribute(lla, 0)
 	android.AssertStringEquals(t, "Print the common value if all keys in an axis have the same value", `[":libfoo.impl"]`, actual)
 }
+
+// If CommonAttributes.Dir is set, the bazel target should be created in that dir
+func TestCreateBazelTargetInDifferentDir(t *testing.T) {
+	t.Parallel()
+	bp := `
+	custom {
+		name: "foo",
+		dir: "subdir",
+	}
+	`
+	registerCustomModule := func(ctx android.RegistrationContext) {
+		ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+	}
+	// Check that foo is not created in root dir
+	RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+		Description: "foo is not created in root dir because it sets dir explicitly",
+		Blueprint:   bp,
+		Filesystem: map[string]string{
+			"subdir/Android.bp": "",
+		},
+		ExpectedBazelTargets: []string{},
+	})
+	// Check that foo is created in `subdir`
+	RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+		Description: "foo is created in `subdir` because it sets dir explicitly",
+		Blueprint:   bp,
+		Filesystem: map[string]string{
+			"subdir/Android.bp": "",
+		},
+		Dir: "subdir",
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("custom", "foo", AttrNameToString{}),
+		},
+	})
+	// Check that we cannot create target in different dir if it is does not an Android.bp
+	RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+		Description: "foo cannot be created in `subdir` because it does not contain an Android.bp file",
+		Blueprint:   bp,
+		Dir:         "subdir",
+		ExpectedErr: fmt.Errorf("Cannot use ca.Dir to create a BazelTarget in dir: subdir since it does not contain an Android.bp file"),
+	})
+
+}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index fa1bf8a..402d4b0 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -94,6 +94,7 @@
         # bazel_module end
         "bool_prop": attr.bool(),
         "bool_ptr_prop": attr.bool(),
+        "dir": attr.string(),
         "embedded_prop": attr.string(),
         "int64_ptr_prop": attr.int(),
         # nested_props start
@@ -126,6 +127,7 @@
         "arch_paths_exclude": attr.string_list(),
         "bool_prop": attr.bool(),
         "bool_ptr_prop": attr.bool(),
+        "dir": attr.string(),
         "embedded_prop": attr.string(),
         "int64_ptr_prop": attr.int(),
         # nested_props start
@@ -158,6 +160,7 @@
         "arch_paths_exclude": attr.string_list(),
         "bool_prop": attr.bool(),
         "bool_ptr_prop": attr.bool(),
+        "dir": attr.string(),
         "embedded_prop": attr.string(),
         "int64_ptr_prop": attr.int(),
         # nested_props start
@@ -199,7 +202,7 @@
 			content: "irrelevant",
 		},
 	}
-	files := CreateBazelFiles(android.NullConfig("out", "out/soong"), ruleShims, make(map[string]BazelTargets), QueryView)
+	files := CreateBazelFiles(ruleShims, make(map[string]BazelTargets), QueryView)
 
 	var actualSoongModuleBzl BazelFile
 	for _, f := range files {
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 490cd91..e5ae73e 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1260,14 +1260,14 @@
         "//build/bazel/platforms/arch:arm": [],
         "//conditions:default": [":arm_static_lib_excludes_bp2build_cc_library_static"],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte": [],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte": [],
         "//conditions:default": [":malloc_not_svelte_static_lib_excludes_bp2build_cc_library_static"],
     })`,
 			"implementation_dynamic_deps": `select({
         "//build/bazel/platforms/arch:arm": [],
         "//conditions:default": [":arm_shared_lib_excludes"],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_shared_lib"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte": [":malloc_not_svelte_shared_lib"],
         "//conditions:default": [],
     })`,
 			"srcs_c": `["common.c"]`,
@@ -1275,7 +1275,7 @@
         "//build/bazel/platforms/arch:arm": [],
         "//conditions:default": [":arm_whole_static_lib_excludes_bp2build_cc_library_static"],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib_bp2build_cc_library_static"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib_bp2build_cc_library_static"],
         "//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes_bp2build_cc_library_static"],
     })`,
 		}),
@@ -1307,7 +1307,7 @@
 `,
 		ExpectedBazelTargets: makeCcLibraryTargets("foo_static", AttrNameToString{
 			"implementation_deps": `select({
-        "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_header_lib"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte": [":malloc_not_svelte_header_lib"],
         "//conditions:default": [],
     })`,
 			"srcs_c":                 `["common.c"]`,
@@ -2434,12 +2434,18 @@
 			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
-			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
+			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 				"tags": `[
         "apex_available=//apex_available:anyapex",
         "manual",
     ]`,
+			}), MakeBazelTargetNoRestrictions("alias", "a_fg_proto_bp2build_converted", AttrNameToString{
+				"actual": `"//.:a_fg_proto_proto"`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
 			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 			}),
@@ -2476,12 +2482,18 @@
 			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
-			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
+			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 				"tags": `[
         "apex_available=//apex_available:anyapex",
         "manual",
     ]`,
+			}), MakeBazelTargetNoRestrictions("alias", "a_fg_proto_bp2build_converted", AttrNameToString{
+				"actual": `"//.:a_fg_proto_proto"`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
 			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 			}),
@@ -4631,7 +4643,7 @@
         "-Wextra",
         "-DDEBUG_ONLY_CODE=0",
     ] + select({
-        "//build/bazel/product_variables:eng": [
+        "//build/bazel/product_config/config_settings:eng": [
             "-UDEBUG_ONLY_CODE",
             "-DDEBUG_ONLY_CODE=1",
         ],
@@ -4903,3 +4915,138 @@
 		},
 	})
 }
+
+// Bazel enforces that proto_library and the .proto file are in the same bazel package
+func TestGenerateProtoLibraryInSamePackage(t *testing.T) {
+	tc := Bp2buildTestCase{
+		Description:                "cc_library depends on .proto files from multiple packages",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: `
+cc_library_static {
+	name: "foo",
+	srcs: [
+	   "foo.proto",
+	   "bar/bar.proto", // Different package because there is a bar/Android.bp
+	   "baz/subbaz/baz.proto", // Different package because there is baz/subbaz/Android.bp
+	],
+	proto: {
+		canonical_path_from_root: true,
+	}
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+		Filesystem: map[string]string{
+			"bar/Android.bp":        "",
+			"baz/subbaz/Android.bp": "",
+		},
+	}
+
+	// We will run the test 3 times and check in the root, bar and baz/subbaz directories
+	// Root dir
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+			"local_includes":                    `["."]`,
+			"deps":                              `[":libprotobuf-cpp-lite"]`,
+			"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+		}),
+		MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			"srcs": `["foo.proto"]`,
+		}),
+		MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			"deps": `[
+        ":foo_proto",
+        "//bar:foo_proto",
+        "//baz/subbaz:foo_proto",
+    ]`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+
+	// bar dir
+	tc.Dir = "bar"
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			"srcs": `["//bar:bar.proto"]`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+
+	// baz/subbaz dir
+	tc.Dir = "baz/subbaz"
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			"srcs": `["//baz/subbaz:baz.proto"]`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+}
+
+// Bazel enforces that proto_library and the .proto file are in the same bazel package
+func TestGenerateProtoLibraryInSamePackageNotCanonicalFromRoot(t *testing.T) {
+	tc := Bp2buildTestCase{
+		Description:                "cc_library depends on .proto files from multiple packages",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: `
+cc_library_static {
+	name: "foo",
+	srcs: [
+	   "foo.proto",
+	   "bar/bar.proto", // Different package because there is a bar/Android.bp
+	   "baz/subbaz/baz.proto", // Different package because there is baz/subbaz/Android.bp
+	],
+	proto: {
+		canonical_path_from_root: false,
+	}
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+		Filesystem: map[string]string{
+			"bar/Android.bp":        "",
+			"baz/subbaz/Android.bp": "",
+		},
+	}
+
+	// We will run the test 3 times and check in the root, bar and baz/subbaz directories
+	// Root dir
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+			"local_includes":                    `["."]`,
+			"deps":                              `[":libprotobuf-cpp-lite"]`,
+			"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+		}),
+		MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			"srcs":                `["foo.proto"]`,
+			"strip_import_prefix": `""`,
+		}),
+		MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			"deps": `[
+        ":foo_proto",
+        "//bar:foo_proto",
+        "//baz/subbaz:foo_proto",
+    ]`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+
+	// bar dir
+	tc.Dir = "bar"
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			"srcs":                `["//bar:bar.proto"]`,
+			"strip_import_prefix": `""`,
+			"import_prefix":       `"bar"`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+
+	// baz/subbaz dir
+	tc.Dir = "baz/subbaz"
+	tc.ExpectedBazelTargets = []string{
+		MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			"srcs":                `["//baz/subbaz:baz.proto"]`,
+			"strip_import_prefix": `""`,
+			"import_prefix":       `"baz/subbaz"`,
+		}),
+	}
+	runCcLibraryTestCase(t, tc)
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 03e9cd0..26baf89 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1188,13 +1188,13 @@
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"copts": `select({
-        "//build/bazel/product_variables:binder32bit": ["-Wbinder32bit"],
+        "//build/bazel/product_config/config_settings:binder32bit": ["-Wbinder32bit"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte": ["-Wmalloc_not_svelte"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:malloc_zero_contents": ["-Wmalloc_zero_contents"],
+        "//build/bazel/product_config/config_settings:malloc_zero_contents": ["-Wmalloc_zero_contents"],
         "//conditions:default": [],
     })`,
 				"srcs_c": `["common.c"]`,
@@ -1248,19 +1248,19 @@
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"copts": `select({
-        "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte": ["-Wmalloc_not_svelte"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte-android": ["-Wandroid_malloc_not_svelte"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte-android": ["-Wandroid_malloc_not_svelte"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte-arm": ["-Wlib32_malloc_not_svelte"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte-arm": ["-Wlib32_malloc_not_svelte"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte-arm64": ["-Warm64_malloc_not_svelte"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte-arm64": ["-Warm64_malloc_not_svelte"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:malloc_not_svelte-x86": ["-Wlib32_malloc_not_svelte"],
+        "//build/bazel/product_config/config_settings:malloc_not_svelte-x86": ["-Wlib32_malloc_not_svelte"],
         "//conditions:default": [],
     })`,
 				"srcs_c": `["common.c"]`,
@@ -1287,7 +1287,7 @@
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"asflags": `select({
-        "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
+        "//build/bazel/product_config/config_settings:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
         "//conditions:default": [],
     })`,
 				"srcs_as": `["common.S"]`,
@@ -2247,3 +2247,38 @@
     ]`,
 			})}})
 }
+
+func TestCcLibraryWithProtoInGeneratedSrcs(t *testing.T) {
+	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library with a .proto file generated from a genrule",
+		ModuleTypeUnderTest:        "cc_library_static",
+		ModuleTypeUnderTestFactory: cc.LibraryStaticFactory,
+		Blueprint: soongCcLibraryPreamble + `
+cc_library_static {
+	name: "mylib",
+	generated_sources: ["myprotogen"],
+}
+genrule {
+	name: "myprotogen",
+	out: ["myproto.proto"],
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_static", "mylib", AttrNameToString{
+				"local_includes":                    `["."]`,
+				"deps":                              `[":libprotobuf-cpp-lite"]`,
+				"implementation_whole_archive_deps": `[":mylib_cc_proto_lite"]`,
+			}),
+			MakeBazelTarget("cc_lite_proto_library", "mylib_cc_proto_lite", AttrNameToString{
+				"deps": `[":mylib_proto"]`,
+			}),
+			MakeBazelTarget("proto_library", "mylib_proto", AttrNameToString{
+				"srcs": `[":myprotogen"]`,
+			}),
+			MakeBazelTargetNoRestrictions("genrule", "myprotogen", AttrNameToString{
+				"cmd":  `""`,
+				"outs": `["myproto.proto"]`,
+			}),
+		},
+	})
+}
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index eab84e1..ecfcb5a 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -200,7 +200,7 @@
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"asflags": `select({
-        "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
+        "//build/bazel/product_config/config_settings:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
         "//conditions:default": [],
     })`,
 				"copts":               `["-fno-addrsig"]`,
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index d5f2386..f280924 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -1,7 +1,6 @@
 package bp2build
 
 import (
-	"android/soong/starlark_fmt"
 	"encoding/json"
 	"fmt"
 	"reflect"
@@ -9,11 +8,11 @@
 	"strings"
 
 	"android/soong/android"
+	"android/soong/apex"
 	"android/soong/cc"
 	cc_config "android/soong/cc/config"
 	java_config "android/soong/java/config"
-
-	"android/soong/apex"
+	"android/soong/starlark_fmt"
 
 	"github.com/google/blueprint/proptools"
 )
@@ -105,12 +104,7 @@
 `, starlark_fmt.PrintBool(cfg.PlatformSdkFinal()), platformSdkVersion, cfg.PlatformSdkCodename(), strings.Join(platformVersionActiveCodenames, ", "))
 }
 
-func CreateBazelFiles(
-	cfg android.Config,
-	ruleShims map[string]RuleShim,
-	buildToTargets map[string]BazelTargets,
-	mode CodegenMode) []BazelFile {
-
+func CreateBazelFiles(ruleShims map[string]RuleShim, buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
 	var files []BazelFile
 
 	if mode == QueryView {
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index 00ffd79..15284ce 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -27,8 +27,7 @@
 }
 
 func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) {
-	files := CreateBazelFiles(android.NullConfig("out", "out/soong"),
-		map[string]RuleShim{}, map[string]BazelTargets{}, QueryView)
+	files := CreateBazelFiles(map[string]RuleShim{}, map[string]BazelTargets{}, QueryView)
 	expectedFilePaths := []bazelFilepath{
 		{
 			dir:      "",
diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go
index 7ce559d..cb2e207 100644
--- a/bp2build/filegroup_conversion_test.go
+++ b/bp2build/filegroup_conversion_test.go
@@ -137,7 +137,7 @@
 		path: "proto",
 }`,
 		ExpectedBazelTargets: []string{
-			MakeBazelTargetNoRestrictions("proto_library", "foo_bp2build_converted", AttrNameToString{
+			MakeBazelTargetNoRestrictions("proto_library", "foo_proto", AttrNameToString{
 				"srcs":                `["proto/foo.proto"]`,
 				"strip_import_prefix": `"proto"`,
 				"tags": `[
@@ -145,6 +145,13 @@
         "manual",
     ]`,
 			}),
+			MakeBazelTargetNoRestrictions("alias", "foo_bp2build_converted", AttrNameToString{
+				"actual": `"//.:foo_proto"`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
+			}),
 			MakeBazelTargetNoRestrictions("filegroup", "foo", AttrNameToString{
 				"srcs": `["proto/foo.proto"]`}),
 		}})
@@ -170,3 +177,27 @@
     ]`}),
 		}})
 }
+
+func TestFilegroupWithProtoInDifferentPackage(t *testing.T) {
+	runFilegroupTestCase(t, Bp2buildTestCase{
+		Description: "filegroup with .proto in different package",
+		Filesystem: map[string]string{
+			"subdir/Android.bp": "",
+		},
+		Blueprint: `
+filegroup {
+    name: "foo",
+    srcs: ["subdir/foo.proto"],
+}`,
+		Dir: "subdir", // check in subdir
+		ExpectedBazelTargets: []string{
+			MakeBazelTargetNoRestrictions("proto_library", "foo_proto", AttrNameToString{
+				"srcs":                `["//subdir:foo.proto"]`,
+				"import_prefix":       `"subdir"`,
+				"strip_import_prefix": `""`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`}),
+		}})
+}
diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go
index aa0a5b7..5b2d609 100644
--- a/bp2build/prebuilt_etc_conversion_test.go
+++ b/bp2build/prebuilt_etc_conversion_test.go
@@ -149,7 +149,7 @@
 			MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
 				"filename": `"tz_version"`,
 				"src": `select({
-        "//build/bazel/product_variables:native_coverage": "src1",
+        "//build/bazel/product_config/config_settings:native_coverage": "src1",
         "//conditions:default": "version/tz_version",
     })`,
 				"dir": `"etc"`,
@@ -318,7 +318,7 @@
 				"dir":      `"etc"`,
 				"src": `select({
         "//build/bazel/platforms/arch:arm": "armSrc",
-        "//build/bazel/product_variables:native_coverage-arm": "nativeCoverageArmSrc",
+        "//build/bazel/product_config/config_settings:native_coverage-arm": "nativeCoverageArmSrc",
         "//conditions:default": None,
     })`,
 			})}})
diff --git a/bp2build/soong_config_module_type_conversion_test.go b/bp2build/soong_config_module_type_conversion_test.go
index 143597d..8302ce8 100644
--- a/bp2build/soong_config_module_type_conversion_test.go
+++ b/bp2build/soong_config_module_type_conversion_test.go
@@ -91,7 +91,7 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "foo",
     copts = select({
-        "//build/bazel/product_variables:acme__feature1": ["-DFEATURE1"],
+        "//build/bazel/product_config/config_settings:acme__feature1": ["-DFEATURE1"],
         "//conditions:default": ["-DDEFAULT1"],
     }),
     local_includes = ["."],
@@ -140,7 +140,7 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "foo",
     copts = select({
-        "//build/bazel/product_variables:acme__feature1": ["-DFEATURE1"],
+        "//build/bazel/product_config/config_settings:acme__feature1": ["-DFEATURE1"],
         "//conditions:default": ["-DDEFAULT1"],
     }),
     local_includes = ["."],
@@ -191,9 +191,9 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "foo",
     copts = select({
-        "//build/bazel/product_variables:acme__board__soc_a": ["-DSOC_A"],
-        "//build/bazel/product_variables:acme__board__soc_b": ["-DSOC_B"],
-        "//build/bazel/product_variables:acme__board__soc_c": [],
+        "//build/bazel/product_config/config_settings:acme__board__soc_a": ["-DSOC_A"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_b": ["-DSOC_B"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_c": [],
         "//conditions:default": ["-DSOC_DEFAULT"],
     }),
     local_includes = ["."],
@@ -240,7 +240,7 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "foo",
     copts = select({
-        "//build/bazel/product_variables:acme__feature1": ["-DFEATURE1"],
+        "//build/bazel/product_config/config_settings:acme__feature1": ["-DFEATURE1"],
         "//conditions:default": ["-DDEFAULT1"],
     }),
     local_includes = ["."],
@@ -310,15 +310,15 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "foo",
     copts = select({
-        "//build/bazel/product_variables:acme__board__soc_a": ["-DSOC_A"],
-        "//build/bazel/product_variables:acme__board__soc_b": ["-DSOC_B"],
-        "//build/bazel/product_variables:acme__board__soc_c": [],
+        "//build/bazel/product_config/config_settings:acme__board__soc_a": ["-DSOC_A"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_b": ["-DSOC_B"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_c": [],
         "//conditions:default": ["-DSOC_DEFAULT"],
     }) + select({
-        "//build/bazel/product_variables:acme__feature1": ["-DFEATURE1"],
+        "//build/bazel/product_config/config_settings:acme__feature1": ["-DFEATURE1"],
         "//conditions:default": ["-DDEFAULT1"],
     }) + select({
-        "//build/bazel/product_variables:acme__feature2": ["-DFEATURE2"],
+        "//build/bazel/product_config/config_settings:acme__feature2": ["-DFEATURE2"],
         "//conditions:default": ["-DDEFAULT2"],
     }),
     local_includes = ["."],
@@ -380,15 +380,15 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "foo",
     copts = select({
-        "//build/bazel/product_variables:acme__board__soc_a": ["-DSOC_A"],
-        "//build/bazel/product_variables:acme__board__soc_b": ["-DSOC_B"],
-        "//build/bazel/product_variables:acme__board__soc_c": [],
+        "//build/bazel/product_config/config_settings:acme__board__soc_a": ["-DSOC_A"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_b": ["-DSOC_B"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_c": [],
         "//conditions:default": ["-DSOC_DEFAULT"],
     }),
     implementation_deps = select({
-        "//build/bazel/product_variables:acme__board__soc_a": ["//foo/bar:soc_a_dep"],
-        "//build/bazel/product_variables:acme__board__soc_b": ["//foo/bar:soc_b_dep"],
-        "//build/bazel/product_variables:acme__board__soc_c": [],
+        "//build/bazel/product_config/config_settings:acme__board__soc_a": ["//foo/bar:soc_a_dep"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_b": ["//foo/bar:soc_b_dep"],
+        "//build/bazel/product_config/config_settings:acme__board__soc_c": [],
         "//conditions:default": ["//foo/bar:soc_default_static_dep"],
     }),
     local_includes = ["."],
@@ -446,7 +446,7 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "lib",
     copts = select({
-        "//build/bazel/product_variables:vendor_foo__feature": [
+        "//build/bazel/product_config/config_settings:vendor_foo__feature": [
             "-cflag_feature_2",
             "-cflag_feature_1",
         ],
@@ -527,11 +527,11 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "lib",
     asflags = select({
-        "//build/bazel/product_variables:acme__feature": ["-asflag_bar"],
+        "//build/bazel/product_config/config_settings:acme__feature": ["-asflag_bar"],
         "//conditions:default": ["-asflag_default_bar"],
     }),
     copts = select({
-        "//build/bazel/product_variables:acme__feature": [
+        "//build/bazel/product_config/config_settings:acme__feature": [
             "-cflag_foo",
             "-cflag_bar",
         ],
@@ -546,11 +546,11 @@
 			`cc_library_static(
     name = "lib2",
     asflags = select({
-        "//build/bazel/product_variables:acme__feature": ["-asflag_bar"],
+        "//build/bazel/product_config/config_settings:acme__feature": ["-asflag_bar"],
         "//conditions:default": ["-asflag_default_bar"],
     }),
     copts = select({
-        "//build/bazel/product_variables:acme__feature": [
+        "//build/bazel/product_config/config_settings:acme__feature": [
             "-cflag_bar",
             "-cflag_foo",
         ],
@@ -643,13 +643,13 @@
 		ExpectedBazelTargets: []string{`cc_library_static(
     name = "lib",
     copts = select({
-        "//build/bazel/product_variables:vendor_bar__feature": ["-DVENDOR_BAR_FEATURE"],
+        "//build/bazel/product_config/config_settings:vendor_bar__feature": ["-DVENDOR_BAR_FEATURE"],
         "//conditions:default": ["-DVENDOR_BAR_DEFAULT"],
     }) + select({
-        "//build/bazel/product_variables:vendor_foo__feature": ["-DVENDOR_FOO_FEATURE"],
+        "//build/bazel/product_config/config_settings:vendor_foo__feature": ["-DVENDOR_FOO_FEATURE"],
         "//conditions:default": ["-DVENDOR_FOO_DEFAULT"],
     }) + select({
-        "//build/bazel/product_variables:vendor_qux__feature": ["-DVENDOR_QUX_FEATURE"],
+        "//build/bazel/product_config/config_settings:vendor_qux__feature": ["-DVENDOR_QUX_FEATURE"],
         "//conditions:default": ["-DVENDOR_QUX_DEFAULT"],
     }),
     local_includes = ["."],
@@ -697,7 +697,7 @@
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("custom", "foo", AttrNameToString{
 				"string_literal_prop": `select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": "29",
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": "29",
         "//conditions:default": "30",
     })`,
 			}),
@@ -779,7 +779,7 @@
 		ExpectedBazelTargets: []string{`cc_binary(
     name = "library_linking_strategy_sample_binary",
     dynamic_deps = select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [],
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": [],
         "//conditions:default": [
             "//foo/bar:lib_b",
             "//foo/bar:lib_a",
@@ -868,7 +868,7 @@
 		ExpectedBazelTargets: []string{
 			MakeBazelTargetNoRestrictions("cc_binary", "library_linking_strategy_sample_binary", AttrNameToString{
 				"dynamic_deps": `select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [],
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": [],
         "//conditions:default": [
             "//foo/bar:lib_b",
             "//foo/bar:lib_c",
@@ -877,7 +877,7 @@
 			}),
 			MakeBazelTargetNoRestrictions("cc_binary", "library_linking_strategy_sample_binary_with_excludes", AttrNameToString{
 				"dynamic_deps": `select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [],
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": [],
         "//conditions:default": ["//foo/bar:lib_b"],
     })`,
 			}),
@@ -965,14 +965,14 @@
 		ExpectedBazelTargets: []string{`cc_binary(
     name = "library_linking_strategy_sample_binary",
     deps = select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": [
             "//foo/bar:lib_b_bp2build_cc_library_static",
             "//foo/bar:lib_a_bp2build_cc_library_static",
         ],
         "//conditions:default": [],
     }),
     dynamic_deps = select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [],
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": [],
         "//conditions:default": [
             "//foo/bar:lib_b",
             "//foo/bar:lib_a",
@@ -1046,14 +1046,14 @@
 		ExpectedBazelTargets: []string{`cc_binary(
     name = "library_linking_strategy_sample_binary",
     deps = select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": [
             "//foo/bar:lib_a_bp2build_cc_library_static",
             "//foo/bar:lib_b_bp2build_cc_library_static",
         ],
         "//conditions:default": [],
     }),
     dynamic_deps = select({
-        "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [],
+        "//build/bazel/product_config/config_settings:android__library_linking_strategy__prefer_static": [],
         "//conditions:default": [
             "//foo/bar:lib_a",
             "//foo/bar:lib_b",
@@ -1134,13 +1134,13 @@
 		ExpectedBazelTargets: []string{`cc_binary(
     name = "alphabet_binary",
     deps = select({
-        "//build/bazel/product_variables:android__alphabet__a": [],
-        "//build/bazel/product_variables:android__alphabet__b": [],
+        "//build/bazel/product_config/config_settings:android__alphabet__a": [],
+        "//build/bazel/product_config/config_settings:android__alphabet__b": [],
         "//conditions:default": ["//foo/bar:lib_default_bp2build_cc_library_static"],
     }),
     dynamic_deps = select({
-        "//build/bazel/product_variables:android__alphabet__a": ["//foo/bar:lib_a"],
-        "//build/bazel/product_variables:android__alphabet__b": ["//foo/bar:lib_b"],
+        "//build/bazel/product_config/config_settings:android__alphabet__a": ["//foo/bar:lib_a"],
+        "//build/bazel/product_config/config_settings:android__alphabet__b": ["//foo/bar:lib_b"],
         "//conditions:default": [],
     }),
     local_includes = ["."],
@@ -1199,7 +1199,7 @@
     name = "alphabet_binary",
     local_includes = ["."],
     srcs = ["main.cc"],
-    target_compatible_with = ["//build/bazel/product_variables:alphabet_module__special_build"] + select({
+    target_compatible_with = select({
         "//build/bazel/platforms/os_arch:android_x86_64": ["@platforms//:incompatible"],
         "//build/bazel/platforms/os_arch:darwin_arm64": ["@platforms//:incompatible"],
         "//build/bazel/platforms/os_arch:darwin_x86_64": ["@platforms//:incompatible"],
@@ -1208,6 +1208,9 @@
         "//build/bazel/platforms/os_arch:linux_musl_x86_64": ["@platforms//:incompatible"],
         "//build/bazel/platforms/os_arch:windows_x86_64": ["@platforms//:incompatible"],
         "//conditions:default": [],
+    }) + select({
+        "//build/bazel/product_config/config_settings:alphabet_module__special_build": [],
+        "//conditions:default": ["@platforms//:incompatible"],
     }),
 )`}})
 }
@@ -1240,6 +1243,24 @@
     srcs: ["main.cc"],
     defaults: ["alphabet_sample_cc_defaults"],
     enabled: false,
+}
+
+alphabet_cc_defaults {
+    name: "alphabet_sample_cc_defaults_conditions_default",
+    soong_config_variables: {
+        special_build: {
+		conditions_default: {
+			enabled: false,
+		},
+	},
+    },
+}
+
+cc_binary {
+    name: "alphabet_binary_conditions_default",
+    srcs: ["main.cc"],
+    defaults: ["alphabet_sample_cc_defaults_conditions_default"],
+    enabled: false,
 }`
 
 	runSoongConfigModuleTypeTest(t, Bp2buildTestCase{
@@ -1252,8 +1273,17 @@
     name = "alphabet_binary",
     local_includes = ["."],
     srcs = ["main.cc"],
-    target_compatible_with = ["//build/bazel/product_variables:alphabet_module__special_build"],
-)`}})
+    target_compatible_with = select({
+        "//build/bazel/product_config/config_settings:alphabet_module__special_build": [],
+        "//conditions:default": ["@platforms//:incompatible"],
+    }),
+)`,
+			MakeBazelTarget("cc_binary", "alphabet_binary_conditions_default", AttrNameToString{
+				"local_includes":         `["."]`,
+				"srcs":                   `["main.cc"]`,
+				"target_compatible_with": `["@platforms//:incompatible"]`,
+			}),
+		}})
 }
 
 func TestSoongConfigModuleType_ProductVariableIgnoredIfEnabledByDefault(t *testing.T) {
@@ -1389,16 +1419,16 @@
         "//build/bazel/platforms/os:android": ["-DFOO"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:my_namespace__my_bool_variable__android": ["-DBAR"],
-        "//build/bazel/product_variables:my_namespace__my_bool_variable__conditions_default__android": ["-DBAZ"],
+        "//build/bazel/product_config/config_settings:my_namespace__my_bool_variable__android": ["-DBAR"],
+        "//build/bazel/product_config/config_settings:my_namespace__my_bool_variable__conditions_default__android": ["-DBAZ"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:my_namespace__my_string_variable__value1": ["-DVALUE1_NOT_ANDROID"],
+        "//build/bazel/product_config/config_settings:my_namespace__my_string_variable__value1": ["-DVALUE1_NOT_ANDROID"],
         "//conditions:default": [],
     }) + select({
-        "//build/bazel/product_variables:my_namespace__my_string_variable__conditions_default__android": ["-DSTRING_VAR_CONDITIONS_DEFAULT"],
-        "//build/bazel/product_variables:my_namespace__my_string_variable__value1__android": ["-DVALUE1"],
-        "//build/bazel/product_variables:my_namespace__my_string_variable__value2__android": ["-DVALUE2"],
+        "//build/bazel/product_config/config_settings:my_namespace__my_string_variable__conditions_default__android": ["-DSTRING_VAR_CONDITIONS_DEFAULT"],
+        "//build/bazel/product_config/config_settings:my_namespace__my_string_variable__value1__android": ["-DVALUE1"],
+        "//build/bazel/product_config/config_settings:my_namespace__my_string_variable__value2__android": ["-DVALUE2"],
         "//conditions:default": [],
     }),
     local_includes = ["."],
@@ -1514,3 +1544,58 @@
 		runSoongConfigModuleTypeTest(t, bp2buildTestCase)
 	}
 }
+
+func TestNoPanicIfEnabledIsNotUsed(t *testing.T) {
+	bp := `
+soong_config_string_variable {
+	name: "my_string_variable",
+	values: ["val1", "val2"],
+}
+soong_config_module_type {
+	name: "special_cc_defaults",
+	module_type: "cc_defaults",
+	config_namespace: "my_namespace",
+	variables: ["my_string_variable"],
+	properties: [
+		"cflags",
+		"enabled",
+	],
+}
+special_cc_defaults {
+	name: "my_special_cc_defaults",
+	soong_config_variables: {
+		my_string_variable: {
+			val1: {
+				cflags: ["-DFOO"],
+			},
+			val2: {
+				cflags: ["-DBAR"],
+			},
+		},
+	},
+}
+cc_binary {
+	name: "my_binary",
+	enabled: false,
+	defaults: ["my_special_cc_defaults"],
+}
+`
+	tc := Bp2buildTestCase{
+		Description:                "Soong config vars is not used to set `enabled` property",
+		ModuleTypeUnderTest:        "cc_binary",
+		ModuleTypeUnderTestFactory: cc.BinaryFactory,
+		Blueprint:                  bp,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_binary", "my_binary", AttrNameToString{
+				"copts": `select({
+        "//build/bazel/product_config/config_settings:my_namespace__my_string_variable__val1": ["-DFOO"],
+        "//build/bazel/product_config/config_settings:my_namespace__my_string_variable__val2": ["-DBAR"],
+        "//conditions:default": [],
+    })`,
+				"local_includes":         `["."]`,
+				"target_compatible_with": `["@platforms//:incompatible"]`,
+			}),
+		},
+	}
+	runSoongConfigModuleTypeTest(t, tc)
+}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 140b214..18ae82d 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -336,6 +336,8 @@
 	Api *string // File describing the APIs of this module
 
 	Test_config_setting *bool // Used to test generation of config_setting targets
+
+	Dir *string // Dir in which the Bazel Target will be created
 }
 
 type customModule struct {
@@ -461,6 +463,10 @@
 	Api                 bazel.LabelAttribute
 }
 
+func (m *customModule) dir() *string {
+	return m.props.Dir
+}
+
 func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
 	if p := m.props.One_to_many_prop; p != nil && *p {
 		customBp2buildOneToMany(ctx, m)
@@ -508,7 +514,7 @@
 		Rule_class: "custom",
 	}
 
-	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name(), Dir: m.dir()}, attrs)
 
 	if proptools.Bool(m.props.Test_config_setting) {
 		m.createConfigSetting(ctx)
diff --git a/cc/Android.bp b/cc/Android.bp
index e88ea03..c32d854 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -37,6 +37,7 @@
         "linkable.go",
         "lto.go",
         "makevars.go",
+        "orderfile.go",
         "pgo.go",
         "prebuilt.go",
         "proto.go",
@@ -104,6 +105,7 @@
         "lto_test.go",
         "ndk_test.go",
         "object_test.go",
+        "orderfile_test.go",
         "prebuilt_test.go",
         "proto_test.go",
         "sanitize_test.go",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 9e485d6..9d90a5b 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -48,6 +48,8 @@
 
 	genrulePartition = "genrule"
 
+	protoFromGenPartition = "proto_gen"
+
 	hdrPartition = "hdr"
 
 	stubsSuffix = "_stub_libs_current"
@@ -126,6 +128,41 @@
 	}
 }
 
+// Returns an unchanged label and a bool indicating whether the dep is a genrule that produces .proto files
+func protoFromGenPartitionMapper(pathCtx android.BazelConversionContext) bazel.LabelMapper {
+	return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
+		mod, exists := ctx.ModuleFromName(label.OriginalModuleName)
+		if !exists {
+			return label.Label, false
+		}
+		gen, isGen := mod.(*genrule.Module)
+		if !isGen {
+			return label.Label, false
+		}
+		if containsProto(ctx, gen.RawOutputFiles(pathCtx)) {
+			// Return unmodified label + true
+			// True will ensure that this module gets dropped from `srcs` of the generated cc_* target. `srcs` is reserved for .cpp files
+			return label.Label, true
+		}
+		return label.Label, false
+	}
+}
+
+// Returns true if srcs contains only .proto files
+// Raises an exception if there is a combination of .proto and non .proto srcs
+func containsProto(ctx bazel.OtherModuleContext, srcs []string) bool {
+	onlyProtos := false
+	for _, src := range srcs {
+		if strings.HasSuffix(src, ".proto") {
+			onlyProtos = true
+		} else if onlyProtos {
+			// This is not a proto file, and we have encountered a .proto file previously
+			ctx.ModuleErrorf("TOOD: Add bp2build support combination of .proto and non .proto files in outs of genrule")
+		}
+	}
+	return onlyProtos
+}
+
 // groupSrcsByExtension partitions `srcs` into groups based on file extension.
 func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
 	// Convert filegroup dependencies into extension-specific filegroups filtered in the filegroup.bzl
@@ -159,10 +196,11 @@
 		// 		contains .l or .ll files we will need to find a way to add a
 		// 		LabelMapper for these that identifies these filegroups and
 		//		converts them appropriately
-		lSrcPartition:       bazel.LabelPartition{Extensions: []string{".l"}},
-		llSrcPartition:      bazel.LabelPartition{Extensions: []string{".ll"}},
-		rScriptSrcPartition: bazel.LabelPartition{Extensions: []string{".fs", ".rscript"}},
-		xsdSrcPartition:     bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(xsdConfigCppTarget)},
+		lSrcPartition:         bazel.LabelPartition{Extensions: []string{".l"}},
+		llSrcPartition:        bazel.LabelPartition{Extensions: []string{".ll"}},
+		rScriptSrcPartition:   bazel.LabelPartition{Extensions: []string{".fs", ".rscript"}},
+		xsdSrcPartition:       bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(xsdConfigCppTarget)},
+		protoFromGenPartition: bazel.LabelPartition{LabelMapper: protoFromGenPartitionMapper(ctx)},
 		// C++ is the "catch-all" group, and comprises generated sources because we don't
 		// know the language of these sources until the genrule is executed.
 		cppSrcPartition:     bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
@@ -594,6 +632,7 @@
 	partitionedHdrs := partitionHeaders(ctx, exportHdrs)
 
 	ca.protoSrcs = partitionedSrcs[protoSrcPartition]
+	ca.protoSrcs.Append(partitionedSrcs[protoFromGenPartition])
 	ca.aidlSrcs = partitionedSrcs[aidlSrcPartition]
 
 	for p, lla := range partitionedSrcs {
diff --git a/cc/cc.go b/cc/cc.go
index be67286..3b92696 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -74,6 +74,9 @@
 		ctx.TopDown("afdo_deps", afdoDepsMutator)
 		ctx.BottomUp("afdo", afdoMutator).Parallel()
 
+		ctx.TopDown("orderfile_deps", orderfileDepsMutator)
+		ctx.BottomUp("orderfile", orderfileMutator).Parallel()
+
 		ctx.TopDown("lto_deps", ltoDepsMutator)
 		ctx.BottomUp("lto", ltoMutator).Parallel()
 
@@ -526,6 +529,7 @@
 	getVndkExtendsModuleName() string
 	isAfdoCompile() bool
 	isPgoCompile() bool
+	isOrderfileCompile() bool
 	isCfi() bool
 	isFuzzer() bool
 	isNDKStubLibrary() bool
@@ -885,6 +889,7 @@
 	lto      *lto
 	afdo     *afdo
 	pgo      *pgo
+	orderfile *orderfile
 
 	library libraryInterface
 
@@ -1259,6 +1264,9 @@
 	if c.pgo != nil {
 		c.AddProperties(c.pgo.props()...)
 	}
+	if c.orderfile != nil {
+		c.AddProperties(c.orderfile.props()...)
+	}
 	for _, feature := range c.features {
 		c.AddProperties(feature.props()...)
 	}
@@ -1392,6 +1400,13 @@
 	return false
 }
 
+func (c *Module) isOrderfileCompile() bool {
+	if orderfile := c.orderfile; orderfile != nil {
+		return orderfile.Properties.OrderfileLoad
+	}
+	return false
+}
+
 func (c *Module) isCfi() bool {
 	if sanitize := c.sanitize; sanitize != nil {
 		return Bool(sanitize.Properties.SanitizeMutated.Cfi)
@@ -1697,6 +1712,10 @@
 	return ctx.mod.isPgoCompile()
 }
 
+func (ctx *moduleContextImpl) isOrderfileCompile() bool {
+	return ctx.mod.isOrderfileCompile()
+}
+
 func (ctx *moduleContextImpl) isCfi() bool {
 	return ctx.mod.isCfi()
 }
@@ -1806,6 +1825,7 @@
 	module.lto = &lto{}
 	module.afdo = &afdo{}
 	module.pgo = &pgo{}
+	module.orderfile = &orderfile{}
 	return module
 }
 
@@ -2234,6 +2254,9 @@
 	if c.pgo != nil {
 		flags = c.pgo.flags(ctx, flags)
 	}
+	if c.orderfile != nil {
+		flags = c.orderfile.flags(ctx, flags)
+	}
 	for _, feature := range c.features {
 		flags = feature.flags(ctx, flags)
 	}
@@ -2376,6 +2399,9 @@
 	if c.lto != nil {
 		c.lto.begin(ctx)
 	}
+	if c.orderfile != nil {
+		c.orderfile.begin(ctx)
+	}
 	if c.pgo != nil {
 		c.pgo.begin(ctx)
 	}
@@ -4284,6 +4310,7 @@
 		&LTOProperties{},
 		&AfdoProperties{},
 		&PgoProperties{},
+		&OrderfileProperties{},
 		&android.ProtoProperties{},
 		// RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules.
 		&RustBindgenClangProperties{},
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index ca2e05f..12722a7 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -100,7 +100,15 @@
 		return strings.Join(flags, " ")
 	})
 
-	exportedVars.ExportStringListStaticVariable("Arm64Cflags", arm64Cflags)
+	exportedVars.ExportStringList("Arm64Cflags", arm64Cflags)
+	pctx.VariableFunc("Arm64Cflags", func(ctx android.PackageVarContext) string {
+		flags := arm64Cflags
+		if ctx.Config().PageSizeAgnostic() {
+			flags = append(flags, "-D__BIONIC_NO_PAGE_SIZE_MACRO")
+		}
+		return strings.Join(flags, " ")
+	})
+
 	exportedVars.ExportStringListStaticVariable("Arm64Cppflags", arm64Cppflags)
 
 	exportedVars.ExportVariableReferenceDict("Arm64ArchVariantCflags", arm64ArchVariantCflagsVar)
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index f9b3eac..dd612ce 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -21,7 +21,6 @@
 var VndkMustUseVendorVariantList = []string{
 	"android.hardware.nfc@1.2",
 	"libbinder",
-	"libdumpstateutil",
 	"libcrypto",
 	"libexpat",
 	"libgatekeeper",
diff --git a/cc/lto.go b/cc/lto.go
index 44361db..df9ca0a 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -135,10 +135,14 @@
 			ltoLdFlags = append(ltoLdFlags, cachePolicyFormat+policy)
 		}
 
-		// If the module does not have a profile, be conservative and limit cross TU inline
-		// limit to 5 LLVM IR instructions, to balance binary size increase and performance.
-		if !ctx.Darwin() && !ctx.isPgoCompile() && !ctx.isAfdoCompile() {
-			ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=5")
+		// Reduce the inlining threshold for a better balance of binary size and
+		// performance.
+		if !ctx.Darwin() {
+			if ctx.isPgoCompile() || ctx.isAfdoCompile() {
+				ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=40")
+			} else {
+				ltoLdFlags = append(ltoLdFlags, "-Wl,-plugin-opt,-import-instr-limit=5")
+			}
 		}
 
 		flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlags...)
diff --git a/cc/orderfile.go b/cc/orderfile.go
new file mode 100644
index 0000000..cc1ab29
--- /dev/null
+++ b/cc/orderfile.go
@@ -0,0 +1,257 @@
+// 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.
+//
+// Note: If you want to know how to use orderfile for your binary or shared
+// library, you can go look at the README in toolchains/pgo-profiles/orderfiles
+
+package cc
+
+import (
+	"fmt"
+
+	"android/soong/android"
+)
+
+// Order files are text files containing symbols representing functions names.
+// Linkers (lld) uses order files to layout functions in a specific order.
+// These binaries with ordered symbols will reduce page faults and improve a program's launch time
+// due to the efficient loading of symbols during a program’s cold-start.
+var (
+	// Add flags to ignore warnings about symbols not be found
+	// or not allowed to be ordered
+	orderfileOtherFlags = []string{
+		"-Wl,--no-warn-symbol-ordering",
+	}
+
+	// Add folder projects for orderfiles
+	globalOrderfileProjects = []string{
+		"toolchain/pgo-profiles/orderfiles",
+		"vendor/google_data/pgo_profile/orderfiles",
+	}
+)
+
+var orderfileProjectsConfigKey = android.NewOnceKey("OrderfileProjects")
+
+const orderfileProfileFlag = "-forder-file-instrumentation"
+const orderfileUseFormat = "-Wl,--symbol-ordering-file=%s"
+
+func getOrderfileProjects(config android.DeviceConfig) []string {
+	return config.OnceStringSlice(orderfileProjectsConfigKey, func() []string {
+		return globalOrderfileProjects
+	})
+}
+
+func recordMissingOrderfile(ctx BaseModuleContext, missing string) {
+	getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true)
+}
+
+type OrderfileProperties struct {
+	Orderfile struct {
+		Instrumentation    *bool
+		Order_file_path    *string `android:"arch_variant"`
+		Load_order_file    *bool `android:"arch_variant"`
+		// Additional compiler flags to use when building this module
+		// for orderfile profiling.
+		Cflags []string `android:"arch_variant"`
+	} `android:"arch_variant"`
+
+	ShouldProfileModule 	  bool `blueprint:"mutated"`
+	OrderfileLoad             bool `blueprint:"mutated"`
+	OrderfileInstrLink        bool `blueprint:"mutated"`
+}
+
+type orderfile struct {
+	Properties OrderfileProperties
+}
+
+func (props *OrderfileProperties) shouldInstrument() bool {
+	return Bool(props.Orderfile.Instrumentation)
+}
+
+// ShouldLoadOrderfile returns true if we need to load the order file rather than
+// profile the binary or shared library
+func (props *OrderfileProperties) shouldLoadOrderfile() bool {
+	return Bool(props.Orderfile.Load_order_file) && props.Orderfile.Order_file_path != nil
+}
+
+// orderfileEnabled returns true for binaries and shared libraries
+// if instrument flag is set to true
+func (orderfile *orderfile) orderfileEnabled() bool {
+	return orderfile != nil && orderfile.Properties.shouldInstrument()
+}
+
+// orderfileLinkEnabled returns true for binaries and shared libraries
+// if you should instrument dependencies
+func (orderfile *orderfile) orderfileLinkEnabled() bool {
+	return orderfile != nil && orderfile.Properties.OrderfileInstrLink
+}
+
+func (orderfile *orderfile) props() []interface{} {
+	return []interface{}{&orderfile.Properties}
+}
+
+// Get the path to the order file by checking it is valid and not empty
+func (props *OrderfileProperties) getOrderfile(ctx BaseModuleContext) android.OptionalPath {
+	orderFile := *props.Orderfile.Order_file_path
+
+	// Test if the order file is present in any of the Orderfile projects
+	for _, profileProject := range getOrderfileProjects(ctx.DeviceConfig()) {
+		path := android.ExistentPathForSource(ctx, profileProject, orderFile)
+		if path.Valid() {
+			return path
+		}
+	}
+
+	// Record that this module's order file is absent
+	missing := *props.Orderfile.Order_file_path + ":" + ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
+	recordMissingOrderfile(ctx, missing)
+
+	return android.OptionalPath{}
+}
+
+func (props *OrderfileProperties) addInstrumentationProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
+	flags.Local.CFlags = append(flags.Local.CFlags, props.Orderfile.Cflags...)
+	flags.Local.CFlags = append(flags.Local.CFlags, orderfileProfileFlag)
+	flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm -enable-order-file-instrumentation")
+	flags.Local.LdFlags = append(flags.Local.LdFlags, orderfileProfileFlag)
+	return flags
+}
+
+
+func (props *OrderfileProperties) loadOrderfileFlags(ctx ModuleContext, file string) []string {
+	flags := []string{fmt.Sprintf(orderfileUseFormat, file)}
+	flags = append(flags, orderfileOtherFlags...)
+	return flags
+}
+
+func (props *OrderfileProperties) addLoadFlags(ctx ModuleContext, flags Flags) Flags {
+	orderFile := props.getOrderfile(ctx)
+	orderFilePath := orderFile.Path()
+	loadFlags := props.loadOrderfileFlags(ctx, orderFilePath.String())
+
+	flags.Local.CFlags = append(flags.Local.CFlags, loadFlags...)
+	flags.Local.LdFlags = append(flags.Local.LdFlags, loadFlags...)
+
+	// Update CFlagsDeps and LdFlagsDeps so the module is rebuilt
+	// if orderfile gets updated
+	flags.CFlagsDeps = append(flags.CFlagsDeps, orderFilePath)
+	flags.LdFlagsDeps = append(flags.LdFlagsDeps, orderFilePath)
+	return flags
+}
+
+func (orderfile *orderfile) begin(ctx BaseModuleContext) {
+	// Currently, we are not enabling orderfiles for host
+	if ctx.Host() {
+		return
+	}
+
+	// Currently, we are not enabling orderfiles to begin from static libraries
+	if ctx.static() && !ctx.staticBinary() {
+		return
+	}
+
+	if ctx.DeviceConfig().ClangCoverageEnabled() {
+		return
+	}
+
+	// Checking if orderfile is enabled for this module
+	if !orderfile.orderfileEnabled() {
+		return
+	}
+
+	orderfile.Properties.OrderfileLoad = orderfile.Properties.shouldLoadOrderfile()
+	orderfile.Properties.ShouldProfileModule = !orderfile.Properties.shouldLoadOrderfile()
+	orderfile.Properties.OrderfileInstrLink = orderfile.orderfileEnabled() && !orderfile.Properties.shouldLoadOrderfile()
+}
+
+func (orderfile *orderfile) flags(ctx ModuleContext, flags Flags) Flags {
+	props := orderfile.Properties
+	// Add flags to load the orderfile using the path in its Android.bp
+	if orderfile.Properties.OrderfileLoad {
+		flags = props.addLoadFlags(ctx, flags)
+		return flags
+	}
+
+	// Add flags to profile this module
+	if props.ShouldProfileModule {
+		flags = props.addInstrumentationProfileGatherFlags(ctx, flags)
+		return flags
+	}
+
+	return flags
+}
+
+// Propagate profile orderfile flags down from binaries and shared libraries
+// We do not allow propagation for load flags because the orderfile is specific
+// to the module (binary / shared library)
+func orderfileDepsMutator(mctx android.TopDownMutatorContext) {
+	if m, ok := mctx.Module().(*Module); ok {
+		if !m.orderfile.orderfileLinkEnabled() {
+			return
+		}
+		mctx.WalkDeps(func(dep android.
+			Module, parent android.Module) bool {
+			tag := mctx.OtherModuleDependencyTag(dep)
+			libTag, isLibTag := tag.(libraryDependencyTag)
+
+			// Do not recurse down non-static dependencies
+			if isLibTag {
+				if !libTag.static() {
+					return false
+				}
+			} else {
+				if tag != objDepTag && tag != reuseObjTag {
+					return false
+				}
+			}
+
+			if dep, ok := dep.(*Module); ok {
+				if m.orderfile.Properties.OrderfileInstrLink {
+					dep.orderfile.Properties.OrderfileInstrLink = true;
+				}
+			}
+
+			return true
+		})
+	}
+}
+
+// Create orderfile variants for modules that need them
+func orderfileMutator(mctx android.BottomUpMutatorContext) {
+	if m, ok := mctx.Module().(*Module); ok && m.orderfile != nil {
+		if !m.static() && m.orderfile.orderfileEnabled() {
+			mctx.SetDependencyVariation("orderfile")
+			return
+		}
+
+		variationNames := []string{""}
+		if m.orderfile.Properties.OrderfileInstrLink {
+			variationNames = append(variationNames, "orderfile")
+		}
+
+		if len(variationNames) > 1 {
+			modules := mctx.CreateVariations(variationNames...)
+			for i, name := range variationNames {
+				if name == "" {
+					continue
+				}
+				variation := modules[i].(*Module)
+				variation.Properties.PreventInstall = true
+				variation.Properties.HideFromMake = true
+				variation.orderfile.Properties.ShouldProfileModule = true
+				variation.orderfile.Properties.OrderfileLoad = false
+			}
+		}
+	}
+}
diff --git a/cc/orderfile_test.go b/cc/orderfile_test.go
new file mode 100644
index 0000000..9e30bd2
--- /dev/null
+++ b/cc/orderfile_test.go
@@ -0,0 +1,493 @@
+// 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 cc
+
+import (
+	"testing"
+	"strings"
+
+	"android/soong/android"
+)
+
+func TestOrderfileProfileSharedLibrary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := libTest.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+func TestOrderfileLoadSharedLibrary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: true,
+			order_file_path: "libTest.orderfile",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/libTest.orderfile", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/libTest.orderfile"
+
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := libTest.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+func TestOrderfileProfileBinary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_binary {
+		name: "test",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	test := result.ModuleForTests("test", "android_arm64_armv8-a")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := test.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := test.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to enable orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+func TestOrderfileLoadBinary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_binary {
+		name: "test",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: true,
+			order_file_path: "test.orderfile",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/test.orderfile", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
+
+	test := result.ModuleForTests("test", "android_arm64_armv8-a")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := test.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := test.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to load orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+// Profile flags should propagate through static libraries
+func TestOrderfileProfilePropagateStaticDeps(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		static_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+
+	cc_library_static {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	// Check cFlags of orderfile-enabled module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of orderfile variant static libraries
+	libFooOfVariant  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_orderfile")
+	libBarOfVariant  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_orderfile")
+
+	cFlags = libFooOfVariant.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFooOfVariant' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBarOfVariant.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBarOfVariant' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to orderfile variant static libraries
+	if !hasDirectDep(result, libTest.Module(), libFooOfVariant.Module()) {
+		t.Errorf("libTest missing dependency on orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFooOfVariant.Module(), libBarOfVariant.Module()) {
+		t.Errorf("libTest missing dependency on orderfile variant of libBar")
+	}
+
+	// Check cFlags of the non-orderfile variant static libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check no dependency edge from orderfile-enabled module to non-orderfile variant static libraries
+	if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest has dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest has dependency on non-orderfile variant of libBar")
+	}
+}
+
+// Load flags should never propagate
+func TestOrderfileLoadPropagateStaticDeps(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		static_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: true,
+			order_file_path: "test.orderfile",
+		},
+	}
+
+	cc_library_static {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/test.orderfile", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
+
+	// Check cFlags of orderfile-enabled module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of the non-orderfile variant static libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' not load orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' not load orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries
+	if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
+	}
+
+	// Make sure no orderfile variants are created for static libraries because the flags were not propagated
+	libFooVariants := result.ModuleVariantsForTests("libFoo")
+	for _, v := range libFooVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
+		}
+	}
+
+	libBarVariants := result.ModuleVariantsForTests("libBar")
+	for _, v := range libBarVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
+		}
+	}
+}
+
+// Profile flags should not propagate through shared libraries
+func TestOrderfileProfilePropagateSharedDeps(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		shared_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+
+	cc_library_shared {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	// Check cFlags of orderfile-enabled module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of the static and shared libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_shared")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries
+	if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
+	}
+
+	// Make sure no orderfile variants are created for libraries because the flags were not propagated
+	libFooVariants := result.ModuleVariantsForTests("libFoo")
+	for _, v := range libFooVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
+		}
+	}
+
+	libBarVariants := result.ModuleVariantsForTests("libBar")
+	for _, v := range libBarVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
+		}
+	}
+}
+
+// Profile flags should not work or be propagated if orderfile flags start at a static library
+func TestOrderfileProfileStaticLibrary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_static {
+		name: "libTest",
+		srcs: ["test.c"],
+		static_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+
+	cc_library_static {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	// Check cFlags of module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_static")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of the static libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to non-orderfile variant libraries
+	if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
+	}
+
+	// Make sure no orderfile variants are created for static libraries because the flags were not propagated
+	libFooVariants := result.ModuleVariantsForTests("libFoo")
+	for _, v := range libFooVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
+		}
+	}
+
+	libBarVariants := result.ModuleVariantsForTests("libBar")
+	for _, v := range libBarVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
+		}
+	}
+}
\ No newline at end of file
diff --git a/cc/sanitize.go b/cc/sanitize.go
index c1ef970..30bce9b 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -87,6 +87,8 @@
 
 	hostOnlySanitizeFlags   = []string{"-fno-sanitize-recover=all"}
 	deviceOnlySanitizeFlags = []string{"-fsanitize-trap=all", "-ftrap-function=abort"}
+
+	noSanitizeLinkRuntimeFlag = "-fno-sanitize-link-runtime"
 )
 
 type SanitizerType int
@@ -407,6 +409,8 @@
 	exportedVars.ExportStringListStaticVariable("HostOnlySanitizeFlags", hostOnlySanitizeFlags)
 	exportedVars.ExportStringList("DeviceOnlySanitizeFlags", deviceOnlySanitizeFlags)
 
+	exportedVars.ExportStringList("MinimalRuntimeFlags", minimalRuntimeFlags)
+
 	// Leave out "-flto" from the slices exported to bazel, as we will use the
 	// dedicated LTO feature for this. For C Flags and Linker Flags, also leave
 	// out the cross DSO flag which will be added separately under the correct conditions.
@@ -422,6 +426,8 @@
 	exportedVars.ExportString("CfiExportsMapFilename", cfiExportsMapFilename)
 	exportedVars.ExportString("CfiAssemblySupportFlag", cfiAssemblySupportFlag)
 
+	exportedVars.ExportString("NoSanitizeLinkRuntimeFlag", noSanitizeLinkRuntimeFlag)
+
 	android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
 	android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
 }
@@ -923,7 +929,7 @@
 			// Bionic and musl sanitizer runtimes have already been added as dependencies so that
 			// the right variant of the runtime will be used (with the "-android" or "-musl"
 			// suffixes), so don't let clang the runtime library.
-			flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-link-runtime")
+			flags.Local.LdFlags = append(flags.Local.LdFlags, noSanitizeLinkRuntimeFlag)
 		} else {
 			// Host sanitizers only link symbols in the final executable, so
 			// there will always be undefined symbols in intermediate libraries.
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 62b3333..20e366e 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -814,9 +814,7 @@
 		// Run the code-generation phase to convert BazelTargetModules to BUILD files
 		// and print conversion codegenMetrics to the user.
 		codegenContext := bp2build.NewCodegenContext(ctx.Config(), ctx, bp2build.Bp2Build, topDir)
-		ctx.EventHandler.Do("codegen", func() {
-			codegenMetrics = bp2build.Codegen(codegenContext)
-		})
+		codegenMetrics = bp2build.Codegen(codegenContext)
 
 		ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
 
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index 67cb6cf..5c2316a 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -15,7 +15,6 @@
 package main
 
 import (
-	"android/soong/starlark_import"
 	"io/fs"
 	"io/ioutil"
 	"os"
@@ -23,6 +22,7 @@
 
 	"android/soong/android"
 	"android/soong/bp2build"
+	"android/soong/starlark_import"
 )
 
 // A helper function to generate a Read-only Bazel workspace in outDir
@@ -35,8 +35,7 @@
 		panic(err)
 	}
 
-	filesToWrite := bp2build.CreateBazelFiles(ctx.Config(), ruleShims, res.BuildDirToTargets(),
-		ctx.Mode())
+	filesToWrite := bp2build.CreateBazelFiles(ruleShims, res.BuildDirToTargets(), ctx.Mode())
 	bazelRcFiles, err2 := CopyBazelRcFiles()
 	if err2 != nil {
 		return err2
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 69ba1e9..8a8d605 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -1012,16 +1012,7 @@
 			Tags: tags,
 		}, attrs)
 	} else {
-		// The Out prop is not in an immediately accessible field
-		// in the Module struct, so use GetProperties and cast it
-		// to the known struct prop.
-		var outs []string
-		for _, propIntf := range m.GetProperties() {
-			if props, ok := propIntf.(*genRuleProperties); ok {
-				outs = props.Out
-				break
-			}
-		}
+		outs := m.RawOutputFiles(ctx)
 		for _, out := range outs {
 			if out == bazelName {
 				// This is a workaround to circumvent a Bazel warning where a genrule's
@@ -1096,6 +1087,25 @@
 	Export_includes []string
 }
 
+// RawOutputFfiles returns the raw outputs specified in Android.bp
+// This does not contain the fully resolved path relative to the top of the tree
+func (g *Module) RawOutputFiles(ctx android.BazelConversionContext) []string {
+	if ctx.Config().BuildMode != android.Bp2build {
+		ctx.ModuleErrorf("RawOutputFiles is only supported in bp2build mode")
+	}
+	// The Out prop is not in an immediately accessible field
+	// in the Module struct, so use GetProperties and cast it
+	// to the known struct prop.
+	var outs []string
+	for _, propIntf := range g.GetProperties() {
+		if props, ok := propIntf.(*genRuleProperties); ok {
+			outs = props.Out
+			break
+		}
+	}
+	return outs
+}
+
 var Bool = proptools.Bool
 var String = proptools.String
 
diff --git a/java/aapt2.go b/java/aapt2.go
index 7845a0b..3bb70b5 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -146,20 +146,25 @@
 
 var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link",
 	blueprint.RuleParams{
-		Command: `rm -rf $genDir && ` +
-			`${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` +
-			`--output-text-symbols ${rTxt} $inFlags && ` +
-			`${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir &&` +
-			`${config.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages '`,
+		Command: `$preamble` +
+			`${config.Aapt2Cmd} link -o $out $flags --proguard $proguardOptions ` +
+			`--output-text-symbols ${rTxt} $inFlags` +
+			`$postamble`,
 
 		CommandDeps: []string{
 			"${config.Aapt2Cmd}",
 			"${config.SoongZipCmd}",
-			"${config.ExtractJarPackagesCmd}",
 		},
 		Restat: true,
 	},
-	"flags", "inFlags", "proguardOptions", "genDir", "genJar", "rTxt", "extraPackages")
+	"flags", "inFlags", "proguardOptions", "rTxt", "extraPackages", "preamble", "postamble")
+
+var aapt2ExtractExtraPackagesRule = pctx.AndroidStaticRule("aapt2ExtractExtraPackages",
+	blueprint.RuleParams{
+		Command:     `${config.ExtractJarPackagesCmd} -i $in -o $out --prefix '--extra-packages '`,
+		CommandDeps: []string{"${config.ExtractJarPackagesCmd}"},
+		Restat:      true,
+	})
 
 var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile",
 	blueprint.RuleParams{
@@ -175,12 +180,10 @@
 	})
 
 func aapt2Link(ctx android.ModuleContext,
-	packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
+	packageRes, genJar, proguardOptions, rTxt android.WritablePath,
 	flags []string, deps android.Paths,
 	compiledRes, compiledOverlay, assetPackages android.Paths, splitPackages android.WritablePaths) {
 
-	genDir := android.PathForModuleGen(ctx, "aapt2", "R")
-
 	var inFlags []string
 
 	if len(compiledRes) > 0 {
@@ -217,7 +220,7 @@
 	}
 
 	// Set auxiliary outputs as implicit outputs to establish correct dependency chains.
-	implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
+	implicitOutputs := append(splitPackages, proguardOptions, rTxt)
 	linkOutput := packageRes
 
 	// AAPT2 ignores assets in overlays. Merge them after linking.
@@ -232,25 +235,49 @@
 		})
 	}
 
+	// Note the absence of splitPackages. The caller is supposed to compose and provide --split flag
+	// values via the flags parameter when it wants to split outputs.
+	// TODO(b/174509108): Perhaps we can process it in this func while keeping the code reasonably
+	// tidy.
+	args := map[string]string{
+		"flags":           strings.Join(flags, " "),
+		"inFlags":         strings.Join(inFlags, " "),
+		"proguardOptions": proguardOptions.String(),
+		"rTxt":            rTxt.String(),
+	}
+
+	if genJar != nil {
+		// Generating java source files from aapt2 was requested, use aapt2LinkAndGenRule and pass it
+		// genJar and genDir args.
+		genDir := android.PathForModuleGen(ctx, "aapt2", "R")
+		ctx.Variable(pctx, "aapt2GenDir", genDir.String())
+		ctx.Variable(pctx, "aapt2GenJar", genJar.String())
+		implicitOutputs = append(implicitOutputs, genJar)
+		args["preamble"] = `rm -rf $aapt2GenDir && `
+		args["postamble"] = `&& ${config.SoongZipCmd} -write_if_changed -jar -o $aapt2GenJar -C $aapt2GenDir -D $aapt2GenDir && ` +
+			`rm -rf $aapt2GenDir`
+		args["flags"] += " --java $aapt2GenDir"
+	}
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:            aapt2LinkRule,
 		Description:     "aapt2 link",
 		Implicits:       deps,
 		Output:          linkOutput,
 		ImplicitOutputs: implicitOutputs,
-		// Note the absence of splitPackages. The caller is supposed to compose and provide --split flag
-		// values via the flags parameter when it wants to split outputs.
-		// TODO(b/174509108): Perhaps we can process it in this func while keeping the code reasonably
-		// tidy.
-		Args: map[string]string{
-			"flags":           strings.Join(flags, " "),
-			"inFlags":         strings.Join(inFlags, " "),
-			"proguardOptions": proguardOptions.String(),
-			"genDir":          genDir.String(),
-			"genJar":          genJar.String(),
-			"rTxt":            rTxt.String(),
-			"extraPackages":   extraPackages.String(),
-		},
+		Args:            args,
+	})
+}
+
+// aapt2ExtractExtraPackages takes a srcjar generated by aapt2 or a classes jar generated by ResourceProcessorBusyBox
+// and converts it to a text file containing a list of --extra_package arguments for passing to Make modules so they
+// correctly generate R.java entries for packages provided by transitive dependencies.
+func aapt2ExtractExtraPackages(ctx android.ModuleContext, out android.WritablePath, in android.Path) {
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        aapt2ExtractExtraPackagesRule,
+		Description: "aapt2 extract extra packages",
+		Input:       in,
+		Output:      out,
 	})
 }
 
diff --git a/java/aar.go b/java/aar.go
index 180e1d7..1e38efc 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -376,13 +376,12 @@
 	}
 
 	packageRes := android.PathForModuleOut(ctx, "package-res.apk")
-	// the subdir "android" is required to be filtered by package names
-	srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
 	proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
 	rTxt := android.PathForModuleOut(ctx, "R.txt")
 	// This file isn't used by Soong, but is generated for exporting
 	extraPackages := android.PathForModuleOut(ctx, "extra_packages")
 	var transitiveRJars android.Paths
+	var srcJar android.WritablePath
 
 	var compiledResDirs []android.Paths
 	for _, dir := range resDirs {
@@ -459,15 +458,19 @@
 		})
 	}
 
+	if !a.useResourceProcessorBusyBox() {
+		// the subdir "android" is required to be filtered by package names
+		srcJar = android.PathForModuleGen(ctx, "android", "R.srcjar")
+	}
+
 	// No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
 	// provided to the final app aapt2Link step.
 	var transitiveAssets android.Paths
 	if !a.isLibrary {
 		transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
 	}
-	aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
+	aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
 		linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages)
-
 	// Extract assets from the resource package output so that they can be used later in aapt2link
 	// for modules that depend on this one.
 	if android.PrefixInList(linkFlags, "-A ") {
@@ -484,8 +487,11 @@
 	if a.useResourceProcessorBusyBox() {
 		rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
 		resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
+		aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
 		transitiveRJars = append(transitiveRJars, rJar)
 		a.rJar = rJar
+	} else {
+		aapt2ExtractExtraPackages(ctx, extraPackages, srcJar)
 	}
 
 	a.aaptSrcJar = srcJar
@@ -731,9 +737,10 @@
 
 	ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
 	ctx.CheckbuildFile(a.aapt.exportPackage)
-	ctx.CheckbuildFile(a.aapt.aaptSrcJar)
 	if a.useResourceProcessorBusyBox() {
 		ctx.CheckbuildFile(a.aapt.rJar)
+	} else {
+		ctx.CheckbuildFile(a.aapt.aaptSrcJar)
 	}
 
 	// apps manifests are handled by aapt, don't let Module see them
@@ -1063,8 +1070,6 @@
 	aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
 
 	a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
-	// the subdir "android" is required to be filtered by package names
-	srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar")
 	proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
 	a.rTxt = android.PathForModuleOut(ctx, "R.txt")
 	a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
@@ -1100,12 +1105,14 @@
 	}
 
 	transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
-	aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, a.rTxt, a.extraAaptPackagesFile,
+	aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, a.rTxt,
 		linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
 
 	a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
 	resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
 
+	aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
+
 	resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
 	resourcesNodesDepSetBuilder.Direct(&resourcesNode{
 		resPackage: a.exportPackage,
@@ -1305,7 +1312,11 @@
 }
 
 func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
-	commonAttrs, bp2buildInfo := a.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2buildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
+
 	depLabels := bp2buildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/java/app.go b/java/app.go
index 7172d22..e277aed 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1022,7 +1022,13 @@
 	case ".aapt.proguardOptionsFile":
 		return []android.Path{a.proguardOptionsFile}, nil
 	case ".aapt.srcjar":
-		return []android.Path{a.aaptSrcJar}, nil
+		if a.aaptSrcJar != nil {
+			return []android.Path{a.aaptSrcJar}, nil
+		}
+	case ".aapt.jar":
+		if a.rJar != nil {
+			return []android.Path{a.rJar}, nil
+		}
 	case ".export-package.apk":
 		return []android.Path{a.exportPackage}, nil
 	}
@@ -1055,7 +1061,6 @@
 
 	module.Module.dexProperties.Optimize.EnabledByDefault = true
 	module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
-	module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
 
 	module.Module.properties.Instrument = true
 	module.Module.properties.Supports_static_instrumentation = true
@@ -1614,7 +1619,10 @@
 
 // ConvertWithBp2build is used to convert android_app to Bazel.
 func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
-	commonAttrs, bp2BuildInfo := a.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/java/dex.go b/java/dex.go
index 7dd14bd..7e7da00 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -45,8 +45,8 @@
 		// Whether to continue building even if warnings are emitted.  Defaults to true.
 		Ignore_warnings *bool
 
-		// If true, runs R8 in Proguard compatibility mode, otherwise runs R8 in full mode.
-		// Defaults to false for apps, true for libraries and tests.
+		// If true, runs R8 in Proguard compatibility mode (default).
+		// Otherwise, runs R8 in full mode.
 		Proguard_compatibility *bool
 
 		// If true, optimize for size by removing unused code.  Defaults to true for apps,
diff --git a/java/droiddoc.go b/java/droiddoc.go
index d4ead12..3ba3065 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -699,7 +699,6 @@
 	cmd := rule.Command().
 		BuiltTool("soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
 		Flag(config.JavacVmFlags).
-		FlagWithArg("-encoding ", "UTF-8").
 		FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "javadoc.rsp"), srcs).
 		FlagWithInput("@", srcJarList)
 
diff --git a/java/droidstubs.go b/java/droidstubs.go
index bb2388f..51d36e4 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -512,17 +512,16 @@
 	cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
 		Flag(config.JavacVmFlags).
 		Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
-		FlagWithArg("-encoding ", "UTF-8").
-		FlagWithArg("-source ", javaVersion.String()).
+		FlagWithArg("--java-source ", javaVersion.String()).
 		FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "metalava.rsp"), srcs).
 		FlagWithInput("@", srcJarList)
 
-	if len(bootclasspath) > 0 {
-		cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
-	}
-
-	if len(classpath) > 0 {
-		cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
+	// Metalava does not differentiate between bootclasspath and classpath and has not done so for
+	// years, so it is unlikely to change any time soon.
+	combinedPaths := append(([]android.Path)(nil), bootclasspath.Paths()...)
+	combinedPaths = append(combinedPaths, classpath.Paths()...)
+	if len(combinedPaths) > 0 {
+		cmd.FlagWithInputList("--classpath ", combinedPaths, ":")
 	}
 
 	cmd.Flag("--color").
diff --git a/java/java.go b/java/java.go
index f29f738..0d39a6a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -26,6 +26,7 @@
 	"android/soong/bazel"
 	"android/soong/bazel/cquery"
 	"android/soong/remoteexec"
+	"android/soong/ui/metrics/bp2build_metrics_proto"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -1725,7 +1726,6 @@
 	cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")).
 		Flag(config.JavacVmFlags).
 		Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED").
-		FlagWithArg("-encoding ", "UTF-8").
 		FlagWithInputList("--source-files ", srcs, " ")
 
 	cmd.Flag("--color").
@@ -2828,7 +2828,7 @@
 // which has other non-attribute information needed for bp2build conversion
 // that needs different handling depending on the module types, and thus needs
 // to be returned to the calling function.
-func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo) {
+func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) {
 	var srcs bazel.LabelListAttribute
 	var deps bazel.LabelListAttribute
 	var staticDeps bazel.LabelListAttribute
@@ -2839,6 +2839,10 @@
 			if archProps, ok := _props.(*CommonProperties); ok {
 				archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs)
 				srcs.SetSelectValue(axis, config, archSrcs)
+				if archProps.Jarjar_rules != nil {
+					ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "jarjar_rules")
+					return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false
+				}
 			}
 		}
 	}
@@ -3006,7 +3010,7 @@
 		hasKotlin: hasKotlin,
 	}
 
-	return commonAttrs, bp2BuildInfo
+	return commonAttrs, bp2BuildInfo, true
 }
 
 type javaLibraryAttributes struct {
@@ -3036,7 +3040,10 @@
 }
 
 func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) {
-	commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
@@ -3083,7 +3090,10 @@
 
 // JavaBinaryHostBp2Build is for java_binary_host bp2build.
 func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) {
-	commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
@@ -3167,7 +3177,10 @@
 
 // javaTestHostBp2Build is for java_test_host bp2build.
 func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) {
-	commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 1bb4996..8494d02 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -122,3 +122,17 @@
 --warning_check RemoteViewLayout
 --warning_check SupportAnnotationUsage
 --warning_check UniqueConstants
+
+# TODO(b/294098365): these checks fail in AOSP, but pass downstream
+--warning_check ForegroundServiceType
+--warning_check MutableImplicitPendingIntent
+
+--warning_check ExactAlarm
+--warning_check ExpiredTargetSdkVersion
+--warning_check ForegroundServicePermission
+--warning_check ObsoleteSdkInt
+--warning_check ScheduleExactAlarm
+--warning_check StartActivityAndCollapseDeprecated
+--warning_check UnspecifiedRegisterReceiverFlag
+--warning_check WearMaterialTheme
+--warning_check WearStandaloneAppFlag
diff --git a/java/plugin.go b/java/plugin.go
index 731dfda..5127298 100644
--- a/java/plugin.go
+++ b/java/plugin.go
@@ -66,7 +66,10 @@
 // ConvertWithBp2build is used to convert android_app to Bazel.
 func (p *Plugin) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
 	pluginName := p.Name()
-	commonAttrs, bp2BuildInfo := p.convertLibraryAttrsBp2Build(ctx)
+	commonAttrs, bp2BuildInfo, supported := p.convertLibraryAttrsBp2Build(ctx)
+	if !supported {
+		return
+	}
 	depLabels := bp2BuildInfo.DepLabels
 
 	deps := depLabels.Deps
diff --git a/python/bp2build.go b/python/bp2build.go
index 60cabc4..41e9f49 100644
--- a/python/bp2build.go
+++ b/python/bp2build.go
@@ -73,7 +73,6 @@
 
 	if !partitionedSrcs["proto"].IsEmpty() {
 		protoInfo, _ := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, partitionedSrcs["proto"])
-		protoLabel := bazel.Label{Label: ":" + protoInfo.Name}
 
 		pyProtoLibraryName := m.Name() + "_py_proto"
 		ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
@@ -82,7 +81,7 @@
 		}, android.CommonAttributes{
 			Name: pyProtoLibraryName,
 		}, &bazelPythonProtoLibraryAttributes{
-			Deps: bazel.MakeSingleLabelListAttribute(protoLabel),
+			Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs),
 		})
 
 		attrs.Deps.Add(bazel.MakeLabelAttribute(":" + pyProtoLibraryName))
diff --git a/starlark_fmt/format.go b/starlark_fmt/format.go
index 4209507..0224bcf 100644
--- a/starlark_fmt/format.go
+++ b/starlark_fmt/format.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"reflect"
 	"sort"
 	"strconv"
 	"strings"
@@ -33,6 +34,72 @@
 	return strings.Repeat(" ", level*indent)
 }
 
+func PrintAny(value any, indentLevel int) string {
+	return printAnyRecursive(reflect.ValueOf(value), indentLevel)
+}
+
+func printAnyRecursive(value reflect.Value, indentLevel int) string {
+	switch value.Type().Kind() {
+	case reflect.String:
+		val := value.String()
+		if strings.Contains(val, "\"") || strings.Contains(val, "\n") {
+			return `'''` + val + `'''`
+		}
+		return `"` + val + `"`
+	case reflect.Bool:
+		if value.Bool() {
+			return "True"
+		} else {
+			return "False"
+		}
+	case reflect.Int:
+		return fmt.Sprintf("%d", value.Int())
+	case reflect.Slice:
+		if value.Len() == 0 {
+			return "[]"
+		} else if value.Len() == 1 {
+			return "[" + printAnyRecursive(value.Index(0), indentLevel) + "]"
+		}
+		list := make([]string, 0, value.Len()+2)
+		list = append(list, "[")
+		innerIndent := Indention(indentLevel + 1)
+		for i := 0; i < value.Len(); i++ {
+			list = append(list, innerIndent+printAnyRecursive(value.Index(i), indentLevel+1)+`,`)
+		}
+		list = append(list, Indention(indentLevel)+"]")
+		return strings.Join(list, "\n")
+	case reflect.Map:
+		if value.Len() == 0 {
+			return "{}"
+		}
+		items := make([]string, 0, value.Len())
+		for _, key := range value.MapKeys() {
+			items = append(items, fmt.Sprintf(`%s%s: %s,`, Indention(indentLevel+1), printAnyRecursive(key, indentLevel+1), printAnyRecursive(value.MapIndex(key), indentLevel+1)))
+		}
+		sort.Strings(items)
+		return fmt.Sprintf(`{
+%s
+%s}`, strings.Join(items, "\n"), Indention(indentLevel))
+	case reflect.Struct:
+		if value.NumField() == 0 {
+			return "struct()"
+		}
+		items := make([]string, 0, value.NumField()+2)
+		items = append(items, "struct(")
+		for i := 0; i < value.NumField(); i++ {
+			if value.Type().Field(i).Anonymous {
+				panic("anonymous fields aren't supported")
+			}
+			name := value.Type().Field(i).Name
+			items = append(items, fmt.Sprintf(`%s%s = %s,`, Indention(indentLevel+1), name, printAnyRecursive(value.Field(i), indentLevel+1)))
+		}
+		items = append(items, Indention(indentLevel)+")")
+		return strings.Join(items, "\n")
+	default:
+		panic("Unhandled kind: " + value.Kind().String())
+	}
+}
+
 // PrintBool returns a Starlark compatible bool string.
 func PrintBool(item bool) string {
 	if item {
diff --git a/tests/lib.sh b/tests/lib.sh
index 40b317b..f3db76f 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -52,6 +52,10 @@
   cp -R "$REAL_TOP/$dir" "$MOCK_TOP/$parent"
 }
 
+function delete_directory {
+  rm -rf "$MOCK_TOP/$1"
+}
+
 function symlink_file {
   local file="$1"
 
@@ -138,6 +142,9 @@
   copy_directory build/bazel
   copy_directory build/bazel_common_rules
 
+  # This requires pulling more tools into the mock top to build partitions
+  delete_directory build/bazel/examples/partitions
+
   symlink_directory packages/modules/common/build
   symlink_directory prebuilts/bazel
   symlink_directory prebuilts/clang
@@ -147,6 +154,7 @@
   symlink_directory external/bazelbuild-rules_go
   symlink_directory external/bazelbuild-rules_license
   symlink_directory external/bazelbuild-kotlin-rules
+  symlink_directory external/bazelbuild-rules_python
   symlink_directory external/bazelbuild-rules_java
 
   symlink_file WORKSPACE
diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh
index 2534b20..c41f28d 100755
--- a/tests/sbom_test.sh
+++ b/tests/sbom_test.sh
@@ -85,34 +85,17 @@
   lz4=$out_dir/host/linux-x86/bin/lz4
 
   declare -A diff_excludes
-  diff_excludes[product]="\
-    -I /product/etc/aconfig_flags.textproto \
-    -I /product/etc/build_flags.json"
   diff_excludes[vendor]="\
-    -I /vendor/lib64/libkeystore2_crypto.so \
-    -I /vendor/etc/aconfig_flags.textproto \
-    -I /vendor/etc/build_flags.json"
+    -I /vendor/lib64/libkeystore2_crypto.so"
   diff_excludes[system]="\
-    -I /bin \
-    -I /bugreports \
-    -I /cache \
-    -I /d \
-    -I /etc \
-    -I /init \
-    -I /odm/app \
-    -I /odm/bin \
-    -I /odm_dlkm/etc \
-    -I /odm/etc \
-    -I /odm/firmware \
-    -I /odm/framework \
-    -I /odm/lib \
-    -I /odm/lib64 \
-    -I /odm/overlay \
-    -I /odm/priv-app \
-    -I /odm/usr \
-    -I /sdcard \
-    -I /system/etc/aconfig_flags.textproto \
-    -I /system/etc/build_flags.json \
+    -I /system/bin/assemble_cvd
+    -I /system/bin/console_forwarder
+    -I /system/bin/kernel_log_monitor
+    -I /system/bin/logcat_receiver
+    -I /system/bin/mkenvimage_slim
+    -I /system/bin/run_cvd
+    -I /system/bin/simg2img
+    -I /system/bin/log_tee
     -I /system/lib64/android.hardware.confirmationui@1.0.so \
     -I /system/lib64/android.hardware.confirmationui-V1-ndk.so \
     -I /system/lib64/android.hardware.keymaster@4.1.so \
@@ -140,11 +123,7 @@
     -I /system/lib64/vndk-sp-29 \
     -I /system/lib/vndk-29 \
     -I /system/lib/vndk-sp-29 \
-    -I /system/usr/icu \
-    -I /vendor_dlkm/etc"
-  diff_excludes[system_ext]="\
-    -I /system_ext/etc/aconfig_flags.textproto \
-    -I /system_ext/etc/build_flags.json"
+    -I /system/usr/icu"
 
   # Example output of dump.erofs is as below, and the data used in the test start
   # at line 11. Column 1 is inode id, column 2 is inode type and column 3 is name.
diff --git a/ui/build/config.go b/ui/build/config.go
index e5c9a50..5d1505a 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -15,7 +15,6 @@
 package build
 
 import (
-	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -40,9 +39,6 @@
 const (
 	envConfigDir = "vendor/google/tools/soong_config"
 	jsonSuffix   = "json"
-
-	configFetcher         = "vendor/google/tools/soong/expconfigfetcher"
-	envConfigFetchTimeout = 20 * time.Second
 )
 
 var (
@@ -174,87 +170,6 @@
 	}
 }
 
-// fetchEnvConfig optionally fetches a configuration file that can then subsequently be
-// loaded into Soong environment to control certain aspects of build behavior (e.g., enabling RBE).
-// If a configuration file already exists on disk, the fetch is run in the background
-// so as to NOT block the rest of the build execution.
-func fetchEnvConfig(ctx Context, config *configImpl, envConfigName string) error {
-	configName := envConfigName + "." + jsonSuffix
-	expConfigFetcher := &smpb.ExpConfigFetcher{Filename: &configName}
-	defer func() {
-		ctx.Metrics.ExpConfigFetcher(expConfigFetcher)
-	}()
-	if !config.GoogleProdCredsExist() {
-		status := smpb.ExpConfigFetcher_MISSING_GCERT
-		expConfigFetcher.Status = &status
-		return nil
-	}
-
-	s, err := os.Stat(configFetcher)
-	if err != nil {
-		if os.IsNotExist(err) {
-			return nil
-		}
-		return err
-	}
-	if s.Mode()&0111 == 0 {
-		status := smpb.ExpConfigFetcher_ERROR
-		expConfigFetcher.Status = &status
-		return fmt.Errorf("configuration fetcher binary %v is not executable: %v", configFetcher, s.Mode())
-	}
-
-	configExists := false
-	outConfigFilePath := filepath.Join(config.OutDir(), configName)
-	if _, err := os.Stat(outConfigFilePath); err == nil {
-		configExists = true
-	}
-
-	tCtx, cancel := context.WithTimeout(ctx, envConfigFetchTimeout)
-	fetchStart := time.Now()
-	cmd := exec.CommandContext(tCtx, configFetcher, "-output_config_dir", config.OutDir(),
-		"-output_config_name", configName)
-	if err := cmd.Start(); err != nil {
-		status := smpb.ExpConfigFetcher_ERROR
-		expConfigFetcher.Status = &status
-		return err
-	}
-
-	fetchCfg := func() error {
-		if err := cmd.Wait(); err != nil {
-			status := smpb.ExpConfigFetcher_ERROR
-			expConfigFetcher.Status = &status
-			return err
-		}
-		fetchEnd := time.Now()
-		expConfigFetcher.Micros = proto.Uint64(uint64(fetchEnd.Sub(fetchStart).Microseconds()))
-		expConfigFetcher.Filename = proto.String(outConfigFilePath)
-
-		if _, err := os.Stat(outConfigFilePath); err != nil {
-			status := smpb.ExpConfigFetcher_NO_CONFIG
-			expConfigFetcher.Status = &status
-			return err
-		}
-		status := smpb.ExpConfigFetcher_CONFIG
-		expConfigFetcher.Status = &status
-		return nil
-	}
-
-	// If a config file does not exist, wait for the config file to be fetched. Otherwise
-	// fetch the config file in the background and return immediately.
-	if !configExists {
-		defer cancel()
-		return fetchCfg()
-	}
-
-	go func() {
-		defer cancel()
-		if err := fetchCfg(); err != nil {
-			ctx.Verbosef("Failed to fetch config file %v: %v\n", configName, err)
-		}
-	}()
-	return nil
-}
-
 func loadEnvConfig(ctx Context, config *configImpl, bc string) error {
 	if bc == "" {
 		return nil
@@ -368,9 +283,6 @@
 	bc := os.Getenv("ANDROID_BUILD_ENVIRONMENT_CONFIG")
 
 	if bc != "" {
-		if err := fetchEnvConfig(ctx, ret, bc); err != nil {
-			ctx.Verbosef("Failed to fetch config file: %v\n", err)
-		}
 		if err := loadEnvConfig(ctx, ret, bc); err != nil {
 			ctx.Fatalln("Failed to parse env config files: %v", err)
 		}
@@ -525,6 +437,11 @@
 	ret.environ.Set("ANDROID_JAVA11_HOME", java11Home)
 	ret.environ.Set("PATH", strings.Join(newPath, string(filepath.ListSeparator)))
 
+	// b/286885495, https://bugzilla.redhat.com/show_bug.cgi?id=2227130: some versions of Fedora include patches
+	// to unzip to enable zipbomb detection that incorrectly handle zip64 and data descriptors and fail on large
+	// zip files produced by soong_zip.  Disable zipbomb detection.
+	ret.environ.Set("UNZIP_DISABLE_ZIPBOMB_DETECTION", "TRUE")
+
 	if ret.MultitreeBuild() {
 		ret.environ.Set("MULTITREE_BUILD", "true")
 	}