Merge "Add `vendor_available: true` to libbuildverison"
diff --git a/android/bazel.go b/android/bazel.go
index c3efb0a..97f47be 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -226,8 +226,9 @@
 
 	// Configure modules in these directories to enable bp2build_available: true or false by default.
 	bp2buildDefaultConfig = Bp2BuildConfig{
-		"art/libdexfile": Bp2BuildDefaultTrueRecursively,
-		"bionic":         Bp2BuildDefaultTrueRecursively,
+		"art/libdexfile":                        Bp2BuildDefaultTrueRecursively,
+		"bionic":                                Bp2BuildDefaultTrueRecursively,
+		"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
 		"build/bazel/examples/soong_config_variables":        Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/apex/minimal":                  Bp2BuildDefaultTrueRecursively,
 		"build/soong":                                        Bp2BuildDefaultTrue,
@@ -235,6 +236,40 @@
 		"build/soong/cc/ndkstubgen":                          Bp2BuildDefaultTrue,
 		"build/soong/cc/symbolfile":                          Bp2BuildDefaultTrue,
 		"cts/common/device-side/nativetesthelper/jni":        Bp2BuildDefaultTrueRecursively,
+		"development/apps/DevelopmentSettings":               Bp2BuildDefaultTrue,
+		"development/apps/Fallback":                          Bp2BuildDefaultTrue,
+		"development/apps/WidgetPreview":                     Bp2BuildDefaultTrue,
+		"development/samples/BasicGLSurfaceView":             Bp2BuildDefaultTrue,
+		"development/samples/BluetoothChat":                  Bp2BuildDefaultTrue,
+		"development/samples/BrokenKeyDerivation":            Bp2BuildDefaultTrue,
+		"development/samples/Compass":                        Bp2BuildDefaultTrue,
+		"development/samples/ContactManager":                 Bp2BuildDefaultTrue,
+		"development/samples/FixedGridLayout":                Bp2BuildDefaultTrue,
+		"development/samples/HelloEffects":                   Bp2BuildDefaultTrue,
+		"development/samples/Home":                           Bp2BuildDefaultTrue,
+		"development/samples/HoneycombGallery":               Bp2BuildDefaultTrue,
+		"development/samples/JetBoy":                         Bp2BuildDefaultTrue,
+		"development/samples/KeyChainDemo":                   Bp2BuildDefaultTrue,
+		"development/samples/LceDemo":                        Bp2BuildDefaultTrue,
+		"development/samples/LunarLander":                    Bp2BuildDefaultTrue,
+		"development/samples/MultiResolution":                Bp2BuildDefaultTrue,
+		"development/samples/MultiWindow":                    Bp2BuildDefaultTrue,
+		"development/samples/NotePad":                        Bp2BuildDefaultTrue,
+		"development/samples/Obb":                            Bp2BuildDefaultTrue,
+		"development/samples/RSSReader":                      Bp2BuildDefaultTrue,
+		"development/samples/ReceiveShareDemo":               Bp2BuildDefaultTrue,
+		"development/samples/SearchableDictionary":           Bp2BuildDefaultTrue,
+		"development/samples/SipDemo":                        Bp2BuildDefaultTrue,
+		"development/samples/SkeletonApp":                    Bp2BuildDefaultTrue,
+		"development/samples/Snake":                          Bp2BuildDefaultTrue,
+		"development/samples/SpellChecker/":                  Bp2BuildDefaultTrueRecursively,
+		"development/samples/ThemedNavBarKeyboard":           Bp2BuildDefaultTrue,
+		"development/samples/ToyVpn":                         Bp2BuildDefaultTrue,
+		"development/samples/TtsEngine":                      Bp2BuildDefaultTrue,
+		"development/samples/USB/AdbTest":                    Bp2BuildDefaultTrue,
+		"development/samples/USB/MissileLauncher":            Bp2BuildDefaultTrue,
+		"development/samples/VoiceRecognitionService":        Bp2BuildDefaultTrue,
+		"development/samples/VoicemailProviderDemo":          Bp2BuildDefaultTrue,
 		"development/sdk":                                    Bp2BuildDefaultTrueRecursively,
 		"external/arm-optimized-routines":                    Bp2BuildDefaultTrueRecursively,
 		"external/boringssl":                                 Bp2BuildDefaultTrueRecursively,
@@ -261,9 +296,19 @@
 		"external/selinux/libselinux":                        Bp2BuildDefaultTrueRecursively,
 		"external/zlib":                                      Bp2BuildDefaultTrueRecursively,
 		"external/zstd":                                      Bp2BuildDefaultTrueRecursively,
+		"frameworks/base/media/tests/MediaDump":              Bp2BuildDefaultTrue,
+		"frameworks/base/startop/apps/test":                  Bp2BuildDefaultTrue,
 		"frameworks/native/libs/adbd_auth":                   Bp2BuildDefaultTrueRecursively,
+		"frameworks/native/opengl/tests/gl2_cameraeye":       Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/gl2_java":            Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/testLatency":         Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/testPauseResume":     Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/testViewport":        Bp2BuildDefaultTrue,
 		"frameworks/proto_logging/stats/stats_log_api_gen":   Bp2BuildDefaultTrueRecursively,
 		"libnativehelper":                                    Bp2BuildDefaultTrueRecursively,
+		"packages/apps/DevCamera":                            Bp2BuildDefaultTrue,
+		"packages/apps/HTMLViewer":                           Bp2BuildDefaultTrue,
+		"packages/apps/Protips":                              Bp2BuildDefaultTrue,
 		"packages/modules/adb":                               Bp2BuildDefaultTrue,
 		"packages/modules/adb/crypto":                        Bp2BuildDefaultTrueRecursively,
 		"packages/modules/adb/libs":                          Bp2BuildDefaultTrueRecursively,
@@ -271,6 +316,9 @@
 		"packages/modules/adb/pairing_connection":            Bp2BuildDefaultTrueRecursively,
 		"packages/modules/adb/proto":                         Bp2BuildDefaultTrueRecursively,
 		"packages/modules/adb/tls":                           Bp2BuildDefaultTrueRecursively,
+		"packages/providers/MediaProvider/tools/dialogs":     Bp2BuildDefaultTrue,
+		"packages/screensavers/Basic":                        Bp2BuildDefaultTrue,
+		"packages/services/Car/tests/SampleRearViewCamera":   Bp2BuildDefaultTrue,
 		"prebuilts/clang/host/linux-x86":                     Bp2BuildDefaultTrueRecursively,
 		"system/apex":                                        Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures
 		"system/core/debuggerd":                              Bp2BuildDefaultTrue,
@@ -393,6 +441,7 @@
 		"mdnsd",        // http://b/202876379 has arch-variant static_executable
 
 		"acvp_modulewrapper", // disabled for android x86/x86_64
+		"CarHTMLViewer",      // depends on unconverted modules android.car-stubs, car-ui-lib
 	}
 
 	// Per-module denylist of cc_library modules to only generate the static
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 729c73c..62e6156 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -279,6 +279,16 @@
 	return newPaths
 }
 
+// Converts root-relative Paths to a list of bazel.Label relative to the module in ctx.
+func RootToModuleRelativePaths(ctx BazelConversionPathContext, paths Paths) []bazel.Label {
+	var newPaths []bazel.Label
+	for _, path := range PathsWithModuleSrcSubDir(ctx, paths, "") {
+		s := path.Rel()
+		newPaths = append(newPaths, bazel.Label{Label: s})
+	}
+	return newPaths
+}
+
 // expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local source
 // directory and Bazel target labels, excluding those included in the excludes argument (which
 // should already be expanded to resolve references to Soong-modules). Valid elements of paths
@@ -328,12 +338,7 @@
 				// e.g. turn "math/*.c" in
 				// external/arm-optimized-routines to external/arm-optimized-routines/math/*.c
 				rootRelativeGlobPath := pathForModuleSrc(ctx, p).String()
-				globbedPaths := GlobFiles(ctx, rootRelativeGlobPath, rootRelativeExpandedExcludes)
-				globbedPaths = PathsWithModuleSrcSubDir(ctx, globbedPaths, "")
-				for _, path := range globbedPaths {
-					s := path.Rel()
-					expandedPaths = append(expandedPaths, bazel.Label{Label: s})
-				}
+				expandedPaths = RootToModuleRelativePaths(ctx, GlobFiles(ctx, rootRelativeGlobPath, rootRelativeExpandedExcludes))
 			} else {
 				if !InList(p, expandedExcludes) {
 					expandedPaths = append(expandedPaths, bazel.Label{Label: p})
diff --git a/android/config.go b/android/config.go
index ddad1f5..8e01e18 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1194,10 +1194,6 @@
 	return c.config.productVariables.DeviceKernelHeaders
 }
 
-func (c *deviceConfig) SamplingPGO() bool {
-	return Bool(c.config.productVariables.SamplingPGO)
-}
-
 // JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
 // path. Coverage is enabled by default when the product variable
 // JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
diff --git a/android/variable.go b/android/variable.go
index a29c6f8..158d264 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -299,8 +299,6 @@
 	ClangTidy  *bool   `json:",omitempty"`
 	TidyChecks *string `json:",omitempty"`
 
-	SamplingPGO *bool `json:",omitempty"`
-
 	JavaCoveragePaths        []string `json:",omitempty"`
 	JavaCoverageExcludePaths []string `json:",omitempty"`
 
diff --git a/apex/apex.go b/apex/apex.go
index 2ca26a2..4ecb104 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2186,6 +2186,40 @@
 		filesToAdd = append(filesToAdd, *af)
 	}
 
+	if pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex(); pathInApex != "" {
+		pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
+		tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)
+
+		if pathOnHost != nil {
+			// We need to copy the profile to a temporary path with the right filename because the apexer
+			// will take the filename as is.
+			ctx.Build(pctx, android.BuildParams{
+				Rule:   android.Cp,
+				Input:  pathOnHost,
+				Output: tempPath,
+			})
+		} else {
+			// At this point, the boot image profile cannot be generated. It is probably because the boot
+			// image profile source file does not exist on the branch, or it is not available for the
+			// current build target.
+			// However, we cannot enforce the boot image profile to be generated because some build
+			// targets (such as module SDK) do not need it. It is only needed when the APEX is being
+			// built. Therefore, we create an error rule so that an error will occur at the ninja phase
+			// only if the APEX is being built.
+			ctx.Build(pctx, android.BuildParams{
+				Rule:   android.ErrorRule,
+				Output: tempPath,
+				Args: map[string]string{
+					"error": "Boot image profile cannot be generated",
+				},
+			})
+		}
+
+		androidMkModuleName := filepath.Base(pathInApex)
+		af := newApexFile(ctx, tempPath, androidMkModuleName, filepath.Dir(pathInApex), etc, nil)
+		filesToAdd = append(filesToAdd, af)
+	}
+
 	return filesToAdd
 }
 
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b805cd9..2f7dce5 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7037,6 +7037,7 @@
 				`, insert))
 			}
 		}),
+		dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
 	).
 		ExtendWithErrorHandler(errorHandler).
 		RunTestWithBp(t, bp)
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index cb7d3d1..9e030f1 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -21,6 +21,7 @@
 	"testing"
 
 	"android/soong/android"
+	"android/soong/dexpreopt"
 	"android/soong/java"
 
 	"github.com/google/blueprint/proptools"
@@ -35,11 +36,14 @@
 )
 
 // Some additional files needed for the art apex.
-var prepareForTestWithArtApex = android.FixtureMergeMockFs(android.MockFS{
-	"com.android.art.avbpubkey":                          nil,
-	"com.android.art.pem":                                nil,
-	"system/sepolicy/apex/com.android.art-file_contexts": nil,
-})
+var prepareForTestWithArtApex = android.GroupFixturePreparers(
+	android.FixtureMergeMockFs(android.MockFS{
+		"com.android.art.avbpubkey":                          nil,
+		"com.android.art.pem":                                nil,
+		"system/sepolicy/apex/com.android.art-file_contexts": nil,
+	}),
+	dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
+)
 
 func TestBootclasspathFragments(t *testing.T) {
 	result := android.GroupFixturePreparers(
@@ -408,6 +412,7 @@
 		).RunTest(t)
 
 		ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+			"etc/boot-image.prof",
 			"etc/classpaths/bootclasspath.pb",
 			"javalib/arm/boot.art",
 			"javalib/arm/boot.oat",
@@ -451,6 +456,7 @@
 		).RunTest(t)
 
 		ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+			"etc/boot-image.prof",
 			"etc/classpaths/bootclasspath.pb",
 			"javalib/arm/boot.art",
 			"javalib/arm/boot.oat",
diff --git a/bazel/properties.go b/bazel/properties.go
index bbaa33e..76be058 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -385,9 +385,12 @@
 	}
 }
 
-func (ll labelListSelectValues) appendSelects(other labelListSelectValues) {
+func (ll labelListSelectValues) appendSelects(other labelListSelectValues, forceSpecifyEmptyList bool) {
 	for k, v := range other {
 		l := ll[k]
+		if forceSpecifyEmptyList && l.IsNil() && !v.IsNil() {
+			l.Includes = []Label{}
+		}
 		(&l).Append(v)
 		ll[k] = l
 	}
@@ -443,17 +446,22 @@
 	cll[axis][config] = list
 }
 
-func (cll configurableLabelLists) Append(other configurableLabelLists) {
+func (cll configurableLabelLists) Append(other configurableLabelLists, forceSpecifyEmptyList bool) {
 	for axis, otherSelects := range other {
 		selects := cll[axis]
 		if selects == nil {
 			selects = make(labelListSelectValues, len(otherSelects))
 		}
-		selects.appendSelects(otherSelects)
+		selects.appendSelects(otherSelects, forceSpecifyEmptyList)
 		cll[axis] = selects
 	}
 }
 
+func (lla *LabelListAttribute) Clone() *LabelListAttribute {
+	result := &LabelListAttribute{ForceSpecifyEmptyList: lla.ForceSpecifyEmptyList}
+	return result.Append(*lla)
+}
+
 // MakeLabelListAttribute initializes a LabelListAttribute with the non-arch specific value.
 func MakeLabelListAttribute(value LabelList) LabelListAttribute {
 	return LabelListAttribute{
@@ -507,16 +515,18 @@
 }
 
 // Append all values, including os and arch specific ones, from another
-// LabelListAttribute to this LabelListAttribute.
-func (lla *LabelListAttribute) Append(other LabelListAttribute) {
-	if lla.ForceSpecifyEmptyList && !other.Value.IsNil() {
+// LabelListAttribute to this LabelListAttribute. Returns this LabelListAttribute.
+func (lla *LabelListAttribute) Append(other LabelListAttribute) *LabelListAttribute {
+	forceSpecifyEmptyList := lla.ForceSpecifyEmptyList || other.ForceSpecifyEmptyList
+	if forceSpecifyEmptyList && lla.Value.IsNil() && !other.Value.IsNil() {
 		lla.Value.Includes = []Label{}
 	}
 	lla.Value.Append(other.Value)
 	if lla.ConfigurableValues == nil {
 		lla.ConfigurableValues = make(configurableLabelLists)
 	}
-	lla.ConfigurableValues.Append(other.ConfigurableValues)
+	lla.ConfigurableValues.Append(other.ConfigurableValues, forceSpecifyEmptyList)
+	return lla
 }
 
 // Add inserts the labels for each axis of LabelAttribute at the end of corresponding axis's
@@ -795,12 +805,18 @@
 
 // Append appends all values, including os and arch specific ones, from another
 // StringListAttribute to this StringListAttribute
-func (sla *StringListAttribute) Append(other StringListAttribute) {
+func (sla *StringListAttribute) Append(other StringListAttribute) *StringListAttribute {
 	sla.Value = append(sla.Value, other.Value...)
 	if sla.ConfigurableValues == nil {
 		sla.ConfigurableValues = make(configurableStringLists)
 	}
 	sla.ConfigurableValues.Append(other.ConfigurableValues)
+	return sla
+}
+
+func (sla *StringListAttribute) Clone() *StringListAttribute {
+	result := &StringListAttribute{}
+	return result.Append(*sla)
 }
 
 // SetSelectValue set a value for a bazel select for the given axis, config and value.
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
new file mode 100644
index 0000000..b12b567
--- /dev/null
+++ b/bp2build/android_app_conversion_test.go
@@ -0,0 +1,92 @@
+// Copyright 2021 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 bp2build
+
+import (
+	"android/soong/android"
+	"android/soong/java"
+
+	"testing"
+)
+
+func runAndroidAppTestCase(t *testing.T, tc bp2buildTestCase) {
+	t.Helper()
+	runBp2BuildTestCase(t, registerAndroidAppModuleTypes, tc)
+}
+
+func registerAndroidAppModuleTypes(ctx android.RegistrationContext) {
+}
+
+func TestMinimalAndroidApp(t *testing.T) {
+	runAndroidAppTestCase(t, bp2buildTestCase{
+		description:                        "Android app - simple example",
+		moduleTypeUnderTest:                "android_app",
+		moduleTypeUnderTestFactory:         java.AndroidAppFactory,
+		moduleTypeUnderTestBp2BuildMutator: java.AppBp2Build,
+		filesystem: map[string]string{
+			"app.java":            "",
+			"res/res.png":         "",
+			"AndroidManifest.xml": "",
+		},
+		blueprint: `
+android_app {
+        name: "TestApp",
+        srcs: ["app.java"],
+        sdk_version: "current",
+}
+`,
+		expectedBazelTargets: []string{
+			makeBazelTarget("android_binary", "TestApp", attrNameToString{
+				"srcs":           `["app.java"]`,
+				"manifest":       `"AndroidManifest.xml"`,
+				"resource_files": `["res/res.png"]`,
+			}),
+		}})
+}
+
+func TestAndroidAppAllSupportedFields(t *testing.T) {
+	runAndroidAppTestCase(t, bp2buildTestCase{
+		description:                        "Android app - all supported fields",
+		moduleTypeUnderTest:                "android_app",
+		moduleTypeUnderTestFactory:         java.AndroidAppFactory,
+		moduleTypeUnderTestBp2BuildMutator: java.AppBp2Build,
+		filesystem: map[string]string{
+			"app.java":                     "",
+			"resa/res.png":                 "",
+			"resb/res.png":                 "",
+			"manifest/AndroidManifest.xml": "",
+		},
+		blueprint: `
+android_app {
+        name: "TestApp",
+        srcs: ["app.java"],
+        sdk_version: "current",
+        package_name: "com.google",
+        resource_dirs: ["resa", "resb"],
+        manifest: "manifest/AndroidManifest.xml",
+}
+`,
+		expectedBazelTargets: []string{
+			makeBazelTarget("android_binary", "TestApp", attrNameToString{
+				"srcs":     `["app.java"]`,
+				"manifest": `"manifest/AndroidManifest.xml"`,
+				"resource_files": `[
+        "resa/res.png",
+        "resb/res.png",
+    ]`,
+				"custom_package": `"com.google"`,
+			}),
+		}})
+}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 8c8898e..dcbe326 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -130,17 +130,16 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo-lib", attrNameToString{
-				"copts":               `["-Wall"]`,
-				"export_includes":     `["foo-dir"]`,
-				"implementation_deps": `[":some-headers"]`,
-				"linkopts": `["-Wl,--exclude-libs=bar.a"] + select({
+		expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+			"copts":               `["-Wall"]`,
+			"export_includes":     `["foo-dir"]`,
+			"implementation_deps": `[":some-headers"]`,
+			"linkopts": `["-Wl,--exclude-libs=bar.a"] + select({
         "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
         "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=qux.a"],
         "//conditions:default": [],
     })`,
-				"srcs": `["impl.cpp"] + select({
+			"srcs": `["impl.cpp"] + select({
         "//build/bazel/platforms/arch:x86": ["x86.cpp"],
         "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
         "//conditions:default": [],
@@ -154,8 +153,7 @@
         "//build/bazel/platforms/os:linux_bionic": ["bionic.cpp"],
         "//conditions:default": [],
     })`,
-			}),
-		},
+		}),
 	})
 }
 
@@ -203,17 +201,16 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "fake-ld-android", attrNameToString{
-				"srcs": `["ld_android.cpp"]`,
-				"copts": `[
+		expectedBazelTargets: makeCcLibraryTargets("fake-ld-android", attrNameToString{
+			"srcs": `["ld_android.cpp"]`,
+			"copts": `[
         "-Wall",
         "-Wextra",
         "-Wunused",
         "-Werror",
     ]`,
-				"implementation_deps": `[":libc_headers"]`,
-				"linkopts": `[
+			"implementation_deps": `[":libc_headers"]`,
+			"linkopts": `[
         "-Wl,--exclude-libs=libgcc.a",
         "-Wl,--exclude-libs=libgcc_stripped.a",
         "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
@@ -225,8 +222,7 @@
         "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=libgcc_eh.a"],
         "//conditions:default": [],
     })`,
-			}),
-		},
+		}),
 	})
 }
 
@@ -271,16 +267,14 @@
 `,
 		},
 		blueprint: soongCcLibraryPreamble,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "fake-libarm-optimized-routines-math", attrNameToString{
-				"copts": `select({
+		expectedBazelTargets: makeCcLibraryTargets("fake-libarm-optimized-routines-math", attrNameToString{
+			"copts": `select({
         "//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
         "//conditions:default": [],
     })`,
-				"local_includes": `["."]`,
-				"srcs_c":         `["math/cosf.c"]`,
-			}),
-		},
+			"local_includes": `["."]`,
+			"srcs_c":         `["math/cosf.c"]`,
+		}),
 	})
 }
 
@@ -366,26 +360,48 @@
 }
 `,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"copts":                       `["bothflag"]`,
-				"implementation_deps":         `[":static_dep_for_both"]`,
-				"implementation_dynamic_deps": `[":shared_dep_for_both"]`,
-				"shared": `{
-        "copts": ["sharedflag"],
-        "implementation_deps": [":static_dep_for_shared"],
-        "implementation_dynamic_deps": [":shared_dep_for_shared"],
-        "srcs": ["sharedonly.cpp"],
-        "whole_archive_deps": [":whole_static_lib_for_shared"],
-    }`,
-				"srcs": `["both.cpp"]`,
-				"static": `{
-        "copts": ["staticflag"],
-        "implementation_deps": [":static_dep_for_static"],
-        "implementation_dynamic_deps": [":shared_dep_for_static"],
-        "srcs": ["staticonly.cpp"],
-        "whole_archive_deps": [":whole_static_lib_for_static"],
-    }`,
-				"whole_archive_deps": `[":whole_static_lib_for_both"]`,
+			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+				"copts": `[
+        "bothflag",
+        "staticflag",
+    ]`,
+				"implementation_deps": `[
+        ":static_dep_for_both",
+        ":static_dep_for_static",
+    ]`,
+				"implementation_dynamic_deps": `[
+        ":shared_dep_for_both",
+        ":shared_dep_for_static",
+    ]`,
+				"srcs": `[
+        "both.cpp",
+        "staticonly.cpp",
+    ]`,
+				"whole_archive_deps": `[
+        ":whole_static_lib_for_both",
+        ":whole_static_lib_for_static",
+    ]`}),
+			makeBazelTarget("cc_library_shared", "a", attrNameToString{
+				"copts": `[
+        "bothflag",
+        "sharedflag",
+    ]`,
+				"implementation_deps": `[
+        ":static_dep_for_both",
+        ":static_dep_for_shared",
+    ]`,
+				"implementation_dynamic_deps": `[
+        ":shared_dep_for_both",
+        ":shared_dep_for_shared",
+    ]`,
+				"srcs": `[
+        "both.cpp",
+        "sharedonly.cpp",
+    ]`,
+				"whole_archive_deps": `[
+        ":whole_static_lib_for_both",
+        ":whole_static_lib_for_shared",
+    ]`,
 			}),
 		},
 	})
@@ -451,44 +467,72 @@
 			simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_both") +
 			simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_both"),
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"copts":                       `["bothflag"]`,
-				"deps":                        `[":static_dep_for_both"]`,
-				"dynamic_deps":                `[":shared_dep_for_both"]`,
-				"implementation_deps":         `[":implementation_static_dep_for_both"]`,
-				"implementation_dynamic_deps": `[":implementation_shared_dep_for_both"]`,
-				"shared": `{
-        "copts": ["sharedflag"],
-        "deps": [":static_dep_for_shared"],
-        "dynamic_deps": [":shared_dep_for_shared"],
-        "implementation_deps": [":implementation_static_dep_for_shared"],
-        "implementation_dynamic_deps": [":implementation_shared_dep_for_shared"],
-        "srcs": ["sharedonly.cpp"],
-        "whole_archive_deps": [
-            ":not_explicitly_exported_whole_static_dep_for_shared",
-            ":whole_static_dep_for_shared",
-        ],
-    }`,
-				"srcs": `["both.cpp"]`,
-				"static": `{
-        "copts": ["staticflag"],
-        "deps": [":static_dep_for_static"],
-        "dynamic_deps": [":shared_dep_for_static"],
-        "implementation_deps": [":implementation_static_dep_for_static"],
-        "implementation_dynamic_deps": [":implementation_shared_dep_for_static"],
-        "srcs": ["staticonly.cpp"],
-        "whole_archive_deps": [
-            ":not_explicitly_exported_whole_static_dep_for_static",
-            ":whole_static_dep_for_static",
-        ],
-    }`,
+			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+				"copts": `[
+        "bothflag",
+        "staticflag",
+    ]`,
+				"deps": `[
+        ":static_dep_for_both",
+        ":static_dep_for_static",
+    ]`,
+				"dynamic_deps": `[
+        ":shared_dep_for_both",
+        ":shared_dep_for_static",
+    ]`,
+				"implementation_deps": `[
+        ":implementation_static_dep_for_both",
+        ":implementation_static_dep_for_static",
+    ]`,
+				"implementation_dynamic_deps": `[
+        ":implementation_shared_dep_for_both",
+        ":implementation_shared_dep_for_static",
+    ]`,
+				"srcs": `[
+        "both.cpp",
+        "staticonly.cpp",
+    ]`,
 				"whole_archive_deps": `[
         ":not_explicitly_exported_whole_static_dep_for_both",
         ":whole_static_dep_for_both",
+        ":not_explicitly_exported_whole_static_dep_for_static",
+        ":whole_static_dep_for_static",
     ]`,
 			}),
-		},
-	})
+			makeBazelTarget("cc_library_shared", "a", attrNameToString{
+				"copts": `[
+        "bothflag",
+        "sharedflag",
+    ]`,
+				"deps": `[
+        ":static_dep_for_both",
+        ":static_dep_for_shared",
+    ]`,
+				"dynamic_deps": `[
+        ":shared_dep_for_both",
+        ":shared_dep_for_shared",
+    ]`,
+				"implementation_deps": `[
+        ":implementation_static_dep_for_both",
+        ":implementation_static_dep_for_shared",
+    ]`,
+				"implementation_dynamic_deps": `[
+        ":implementation_shared_dep_for_both",
+        ":implementation_shared_dep_for_shared",
+    ]`,
+				"srcs": `[
+        "both.cpp",
+        "sharedonly.cpp",
+    ]`,
+				"whole_archive_deps": `[
+        ":not_explicitly_exported_whole_static_dep_for_both",
+        ":whole_static_dep_for_both",
+        ":not_explicitly_exported_whole_static_dep_for_shared",
+        ":whole_static_dep_for_shared",
+    ]`,
+			})},
+	},
+	)
 }
 
 func TestCcLibraryWholeStaticLibsAlwaysLink(t *testing.T) {
@@ -521,17 +565,21 @@
 		},
 		blueprint: soongCcLibraryPreamble,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"shared": `{
-        "whole_archive_deps": [":whole_static_lib_for_shared_alwayslink"],
-    }`,
-				"static": `{
-        "whole_archive_deps": [":whole_static_lib_for_static_alwayslink"],
-    }`,
-				"whole_archive_deps": `[":whole_static_lib_for_both_alwayslink"]`,
+			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+				"whole_archive_deps": `[
+        ":whole_static_lib_for_both_alwayslink",
+        ":whole_static_lib_for_static_alwayslink",
+    ]`,
+			}),
+			makeBazelTarget("cc_library_shared", "a", attrNameToString{
+				"whole_archive_deps": `[
+        ":whole_static_lib_for_both_alwayslink",
+        ":whole_static_lib_for_shared_alwayslink",
+    ]`,
 			}),
 		},
-	})
+	},
+	)
 }
 
 func TestCcLibrarySharedStaticPropsInArch(t *testing.T) {
@@ -612,62 +660,77 @@
 		},
 		blueprint: soongCcLibraryPreamble,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"copts":               `["bothflag"]`,
-				"implementation_deps": `[":static_dep_for_both"]`,
-				"local_includes":      `["."]`,
-				"shared": `{
-        "copts": ["sharedflag"] + select({
-            "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
-            "//conditions:default": [],
-        }) + select({
-            "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
-            "//conditions:default": [],
-        }) + select({
-            "//build/bazel/platforms/os_arch:android_arm": ["-DANDROID_ARM_SHARED"],
-            "//conditions:default": [],
-        }),
-        "implementation_deps": [":static_dep_for_shared"] + select({
-            "//build/bazel/platforms/arch:arm": [":arm_static_dep_for_shared"],
-            "//conditions:default": [],
-        }) + select({
-            "//build/bazel/platforms/os:android": [":android_dep_for_shared"],
-            "//conditions:default": [],
-        }),
-        "implementation_dynamic_deps": select({
-            "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
-            "//conditions:default": [],
-        }),
-        "srcs": ["sharedonly.cpp"] + select({
-            "//build/bazel/platforms/arch:arm": ["arm_shared.cpp"],
-            "//conditions:default": [],
-        }) + select({
-            "//build/bazel/platforms/os:android": ["android_shared.cpp"],
-            "//conditions:default": [],
-        }),
-        "whole_archive_deps": select({
-            "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
-            "//conditions:default": [],
-        }),
-    }`,
-				"srcs": `["both.cpp"]`,
-				"static": `{
-        "copts": ["staticflag"] + select({
-            "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
-            "//conditions:default": [],
-        }),
-        "implementation_deps": [":static_dep_for_static"] + select({
-            "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
-            "//conditions:default": [],
-        }),
-        "srcs": ["staticonly.cpp"] + select({
-            "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
-            "//conditions:default": [],
-        }),
-    }`,
+			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+				"copts": `[
+        "bothflag",
+        "staticflag",
+    ] + select({
+        "//build/bazel/platforms/arch:x86": ["-DX86_STATIC"],
+        "//conditions:default": [],
+    })`,
+				"implementation_deps": `[
+        ":static_dep_for_both",
+        ":static_dep_for_static",
+    ] + select({
+        "//build/bazel/platforms/arch:x86": [":x86_dep_for_static"],
+        "//conditions:default": [],
+    })`,
+				"local_includes": `["."]`,
+				"srcs": `[
+        "both.cpp",
+        "staticonly.cpp",
+    ] + select({
+        "//build/bazel/platforms/arch:x86": ["x86_static.cpp"],
+        "//conditions:default": [],
+    })`,
+			}),
+			makeBazelTarget("cc_library_shared", "a", attrNameToString{
+				"copts": `[
+        "bothflag",
+        "sharedflag",
+    ] + select({
+        "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
+        "//conditions:default": [],
+    }) + select({
+        "//build/bazel/platforms/os:android": ["-DANDROID_SHARED"],
+        "//conditions:default": [],
+    }) + select({
+        "//build/bazel/platforms/os_arch:android_arm": ["-DANDROID_ARM_SHARED"],
+        "//conditions:default": [],
+    })`,
+				"implementation_deps": `[
+        ":static_dep_for_both",
+        ":static_dep_for_shared",
+    ] + select({
+        "//build/bazel/platforms/arch:arm": [":arm_static_dep_for_shared"],
+        "//conditions:default": [],
+    }) + select({
+        "//build/bazel/platforms/os:android": [":android_dep_for_shared"],
+        "//conditions:default": [],
+    })`,
+				"implementation_dynamic_deps": `select({
+        "//build/bazel/platforms/arch:arm": [":arm_shared_dep_for_shared"],
+        "//conditions:default": [],
+    })`,
+				"local_includes": `["."]`,
+				"srcs": `[
+        "both.cpp",
+        "sharedonly.cpp",
+    ] + select({
+        "//build/bazel/platforms/arch:arm": ["arm_shared.cpp"],
+        "//conditions:default": [],
+    }) + select({
+        "//build/bazel/platforms/os:android": ["android_shared.cpp"],
+        "//conditions:default": [],
+    })`,
+				"whole_archive_deps": `select({
+        "//build/bazel/platforms/arch:arm": [":arm_whole_static_dep_for_shared"],
+        "//conditions:default": [],
+    })`,
 			}),
 		},
-	})
+	},
+	)
 }
 
 func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) {
@@ -751,57 +814,56 @@
 		},
 		blueprint: soongCcLibraryPreamble,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
+			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
 				"local_includes": `["."]`,
-				"shared": `{
-        "srcs": [
-            "shared_source.cpp",
-            "shared_source.cc",
-            ":shared_filegroup_cpp_srcs",
-        ],
-        "srcs_as": [
-            "shared_source.s",
-            "shared_source.S",
-            ":shared_filegroup_as_srcs",
-        ],
-        "srcs_c": [
-            "shared_source.c",
-            ":shared_filegroup_c_srcs",
-        ],
-    }`,
 				"srcs": `[
         "both_source.cpp",
         "both_source.cc",
         ":both_filegroup_cpp_srcs",
+        "static_source.cpp",
+        "static_source.cc",
+        ":static_filegroup_cpp_srcs",
     ]`,
 				"srcs_as": `[
         "both_source.s",
         "both_source.S",
         ":both_filegroup_as_srcs",
+        "static_source.s",
+        "static_source.S",
+        ":static_filegroup_as_srcs",
     ]`,
 				"srcs_c": `[
         "both_source.c",
         ":both_filegroup_c_srcs",
+        "static_source.c",
+        ":static_filegroup_c_srcs",
     ]`,
-				"static": `{
-        "srcs": [
-            "static_source.cpp",
-            "static_source.cc",
-            ":static_filegroup_cpp_srcs",
-        ],
-        "srcs_as": [
-            "static_source.s",
-            "static_source.S",
-            ":static_filegroup_as_srcs",
-        ],
-        "srcs_c": [
-            "static_source.c",
-            ":static_filegroup_c_srcs",
-        ],
-    }`,
 			}),
-		},
-	})
+			makeBazelTarget("cc_library_shared", "a", attrNameToString{
+				"local_includes": `["."]`,
+				"srcs": `[
+        "both_source.cpp",
+        "both_source.cc",
+        ":both_filegroup_cpp_srcs",
+        "shared_source.cpp",
+        "shared_source.cc",
+        ":shared_filegroup_cpp_srcs",
+    ]`,
+				"srcs_as": `[
+        "both_source.s",
+        "both_source.S",
+        ":both_filegroup_as_srcs",
+        "shared_source.s",
+        "shared_source.S",
+        ":shared_filegroup_as_srcs",
+    ]`,
+				"srcs_c": `[
+        "both_source.c",
+        ":both_filegroup_c_srcs",
+        "shared_source.c",
+        ":shared_filegroup_c_srcs",
+    ]`,
+			})}})
 }
 
 func TestCcLibraryNonConfiguredVersionScript(t *testing.T) {
@@ -823,14 +885,13 @@
 `,
 		},
 		blueprint: soongCcLibraryPreamble,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"additional_linker_inputs": `["v.map"]`,
-				"linkopts":                 `["-Wl,--version-script,$(location v.map)"]`,
-				"srcs":                     `["a.cpp"]`,
-			}),
-		},
-	})
+		expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+			"additional_linker_inputs": `["v.map"]`,
+			"linkopts":                 `["-Wl,--version-script,$(location v.map)"]`,
+			"srcs":                     `["a.cpp"]`,
+		}),
+	},
+	)
 }
 
 func TestCcLibraryConfiguredVersionScript(t *testing.T) {
@@ -860,22 +921,21 @@
     `,
 		},
 		blueprint: soongCcLibraryPreamble,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"additional_linker_inputs": `select({
+		expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+			"additional_linker_inputs": `select({
         "//build/bazel/platforms/arch:arm": ["arm.map"],
         "//build/bazel/platforms/arch:arm64": ["arm64.map"],
         "//conditions:default": [],
     })`,
-				"linkopts": `select({
+			"linkopts": `select({
         "//build/bazel/platforms/arch:arm": ["-Wl,--version-script,$(location arm.map)"],
         "//build/bazel/platforms/arch:arm64": ["-Wl,--version-script,$(location arm64.map)"],
         "//conditions:default": [],
     })`,
-				"srcs": `["a.cpp"]`,
-			}),
-		},
-	})
+			"srcs": `["a.cpp"]`,
+		}),
+	},
+	)
 }
 
 func TestCcLibrarySharedLibs(t *testing.T) {
@@ -896,15 +956,43 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"implementation_dynamic_deps": `[":mylib"]`,
-			}),
-		},
-	})
+		expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+			"implementation_dynamic_deps": `[":mylib"]`,
+		}),
+	},
+	)
 }
 
 func TestCcLibraryFeatures(t *testing.T) {
+	expected_targets := []string{}
+	expected_targets = append(expected_targets, makeCcLibraryTargets("a", attrNameToString{
+		"features": `[
+        "disable_pack_relocations",
+        "-no_undefined_symbols",
+    ]`,
+		"srcs": `["a.cpp"]`,
+	})...)
+	expected_targets = append(expected_targets, makeCcLibraryTargets("b", attrNameToString{
+		"features": `select({
+        "//build/bazel/platforms/arch:x86_64": [
+            "disable_pack_relocations",
+            "-no_undefined_symbols",
+        ],
+        "//conditions:default": [],
+    })`,
+		"srcs": `["b.cpp"]`,
+	})...)
+	expected_targets = append(expected_targets, makeCcLibraryTargets("c", attrNameToString{
+		"features": `select({
+        "//build/bazel/platforms/os:darwin": [
+            "disable_pack_relocations",
+            "-no_undefined_symbols",
+        ],
+        "//conditions:default": [],
+    })`,
+		"srcs": `["c.cpp"]`,
+	})...)
+
 	runCcLibraryTestCase(t, bp2buildTestCase{
 		description:                        "cc_library pack_relocations test",
 		moduleTypeUnderTest:                "cc_library",
@@ -942,33 +1030,7 @@
     },
     include_build_directory: false,
 }`,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"features": `[
-        "disable_pack_relocations",
-        "-no_undefined_symbols",
-    ]`,
-				"srcs": `["a.cpp"]`,
-			}), makeBazelTarget("cc_library", "b", attrNameToString{
-				"features": `select({
-        "//build/bazel/platforms/arch:x86_64": [
-            "disable_pack_relocations",
-            "-no_undefined_symbols",
-        ],
-        "//conditions:default": [],
-    })`,
-				"srcs": `["b.cpp"]`,
-			}), makeBazelTarget("cc_library", "c", attrNameToString{
-				"features": `select({
-        "//build/bazel/platforms/os:darwin": [
-            "disable_pack_relocations",
-            "-no_undefined_symbols",
-        ],
-        "//conditions:default": [],
-    })`,
-				"srcs": `["c.cpp"]`,
-			}),
-		},
+		expectedBazelTargets: expected_targets,
 	})
 }
 
@@ -985,15 +1047,14 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"copts": `[
+		expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+			"copts": `[
         "-include",
         "header.h",
     ]`,
-			}),
-		},
-	})
+		}),
+	},
+	)
 }
 
 func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
@@ -1023,10 +1084,9 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "a", attrNameToString{
-				"copts": `["-Wall"]`,
-				"cppflags": `[
+		expectedBazelTargets: makeCcLibraryTargets("a", attrNameToString{
+			"copts": `["-Wall"]`,
+			"cppflags": `[
         "-fsigned-char",
         "-pedantic",
     ] + select({
@@ -1036,10 +1096,10 @@
         "//build/bazel/platforms/os:android": ["-DANDROID=1"],
         "//conditions:default": [],
     })`,
-				"srcs": `["a.cpp"]`,
-			}),
-		},
-	})
+			"srcs": `["a.cpp"]`,
+		}),
+	},
+	)
 }
 
 func TestCcLibraryExcludeLibs(t *testing.T) {
@@ -1122,33 +1182,32 @@
     bazel_module: { bp2build_available: false },
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo_static", attrNameToString{
-				"implementation_deps": `select({
+		expectedBazelTargets: makeCcLibraryTargets("foo_static", attrNameToString{
+			"implementation_deps": `select({
         "//build/bazel/platforms/arch:arm": [],
         "//conditions:default": [":arm_static_lib_excludes_bp2build_cc_library_static"],
     }) + select({
         "//build/bazel/product_variables:malloc_not_svelte": [],
         "//conditions:default": [":malloc_not_svelte_static_lib_excludes_bp2build_cc_library_static"],
     })`,
-				"implementation_dynamic_deps": `select({
+			"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"],
         "//conditions:default": [],
     })`,
-				"srcs_c": `["common.c"]`,
-				"whole_archive_deps": `select({
+			"srcs_c": `["common.c"]`,
+			"whole_archive_deps": `select({
         "//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"],
         "//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes_bp2build_cc_library_static"],
     })`,
-			}),
-		},
-	})
+		}),
+	},
+	)
 }
 
 func TestCCLibraryNoCrtTrue(t *testing.T) {
@@ -1168,13 +1227,12 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo-lib", attrNameToString{
-				"link_crt": `False`,
-				"srcs":     `["impl.cpp"]`,
-			}),
-		},
-	})
+		expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+			"link_crt": `False`,
+			"srcs":     `["impl.cpp"]`,
+		}),
+	},
+	)
 }
 
 func TestCCLibraryNoCrtFalse(t *testing.T) {
@@ -1194,11 +1252,9 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo-lib", attrNameToString{
-				"srcs": `["impl.cpp"]`,
-			}),
-		},
+		expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+			"srcs": `["impl.cpp"]`,
+		}),
 	})
 }
 
@@ -1248,12 +1304,35 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo-lib", attrNameToString{
-				"srcs":       `["impl.cpp"]`,
-				"use_libcrt": `False`,
-			}),
-		}})
+		expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+			"srcs":       `["impl.cpp"]`,
+			"use_libcrt": `False`,
+		}),
+	})
+}
+
+func makeCcLibraryTargets(name string, attrs attrNameToString) []string {
+	STATIC_ONLY_ATTRS := map[string]bool{}
+	SHARED_ONLY_ATTRS := map[string]bool{
+		"link_crt":                 true,
+		"additional_linker_inputs": true,
+		"linkopts":                 true,
+		"strip":                    true,
+	}
+	sharedAttrs := attrNameToString{}
+	staticAttrs := attrNameToString{}
+	for key, val := range attrs {
+		if _, staticOnly := STATIC_ONLY_ATTRS[key]; !staticOnly {
+			sharedAttrs[key] = val
+		}
+		if _, sharedOnly := SHARED_ONLY_ATTRS[key]; !sharedOnly {
+			staticAttrs[key] = val
+		}
+	}
+	sharedTarget := makeBazelTarget("cc_library_shared", name, sharedAttrs)
+	staticTarget := makeBazelTarget("cc_library_static", name+"_bp2build_cc_library_static", staticAttrs)
+
+	return []string{staticTarget, sharedTarget}
 }
 
 func TestCCLibraryNoLibCrtFalse(t *testing.T) {
@@ -1273,12 +1352,11 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo-lib", attrNameToString{
-				"srcs":       `["impl.cpp"]`,
-				"use_libcrt": `True`,
-			}),
-		}})
+		expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+			"srcs":       `["impl.cpp"]`,
+			"use_libcrt": `True`,
+		}),
+	})
 }
 
 func TestCCLibraryNoLibCrtArchVariant(t *testing.T) {
@@ -1304,19 +1382,46 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo-lib", attrNameToString{
-				"srcs": `["impl.cpp"]`,
-				"use_libcrt": `select({
+		expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+			"srcs": `["impl.cpp"]`,
+			"use_libcrt": `select({
         "//build/bazel/platforms/arch:arm": False,
         "//build/bazel/platforms/arch:x86": False,
         "//conditions:default": None,
     })`,
-			}),
-		}})
+		}),
+	})
 }
 
 func TestCcLibraryStrip(t *testing.T) {
+	expectedTargets := []string{}
+	expectedTargets = append(expectedTargets, makeCcLibraryTargets("all", attrNameToString{
+		"strip": `{
+        "all": True,
+    }`,
+	})...)
+	expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols", attrNameToString{
+		"strip": `{
+        "keep_symbols": True,
+    }`,
+	})...)
+	expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols_and_debug_frame", attrNameToString{
+		"strip": `{
+        "keep_symbols_and_debug_frame": True,
+    }`,
+	})...)
+	expectedTargets = append(expectedTargets, makeCcLibraryTargets("keep_symbols_list", attrNameToString{
+		"strip": `{
+        "keep_symbols_list": ["symbol"],
+    }`,
+	})...)
+	expectedTargets = append(expectedTargets, makeCcLibraryTargets("none", attrNameToString{
+		"strip": `{
+        "none": True,
+    }`,
+	})...)
+	expectedTargets = append(expectedTargets, makeCcLibraryTargets("nothing", attrNameToString{})...)
+
 	runCcLibraryTestCase(t, bp2buildTestCase{
 		description:                        "cc_library strip args",
 		moduleTypeUnderTest:                "cc_library",
@@ -1363,29 +1468,7 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "all", attrNameToString{
-				"strip": `{
-        "all": True,
-    }`,
-			}), makeBazelTarget("cc_library", "keep_symbols", attrNameToString{
-				"strip": `{
-        "keep_symbols": True,
-    }`,
-			}), makeBazelTarget("cc_library", "keep_symbols_and_debug_frame", attrNameToString{
-				"strip": `{
-        "keep_symbols_and_debug_frame": True,
-    }`,
-			}), makeBazelTarget("cc_library", "keep_symbols_list", attrNameToString{
-				"strip": `{
-        "keep_symbols_list": ["symbol"],
-    }`,
-			}), makeBazelTarget("cc_library", "none", attrNameToString{
-				"strip": `{
-        "none": True,
-    }`,
-			}), makeBazelTarget("cc_library", "nothing", attrNameToString{}),
-		},
+		expectedBazelTargets: expectedTargets,
 	})
 }
 
@@ -1420,9 +1503,8 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "multi-arch", attrNameToString{
-				"strip": `{
+		expectedBazelTargets: makeCcLibraryTargets("multi-arch", attrNameToString{
+			"strip": `{
         "keep_symbols": select({
             "//build/bazel/platforms/arch:arm64": True,
             "//conditions:default": None,
@@ -1439,9 +1521,9 @@
             "//conditions:default": [],
         }),
     }`,
-			}),
-		},
-	})
+		}),
+	},
+	)
 }
 
 func TestCcLibrary_SystemSharedLibsRootEmpty(t *testing.T) {
@@ -1457,12 +1539,11 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "root_empty", attrNameToString{
-				"system_dynamic_deps": `[]`,
-			}),
-		},
-	})
+		expectedBazelTargets: makeCcLibraryTargets("root_empty", attrNameToString{
+			"system_dynamic_deps": `[]`,
+		}),
+	},
+	)
 }
 
 func TestCcLibrary_SystemSharedLibsStaticEmpty(t *testing.T) {
@@ -1481,11 +1562,10 @@
 }
 `,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "static_empty", attrNameToString{
-				"static": `{
-        "system_dynamic_deps": [],
-    }`,
+			makeBazelTarget("cc_library_static", "static_empty_bp2build_cc_library_static", attrNameToString{
+				"system_dynamic_deps": "[]",
 			}),
+			makeBazelTarget("cc_library_shared", "static_empty", attrNameToString{}),
 		},
 	})
 }
@@ -1506,10 +1586,9 @@
 }
 `,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "shared_empty", attrNameToString{
-				"shared": `{
-        "system_dynamic_deps": [],
-    }`,
+			makeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", attrNameToString{}),
+			makeBazelTarget("cc_library_shared", "shared_empty", attrNameToString{
+				"system_dynamic_deps": "[]",
 			}),
 		},
 	})
@@ -1535,10 +1614,9 @@
 }
 `,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "shared_empty", attrNameToString{
-				"shared": `{
-        "system_dynamic_deps": [],
-    }`,
+			makeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", attrNameToString{}),
+			makeBazelTarget("cc_library_shared", "shared_empty", attrNameToString{
+				"system_dynamic_deps": "[]",
 			}),
 		},
 	})
@@ -1565,12 +1643,11 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "target_linux_bionic_empty", attrNameToString{
-				"system_dynamic_deps": `[]`,
-			}),
-		},
-	})
+		expectedBazelTargets: makeCcLibraryTargets("target_linux_bionic_empty", attrNameToString{
+			"system_dynamic_deps": `[]`,
+		}),
+	},
+	)
 }
 
 func TestCcLibrary_SystemSharedLibsBionicEmpty(t *testing.T) {
@@ -1590,12 +1667,11 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "target_bionic_empty", attrNameToString{
-				"system_dynamic_deps": `[]`,
-			}),
-		},
-	})
+		expectedBazelTargets: makeCcLibraryTargets("target_bionic_empty", attrNameToString{
+			"system_dynamic_deps": `[]`,
+		}),
+	},
+	)
 }
 
 func TestCcLibrary_SystemSharedLibsSharedAndRoot(t *testing.T) {
@@ -1624,12 +1700,15 @@
 }
 `,
 		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo", attrNameToString{
-				"shared": `{
-        "system_dynamic_deps": [":libm"],
-    }`,
+			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
 				"system_dynamic_deps": `[":libc"]`,
 			}),
+			makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"system_dynamic_deps": `[
+        ":libc",
+        ":libm",
+    ]`,
+			}),
 		},
 	})
 }
@@ -1672,9 +1751,8 @@
     include_build_directory: false,
 }
 `,
-		expectedBazelTargets: []string{
-			makeBazelTarget("cc_library", "foo-lib", attrNameToString{
-				"srcs": `["base.cpp"] + select({
+		expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+			"srcs": `["base.cpp"] + select({
         "//build/bazel/platforms/os:android": [
             "linux.cpp",
             "bionic.cpp",
@@ -1696,9 +1774,9 @@
         "//build/bazel/platforms/os:windows": ["windows.cpp"],
         "//conditions:default": [],
     })`,
-			}),
-		},
-	})
+		}),
+	},
+	)
 }
 
 func TestCcLibraryCppStdWithGnuExtensions_ConvertsToFeatureAttr(t *testing.T) {
@@ -1796,9 +1874,7 @@
 	include_build_directory: false,
 }
 `, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
-			expectedBazelTargets: []string{
-				makeBazelTarget("cc_library", name_prefix+"_full", attrs),
-			},
+			expectedBazelTargets: makeCcLibraryTargets(name_prefix+"_full", attrs),
 		})
 
 		runCcLibraryStaticTestCase(t, bp2buildTestCase{
@@ -1859,14 +1935,11 @@
 				"strip_import_prefix": `""`,
 			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library", "foo", attrNameToString{
+			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
-				"shared": `{
-        "dynamic_deps": [":libprotobuf-cpp-lite"],
-    }`,
-				"static": `{
-        "deps": [":libprotobuf-cpp-lite"],
-    }`,
+				"deps":                              `[":libprotobuf-cpp-lite"]`,
+			}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
 	})
@@ -1888,14 +1961,11 @@
 				"srcs": `["foo.proto"]`,
 			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library", "foo", attrNameToString{
+			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
-				"shared": `{
-        "dynamic_deps": [":libprotobuf-cpp-lite"],
-    }`,
-				"static": `{
-        "deps": [":libprotobuf-cpp-lite"],
-    }`,
+				"deps":                              `[":libprotobuf-cpp-lite"]`,
+			}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
 	})
@@ -1918,14 +1988,11 @@
 				"strip_import_prefix": `""`,
 			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library", "foo", attrNameToString{
+			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
-				"shared": `{
-        "dynamic_deps": [":libprotobuf-cpp-lite"],
-    }`,
-				"static": `{
-        "deps": [":libprotobuf-cpp-lite"],
-    }`,
+				"deps":                              `[":libprotobuf-cpp-lite"]`,
+			}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
 	})
@@ -1950,14 +2017,11 @@
 				"srcs": `["foo.proto"]`,
 			}), makeBazelTarget("cc_proto_library", "foo_cc_proto", attrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library", "foo", attrNameToString{
+			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto"]`,
-				"shared": `{
-        "dynamic_deps": [":libprotobuf-cpp-full"],
-    }`,
-				"static": `{
-        "deps": [":libprotobuf-cpp-full"],
-    }`,
+				"deps":                              `[":libprotobuf-cpp-full"]`,
+			}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"dynamic_deps": `[":libprotobuf-cpp-full"]`,
 			}),
 		},
 	})
@@ -1982,14 +2046,11 @@
 				"srcs": `["foo.proto"]`,
 			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library", "foo", attrNameToString{
+			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
-				"shared": `{
-        "dynamic_deps": [":libprotobuf-cpp-lite"],
-    }`,
-				"static": `{
-        "deps": [":libprotobuf-cpp-lite"],
-    }`,
+				"deps":                              `[":libprotobuf-cpp-lite"]`,
+			}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
 	})
@@ -2014,14 +2075,12 @@
 				"srcs": `["foo.proto"]`,
 			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", attrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library", "foo", attrNameToString{
+			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+				"deps":               `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
-				"shared": `{
-        "dynamic_deps": [":libprotobuf-cpp-lite"],
-    }`,
-				"static": `{
-        "deps": [":libprotobuf-cpp-lite"],
-    }`,
+			}), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
+				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
 			}),
 		},
 	})
diff --git a/cc/binary.go b/cc/binary.go
index 63657e4..0650bdf 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -412,6 +412,7 @@
 		linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
 		linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
 		linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
+		linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
 	}
 
 	validations = append(validations, objs.tidyFiles...)
diff --git a/cc/builder.go b/cc/builder.go
index fea65d5..72c2fa5 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -549,10 +549,6 @@
 		return "$" + kind + n
 	}
 
-	// clang-tidy checks source files and does not need to link with libraries.
-	// tidyPathDeps should contain pathDeps but not libraries.
-	tidyPathDeps := skipNdkLibraryDeps(ctx, pathDeps)
-
 	for i, srcFile := range srcFiles {
 		objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
 
@@ -676,7 +672,7 @@
 				Output:      tidyFile,
 				Input:       srcFile,
 				Implicits:   cFlagsDeps,
-				OrderOnly:   tidyPathDeps,
+				OrderOnly:   pathDeps,
 				Args: map[string]string{
 					"ccCmd":     ccCmd,
 					"cFlags":    shareFlags("cFlags", escapeSingleQuotes(moduleToolingFlags)),
diff --git a/cc/cc.go b/cc/cc.go
index 113620c..aeb342f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1713,7 +1713,15 @@
 
 // Returns true if Bazel was successfully used for the analysis of this module.
 func (c *Module) maybeGenerateBazelActions(actx android.ModuleContext) bool {
-	bazelModuleLabel := c.GetBazelLabel(actx, c)
+	var bazelModuleLabel string
+	if actx.ModuleType() == "cc_library" && c.static() {
+		// cc_library is a special case in bp2build; two targets are generated -- one for each
+		// of the shared and static variants. The shared variant keeps the module name, but the
+		// static variant uses a different suffixed name.
+		bazelModuleLabel = bazelLabelForStaticModule(actx, c)
+	} else {
+		bazelModuleLabel = c.GetBazelLabel(actx, c)
+	}
 	bazelActionsUsed := false
 	// Mixed builds mode is disabled for modules outside of device OS.
 	// TODO(b/200841190): Support non-device OS in mixed builds.
diff --git a/cc/compiler.go b/cc/compiler.go
index 2e62b00..8adc3ab 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -637,9 +637,9 @@
 
 func ndkPathDeps(ctx ModuleContext) android.Paths {
 	if ctx.Module().(*Module).IsSdkVariant() {
-		// The NDK sysroot timestamp file depends on all the NDK sysroot files
-		// (headers and libraries).
-		return android.Paths{getNdkBaseTimestampFile(ctx)}
+		// The NDK sysroot timestamp file depends on all the NDK sysroot header files
+		// for compiling src to obj files.
+		return android.Paths{getNdkHeadersTimestampFile(ctx)}
 	}
 	return nil
 }
diff --git a/cc/config/global.go b/cc/config/global.go
index 0b229be..a340e46 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -46,7 +46,6 @@
 
 		"-O2",
 		"-g",
-		"-fdebug-info-for-profiling",
 
 		"-fno-strict-aliasing",
 
@@ -125,6 +124,9 @@
 		"-Werror=sequence-point",
 		"-Werror=format-security",
 		"-nostdlibinc",
+
+		// Emit additional debug info for AutoFDO
+		"-fdebug-info-for-profiling",
 	}
 
 	deviceGlobalCppflags = []string{
diff --git a/cc/library.go b/cc/library.go
index 84aae0d..e53aac0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -313,35 +313,74 @@
 		asFlags = bazel.MakeStringListAttribute(nil)
 	}
 
-	attrs := &bazelCcLibraryAttributes{
-		Srcs:    srcs,
-		Srcs_c:  compilerAttrs.cSrcs,
-		Srcs_as: compilerAttrs.asSrcs,
-		Hdrs:    compilerAttrs.hdrs,
+	staticCommonAttrs := staticOrSharedAttributes{
+		Srcs:    *srcs.Clone().Append(staticAttrs.Srcs),
+		Srcs_c:  *compilerAttrs.cSrcs.Clone().Append(staticAttrs.Srcs_c),
+		Srcs_as: *compilerAttrs.asSrcs.Clone().Append(staticAttrs.Srcs_as),
+		Copts:   *compilerAttrs.copts.Clone().Append(staticAttrs.Copts),
+		Hdrs:    *compilerAttrs.hdrs.Clone().Append(staticAttrs.Hdrs),
 
-		Copts:      compilerAttrs.copts,
+		Deps:                              *linkerAttrs.deps.Clone().Append(staticAttrs.Deps),
+		Implementation_deps:               *linkerAttrs.implementationDeps.Clone().Append(staticAttrs.Implementation_deps),
+		Dynamic_deps:                      *linkerAttrs.dynamicDeps.Clone().Append(staticAttrs.Dynamic_deps),
+		Implementation_dynamic_deps:       *linkerAttrs.implementationDynamicDeps.Clone().Append(staticAttrs.Implementation_dynamic_deps),
+		Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps,
+		Whole_archive_deps:                *linkerAttrs.wholeArchiveDeps.Clone().Append(staticAttrs.Whole_archive_deps),
+		System_dynamic_deps:               *linkerAttrs.systemDynamicDeps.Clone().Append(staticAttrs.System_dynamic_deps),
+	}
+
+	sharedCommonAttrs := staticOrSharedAttributes{
+		Srcs:    *srcs.Clone().Append(sharedAttrs.Srcs),
+		Srcs_c:  *compilerAttrs.cSrcs.Clone().Append(sharedAttrs.Srcs_c),
+		Srcs_as: *compilerAttrs.asSrcs.Clone().Append(sharedAttrs.Srcs_as),
+		Copts:   *compilerAttrs.copts.Clone().Append(sharedAttrs.Copts),
+		Hdrs:    *compilerAttrs.hdrs.Clone().Append(sharedAttrs.Hdrs),
+
+		Deps:                        *linkerAttrs.deps.Clone().Append(sharedAttrs.Deps),
+		Implementation_deps:         *linkerAttrs.implementationDeps.Clone().Append(sharedAttrs.Implementation_deps),
+		Dynamic_deps:                *linkerAttrs.dynamicDeps.Clone().Append(sharedAttrs.Dynamic_deps),
+		Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(sharedAttrs.Implementation_dynamic_deps),
+		Whole_archive_deps:          *linkerAttrs.wholeArchiveDeps.Clone().Append(sharedAttrs.Whole_archive_deps),
+		System_dynamic_deps:         *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps),
+	}
+
+	staticTargetAttrs := &bazelCcLibraryStaticAttributes{
+		staticOrSharedAttributes: staticCommonAttrs,
+
 		Cppflags:   compilerAttrs.cppFlags,
 		Conlyflags: compilerAttrs.conlyFlags,
 		Asflags:    asFlags,
 
-		Implementation_deps:               linkerAttrs.implementationDeps,
-		Deps:                              linkerAttrs.deps,
-		Implementation_dynamic_deps:       linkerAttrs.implementationDynamicDeps,
-		Dynamic_deps:                      linkerAttrs.dynamicDeps,
-		Whole_archive_deps:                linkerAttrs.wholeArchiveDeps,
-		Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps,
-		System_dynamic_deps:               linkerAttrs.systemDynamicDeps,
-		Export_includes:                   exportedIncludes.Includes,
-		Export_system_includes:            exportedIncludes.SystemIncludes,
-		Local_includes:                    compilerAttrs.localIncludes,
-		Absolute_includes:                 compilerAttrs.absoluteIncludes,
-		Linkopts:                          linkerAttrs.linkopts,
-		Link_crt:                          linkerAttrs.linkCrt,
-		Use_libcrt:                        linkerAttrs.useLibcrt,
-		Rtti:                              compilerAttrs.rtti,
-		Stl:                               compilerAttrs.stl,
-		Cpp_std:                           compilerAttrs.cppStd,
-		C_std:                             compilerAttrs.cStd,
+		Export_includes:        exportedIncludes.Includes,
+		Export_system_includes: exportedIncludes.SystemIncludes,
+		Local_includes:         compilerAttrs.localIncludes,
+		Absolute_includes:      compilerAttrs.absoluteIncludes,
+		Use_libcrt:             linkerAttrs.useLibcrt,
+		Rtti:                   compilerAttrs.rtti,
+		Stl:                    compilerAttrs.stl,
+		Cpp_std:                compilerAttrs.cppStd,
+		C_std:                  compilerAttrs.cStd,
+
+		Features: linkerAttrs.features,
+	}
+
+	sharedTargetAttrs := &bazelCcLibrarySharedAttributes{
+		staticOrSharedAttributes: sharedCommonAttrs,
+		Cppflags:                 compilerAttrs.cppFlags,
+		Conlyflags:               compilerAttrs.conlyFlags,
+		Asflags:                  asFlags,
+
+		Export_includes:        exportedIncludes.Includes,
+		Export_system_includes: exportedIncludes.SystemIncludes,
+		Local_includes:         compilerAttrs.localIncludes,
+		Absolute_includes:      compilerAttrs.absoluteIncludes,
+		Linkopts:               linkerAttrs.linkopts,
+		Link_crt:               linkerAttrs.linkCrt,
+		Use_libcrt:             linkerAttrs.useLibcrt,
+		Rtti:                   compilerAttrs.rtti,
+		Stl:                    compilerAttrs.stl,
+		Cpp_std:                compilerAttrs.cppStd,
+		C_std:                  compilerAttrs.cStd,
 
 		Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
 
@@ -352,20 +391,20 @@
 			All:                          linkerAttrs.stripAll,
 			None:                         linkerAttrs.stripNone,
 		},
-
-		Shared: sharedAttrs,
-
-		Static: staticAttrs,
-
 		Features: linkerAttrs.features,
 	}
 
-	props := bazel.BazelTargetModuleProperties{
-		Rule_class:        "cc_library",
-		Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl",
+	staticProps := bazel.BazelTargetModuleProperties{
+		Rule_class:        "cc_library_static",
+		Bzl_load_location: "//build/bazel/rules:cc_library_static.bzl",
+	}
+	sharedProps := bazel.BazelTargetModuleProperties{
+		Rule_class:        "cc_library_shared",
+		Bzl_load_location: "//build/bazel/rules:cc_library_shared.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+	ctx.CreateBazelTargetModule(staticProps, android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"}, staticTargetAttrs)
+	ctx.CreateBazelTargetModule(sharedProps, android.CommonAttributes{Name: m.Name()}, sharedTargetAttrs)
 }
 
 // cc_library creates both static and/or shared libraries for a device and/or
@@ -1327,11 +1366,21 @@
 	return outputFile
 }
 
+func ndkSharedLibDeps(ctx ModuleContext) android.Paths {
+	if ctx.Module().(*Module).IsSdkVariant() {
+		// The NDK sysroot timestamp file depends on all the NDK
+		// sysroot header and shared library files.
+		return android.Paths{getNdkBaseTimestampFile(ctx)}
+	}
+	return nil
+}
+
 func (library *libraryDecorator) linkShared(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 
 	var linkerDeps android.Paths
 	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
+	linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
 
 	unexportedSymbols := ctx.ExpandOptionalSource(library.Properties.Unexported_symbols_list, "unexported_symbols_list")
 	forceNotWeakSymbols := ctx.ExpandOptionalSource(library.Properties.Force_symbols_not_weak_list, "force_symbols_not_weak_list")
diff --git a/cc/library_test.go b/cc/library_test.go
index 7ddfaa7..7427b59 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -257,9 +257,14 @@
 				CcObjectFiles:        []string{"foo.o"},
 				Includes:             []string{"include"},
 				SystemIncludes:       []string{"system_include"},
-				RootStaticArchives:   []string{"foo.a"},
 				RootDynamicLibraries: []string{"foo.so"},
 			},
+			"//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
+				CcObjectFiles:      []string{"foo.o"},
+				Includes:           []string{"include"},
+				SystemIncludes:     []string{"system_include"},
+				RootStaticArchives: []string{"foo.a"},
+			},
 		},
 	}
 	ctx := testCcWithConfig(t, config)
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index ee11db1..6c200f5 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -94,21 +94,6 @@
 	return android.PathForOutput(ctx, "ndk.timestamp")
 }
 
-// Replace ndk_base.timestamp and ndk.timestamp with ndk_headers.timestamp.
-func skipNdkLibraryDeps(ctx android.ModuleContext, paths android.Paths) android.Paths {
-	var newPaths android.Paths
-	baseTimestamp := getNdkBaseTimestampFile(ctx)
-	fullTimestamp := getNdkFullTimestampFile(ctx)
-	headersTimestamp := getNdkHeadersTimestampFile(ctx)
-	for _, path := range paths {
-		if path == baseTimestamp || path == fullTimestamp {
-			path = headersTimestamp
-		}
-		newPaths = append(newPaths, path)
-	}
-	return newPaths
-}
-
 func NdkSingleton() android.Singleton {
 	return &ndkSingleton{}
 }
diff --git a/cc/pgo.go b/cc/pgo.go
index e78549e..cd017c4 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -96,10 +96,6 @@
 	flags.Local.LdFlags = append(flags.Local.LdFlags, profileInstrumentFlag)
 	return flags
 }
-func (props *PgoProperties) addSamplingProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
-	flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...)
-	return flags
-}
 
 func (props *PgoProperties) getPgoProfileFile(ctx BaseModuleContext) android.OptionalPath {
 	profileFile := *props.Pgo.Profile_file
@@ -313,10 +309,6 @@
 	if (props.ShouldProfileModule && props.isInstrumentation()) || props.PgoInstrLink {
 		// Instrumentation PGO use and gather flags cannot coexist.
 		return props.addInstrumentationProfileGatherFlags(ctx, flags)
-	} else if props.ShouldProfileModule && props.isSampling() {
-		flags = props.addSamplingProfileGatherFlags(ctx, flags)
-	} else if ctx.DeviceConfig().SamplingPGO() {
-		flags = props.addSamplingProfileGatherFlags(ctx, flags)
 	}
 
 	if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") {
diff --git a/dexpreopt/testing.go b/dexpreopt/testing.go
index 2fba01a..5131cd3 100644
--- a/dexpreopt/testing.go
+++ b/dexpreopt/testing.go
@@ -85,12 +85,12 @@
 // Prepares a test fixture by enabling dexpreopt, registering the fake_tool_binary module type and
 // using that to define the `dex2oatd` module.
 var PrepareForTestByEnablingDexpreopt = android.GroupFixturePreparers(
-	FixtureModifyGlobalConfig(func(*GlobalConfig) {}),
+	FixtureModifyGlobalConfig(func(android.PathContext, *GlobalConfig) {}),
 )
 
 // FixtureModifyGlobalConfig enables dexpreopt (unless modified by the mutator) and modifies the
 // configuration.
-func FixtureModifyGlobalConfig(configModifier func(dexpreoptConfig *GlobalConfig)) android.FixturePreparer {
+func FixtureModifyGlobalConfig(configModifier func(ctx android.PathContext, dexpreoptConfig *GlobalConfig)) android.FixturePreparer {
 	return android.FixtureModifyConfig(func(config android.Config) {
 		// Initialize the dexpreopt GlobalConfig to an empty structure. This has no effect if it has
 		// already been set.
@@ -100,48 +100,48 @@
 
 		// Retrieve the existing configuration and modify it.
 		dexpreoptConfig = GetGlobalConfig(pathCtx)
-		configModifier(dexpreoptConfig)
+		configModifier(pathCtx, dexpreoptConfig)
 	})
 }
 
 // FixtureSetArtBootJars enables dexpreopt and sets the ArtApexJars property.
 func FixtureSetArtBootJars(bootJars ...string) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.ArtApexJars = android.CreateTestConfiguredJarList(bootJars)
 	})
 }
 
 // FixtureSetBootJars enables dexpreopt and sets the BootJars property.
 func FixtureSetBootJars(bootJars ...string) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.BootJars = android.CreateTestConfiguredJarList(bootJars)
 	})
 }
 
 // FixtureSetApexBootJars sets the ApexBootJars property in the global config.
 func FixtureSetApexBootJars(bootJars ...string) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.ApexBootJars = android.CreateTestConfiguredJarList(bootJars)
 	})
 }
 
 // FixtureSetStandaloneSystemServerJars sets the StandaloneSystemServerJars property.
 func FixtureSetStandaloneSystemServerJars(jars ...string) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(jars)
 	})
 }
 
 // FixtureSetSystemServerJars sets the SystemServerJars property.
 func FixtureSetSystemServerJars(jars ...string) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.SystemServerJars = android.CreateTestConfiguredJarList(jars)
 	})
 }
 
 // FixtureSetApexSystemServerJars sets the ApexSystemServerJars property in the global config.
 func FixtureSetApexSystemServerJars(jars ...string) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.ApexSystemServerJars = android.CreateTestConfiguredJarList(jars)
 	})
 }
@@ -149,14 +149,21 @@
 // FixtureSetApexStandaloneSystemServerJars sets the ApexStandaloneSystemServerJars property in the
 // global config.
 func FixtureSetApexStandaloneSystemServerJars(jars ...string) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(jars)
 	})
 }
 
 // FixtureSetPreoptWithUpdatableBcp sets the PreoptWithUpdatableBcp property in the global config.
 func FixtureSetPreoptWithUpdatableBcp(value bool) android.FixturePreparer {
-	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+	return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
 		dexpreoptConfig.PreoptWithUpdatableBcp = value
 	})
 }
+
+// FixtureSetBootImageProfiles sets the BootImageProfiles property in the global config.
+func FixtureSetBootImageProfiles(profiles ...string) android.FixturePreparer {
+	return FixtureModifyGlobalConfig(func(ctx android.PathContext, dexpreoptConfig *GlobalConfig) {
+		dexpreoptConfig.BootImageProfiles = android.PathsForSource(ctx, profiles)
+	})
+}
diff --git a/java/android_resources.go b/java/android_resources.go
index 6864ebb..8c5908f 100644
--- a/java/android_resources.go
+++ b/java/android_resources.go
@@ -43,7 +43,7 @@
 
 // androidResourceGlob returns the list of files in the given directory, using the standard
 // exclusion patterns for Android resources.
-func androidResourceGlob(ctx android.ModuleContext, dir android.Path) android.Paths {
+func androidResourceGlob(ctx android.EarlyModuleContext, dir android.Path) android.Paths {
 	return ctx.GlobFiles(filepath.Join(dir.String(), "**/*"), androidResourceIgnoreFilenames)
 }
 
diff --git a/java/app.go b/java/app.go
index bf76a50..b43e532 100755
--- a/java/app.go
+++ b/java/app.go
@@ -45,6 +45,7 @@
 	ctx.RegisterModuleType("override_android_test", OverrideAndroidTestModuleFactory)
 
 	android.RegisterBp2BuildMutator("android_app_certificate", AndroidAppCertificateBp2Build)
+	android.RegisterBp2BuildMutator("android_app", AppBp2Build)
 }
 
 // AndroidManifest.xml merging
@@ -139,6 +140,7 @@
 }
 
 type AndroidApp struct {
+	android.BazelModuleBase
 	Library
 	aapt
 	android.OverridableModuleBase
@@ -1438,3 +1440,47 @@
 
 	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
 }
+
+type bazelAndroidAppAttributes struct {
+	Srcs           bazel.LabelListAttribute
+	Manifest       bazel.Label
+	Custom_package *string
+	Resource_files bazel.LabelListAttribute
+}
+
+// AppBp2Build is used for android_app.
+func AppBp2Build(ctx android.TopDownMutatorContext) {
+	a, ok := ctx.Module().(*AndroidApp)
+	if !ok || !a.ConvertWithBp2build(ctx) {
+		return
+	}
+	if ctx.ModuleType() != "android_app" {
+		return
+	}
+
+	//TODO(b/209577426): Support multiple arch variants
+	srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Srcs, a.properties.Exclude_srcs))
+
+	manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
+
+	resourceFiles := bazel.LabelList{
+		Includes: []bazel.Label{},
+	}
+	for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
+		files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
+		resourceFiles.Includes = append(resourceFiles.Includes, files...)
+	}
+
+	attrs := &bazelAndroidAppAttributes{
+		Srcs:     srcs,
+		Manifest: android.BazelLabelForModuleSrcSingle(ctx, manifest),
+		// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
+		Custom_package: a.overridableAppProperties.Package_name,
+		Resource_files: bazel.MakeLabelListAttribute(resourceFiles),
+	}
+	props := bazel.BazelTargetModuleProperties{Rule_class: "android_binary",
+		Bzl_load_location: "@rules_android//rules:rules.bzl"}
+
+	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs)
+
+}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index bfa6838..df1e121 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -390,6 +390,13 @@
 	// Map from the base module name (without prebuilt_ prefix) of a fragment's contents module to the
 	// hidden API encoded dex jar path.
 	contentModuleDexJarPaths bootDexJarByModule
+
+	// Path to the image profile file on host (or empty, if profile is not generated).
+	profilePathOnHost android.Path
+
+	// Install path of the boot image profile if it needs to be installed in the APEX, or empty if not
+	// needed.
+	profileInstallPathInApex string
 }
 
 func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
@@ -418,6 +425,14 @@
 	}
 }
 
+func (i BootclasspathFragmentApexContentInfo) ProfilePathOnHost() android.Path {
+	return i.profilePathOnHost
+}
+
+func (i BootclasspathFragmentApexContentInfo) ProfileInstallPathInApex() string {
+	return i.profileInstallPathInApex
+}
+
 func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
 	tag := ctx.OtherModuleDependencyTag(dep)
 	if IsBootclasspathFragmentContentDepTag(tag) {
@@ -579,6 +594,8 @@
 
 	if imageConfig != nil {
 		info.modules = imageConfig.modules
+		info.profilePathOnHost = imageConfig.profilePathOnHost
+		info.profileInstallPathInApex = imageConfig.profileInstallPathInApex
 	}
 
 	info.bootImageFilesByArch = bootImageFilesByArch
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a722946..75083e8 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -256,6 +256,10 @@
 	// Subdirectory where the image files on device are installed.
 	installDirOnDevice string
 
+	// Install path of the boot image profile if it needs to be installed in the APEX, or empty if not
+	// needed.
+	profileInstallPathInApex string
+
 	// A list of (location, jar) pairs for the Java modules in this image.
 	modules android.ConfiguredJarList
 
@@ -272,6 +276,9 @@
 	// Rules which should be used in make to install the outputs.
 	profileInstalls android.RuleBuilderInstalls
 
+	// Path to the image profile file on host (or empty, if profile is not generated).
+	profilePathOnHost android.Path
+
 	// Target-dependent fields.
 	variants []*bootImageVariant
 }
@@ -769,11 +776,14 @@
 		FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps).
 		FlagWithOutput("--reference-profile-file=", profile)
 
-	rule.Install(profile, "/system/etc/boot-image.prof")
+	if image == defaultBootImageConfig(ctx) {
+		rule.Install(profile, "/system/etc/boot-image.prof")
+		image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
+	}
 
 	rule.Build("bootJarsProfile", "profile boot jars")
 
-	image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
+	image.profilePathOnHost = profile
 
 	return profile
 }
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 415a1d4..26c1105 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -56,22 +56,20 @@
 		artModules := global.ArtApexJars
 		frameworkModules := global.BootJars.RemoveList(artModules)
 
-		artDirOnHost := "apex/art_boot_images/javalib"
-		artDirOnDevice := "apex/com.android.art/javalib"
-		frameworkSubdir := "system/framework"
-
 		// ART config for the primary boot image in the ART apex.
 		// It includes the Core Libraries.
 		artCfg := bootImageConfig{
-			name:               artBootImageName,
-			stem:               "boot",
-			installDirOnHost:   artDirOnHost,
-			installDirOnDevice: artDirOnDevice,
-			modules:            artModules,
+			name:                     artBootImageName,
+			stem:                     "boot",
+			installDirOnHost:         "apex/art_boot_images/javalib",
+			installDirOnDevice:       "apex/com.android.art/javalib",
+			profileInstallPathInApex: "etc/boot-image.prof",
+			modules:                  artModules,
 		}
 
 		// Framework config for the boot image extension.
 		// It includes framework libraries and depends on the ART config.
+		frameworkSubdir := "system/framework"
 		frameworkCfg := bootImageConfig{
 			extends:            &artCfg,
 			name:               frameworkBootImageName,
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 15e5963..cade4d2 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -1111,10 +1111,8 @@
 	}
 
 	switch call.name {
-	case "filter":
+	case "filter", "filter-out":
 		return ctx.parseCompareFilterFuncResult(directive, call, value, isEq), true
-	case "filter-out":
-		return ctx.parseCompareFilterFuncResult(directive, call, value, !isEq), true
 	case "wildcard":
 		return ctx.parseCompareWildcardFuncResult(directive, call, value, !isEq), true
 	case "findstring":
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index dfdf274..fa33e75 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -390,6 +390,8 @@
 ifeq (,$(filter barbet coral%,$(TARGET_PRODUCT)))
 else ifneq (,$(filter barbet%,$(TARGET_PRODUCT)))
 endif
+ifeq (,$(filter-out sunfish_kasan, $(TARGET_PRODUCT)))
+endif
 `,
 		expected: `load("//build/make/core:product_config.rbc", "rblf")
 
@@ -409,6 +411,8 @@
     pass
   elif rblf.filter("barbet%", g["TARGET_PRODUCT"]):
     pass
+  if not rblf.filter_out("sunfish_kasan", g["TARGET_PRODUCT"]):
+    pass
 `,
 	},
 	{
diff --git a/rust/builder.go b/rust/builder.go
index 60b5926..a7efc28 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -216,6 +216,13 @@
 	// Suppress an implicit sysroot
 	rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
 
+	// Enable incremental compilation if requested by user
+	if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
+		incrementalPath := android.PathForOutput(ctx, "rustc").String()
+
+		rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath)
+	}
+
 	// Collect linker flags
 	linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
 	linkFlags = append(linkFlags, flags.LinkFlags...)
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index ff2af43..2dacdb5 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -40,6 +40,7 @@
 			}
 		`, apex, fragment)),
 		android.FixtureAddFile("frameworks/base/config/boot-profile.txt", nil),
+		android.FixtureAddFile("frameworks/base/config/boot-image-profile.txt", nil),
 		android.FixtureAddFile("build/soong/scripts/check_boot_jars/package_allowed_list.txt", nil),
 	)
 }
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 4ced722..ae9a2ce 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -153,7 +153,12 @@
 	return true, nil
 }
 
-func primaryBuilderInvocation(config Config, name string, output string, specificArgs []string) bootstrap.PrimaryBuilderInvocation {
+func primaryBuilderInvocation(
+	config Config,
+	name string,
+	output string,
+	specificArgs []string,
+	description string) bootstrap.PrimaryBuilderInvocation {
 	commonArgs := make([]string, 0, 0)
 
 	if !config.skipSoongTests {
@@ -178,9 +183,10 @@
 	allArgs = append(allArgs, "Android.bp")
 
 	return bootstrap.PrimaryBuilderInvocation{
-		Inputs:  []string{"Android.bp"},
-		Outputs: []string{output},
-		Args:    allArgs,
+		Inputs:      []string{"Android.bp"},
+		Outputs:     []string{output},
+		Args:        allArgs,
+		Description: description,
 	}
 }
 
@@ -232,7 +238,9 @@
 		config,
 		soongBuildTag,
 		config.SoongNinjaFile(),
-		mainSoongBuildExtraArgs)
+		mainSoongBuildExtraArgs,
+		fmt.Sprintf("analyzing Android.bp files and generating ninja file at %s", config.SoongNinjaFile()),
+	)
 
 	if config.bazelBuildMode() == mixedBuild {
 		// Mixed builds call Bazel from soong_build and they therefore need the
@@ -248,7 +256,9 @@
 		config.Bp2BuildMarkerFile(),
 		[]string{
 			"--bp2build_marker", config.Bp2BuildMarkerFile(),
-		})
+		},
+		fmt.Sprintf("converting Android.bp files to BUILD files at %s/bp2build", config.SoongOutDir()),
+	)
 
 	jsonModuleGraphInvocation := primaryBuilderInvocation(
 		config,
@@ -256,15 +266,20 @@
 		config.ModuleGraphFile(),
 		[]string{
 			"--module_graph_file", config.ModuleGraphFile(),
-		})
+		},
+		fmt.Sprintf("generating the Soong module graph at %s", config.ModuleGraphFile()),
+	)
 
+	queryviewDir := filepath.Join(config.SoongOutDir(), "queryview")
 	queryviewInvocation := primaryBuilderInvocation(
 		config,
 		queryviewTag,
 		config.QueryviewMarkerFile(),
 		[]string{
-			"--bazel_queryview_dir", filepath.Join(config.SoongOutDir(), "queryview"),
-		})
+			"--bazel_queryview_dir", queryviewDir,
+		},
+		fmt.Sprintf("generating the Soong module graph as a Bazel workspace at %s", queryviewDir),
+	)
 
 	soongDocsInvocation := primaryBuilderInvocation(
 		config,
@@ -272,7 +287,9 @@
 		config.SoongDocsHtml(),
 		[]string{
 			"--soong_docs", config.SoongDocsHtml(),
-		})
+		},
+		fmt.Sprintf("generating Soong docs at %s", config.SoongDocsHtml()),
+	)
 
 	globFiles := []string{
 		config.NamedGlobFile(soongBuildTag),