Merge "Enable aidl#generate_traces by default for some Java SDK kinds"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 3223b04..41a696f 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -37,8 +37,8 @@
 
 var (
 	Bp2buildDefaultConfig = Bp2BuildConfig{
-		"art/libartpalette":                     Bp2BuildDefaultTrueRecursively,
 		"art/libartbase":                        Bp2BuildDefaultTrueRecursively,
+		"art/libartpalette":                     Bp2BuildDefaultTrueRecursively,
 		"art/libdexfile":                        Bp2BuildDefaultTrueRecursively,
 		"art/libnativebridge":                   Bp2BuildDefaultTrueRecursively,
 		"art/runtime":                           Bp2BuildDefaultTrueRecursively,
@@ -134,11 +134,13 @@
 		"external/libjpeg-turbo":                 Bp2BuildDefaultTrueRecursively,
 		"external/libmpeg2":                      Bp2BuildDefaultTrueRecursively,
 		"external/libpng":                        Bp2BuildDefaultTrueRecursively,
+		"external/libvpx":                        Bp2BuildDefaultTrueRecursively,
 		"external/libyuv":                        Bp2BuildDefaultTrueRecursively,
 		"external/lz4/lib":                       Bp2BuildDefaultTrue,
 		"external/lzma/C":                        Bp2BuildDefaultTrueRecursively,
 		"external/mdnsresponder":                 Bp2BuildDefaultTrueRecursively,
 		"external/minijail":                      Bp2BuildDefaultTrueRecursively,
+		"external/openscreen":                    Bp2BuildDefaultTrueRecursively,
 		"external/pcre":                          Bp2BuildDefaultTrueRecursively,
 		"external/protobuf":                      Bp2BuildDefaultTrueRecursively,
 		"external/python/six":                    Bp2BuildDefaultTrueRecursively,
@@ -152,6 +154,7 @@
 		"external/zopfli":                        Bp2BuildDefaultTrueRecursively,
 		"external/zstd":                          Bp2BuildDefaultTrueRecursively,
 
+		"frameworks/av":                                      Bp2BuildDefaultTrue,
 		"frameworks/av/media/codecs":                         Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/liberror":                       Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/services/minijail":                    Bp2BuildDefaultTrueRecursively,
@@ -162,9 +165,6 @@
 		"frameworks/native/libs/adbd_auth":                   Bp2BuildDefaultTrueRecursively,
 		"frameworks/native/libs/arect":                       Bp2BuildDefaultTrueRecursively,
 		"frameworks/native/libs/math":                        Bp2BuildDefaultTrueRecursively,
-		"hardware/interfaces/common/aidl":                    Bp2BuildDefaultTrue,
-		"hardware/interfaces/graphics/common/aidl":           Bp2BuildDefaultTrue,
-		"hardware/interfaces/neuralnetworks/aidl":            Bp2BuildDefaultTrue,
 		"frameworks/native/libs/nativebase":                  Bp2BuildDefaultTrueRecursively,
 		"frameworks/native/opengl/tests/gl2_cameraeye":       Bp2BuildDefaultTrue,
 		"frameworks/native/opengl/tests/gl2_java":            Bp2BuildDefaultTrue,
@@ -174,6 +174,7 @@
 		"frameworks/proto_logging/stats/stats_log_api_gen":   Bp2BuildDefaultTrueRecursively,
 
 		"hardware/interfaces":                          Bp2BuildDefaultTrue,
+		"hardware/interfaces/common/aidl":              Bp2BuildDefaultTrue,
 		"hardware/interfaces/configstore/1.0":          Bp2BuildDefaultTrue,
 		"hardware/interfaces/configstore/1.1":          Bp2BuildDefaultTrue,
 		"hardware/interfaces/configstore/utils":        Bp2BuildDefaultTrue,
@@ -185,6 +186,7 @@
 		"hardware/interfaces/graphics/common/1.0":      Bp2BuildDefaultTrue,
 		"hardware/interfaces/graphics/common/1.1":      Bp2BuildDefaultTrue,
 		"hardware/interfaces/graphics/common/1.2":      Bp2BuildDefaultTrue,
+		"hardware/interfaces/graphics/common/aidl":     Bp2BuildDefaultTrue,
 		"hardware/interfaces/graphics/mapper/2.0":      Bp2BuildDefaultTrue,
 		"hardware/interfaces/graphics/mapper/2.1":      Bp2BuildDefaultTrue,
 		"hardware/interfaces/graphics/mapper/3.0":      Bp2BuildDefaultTrue,
@@ -199,6 +201,7 @@
 		"hardware/interfaces/neuralnetworks/1.1":       Bp2BuildDefaultTrue,
 		"hardware/interfaces/neuralnetworks/1.2":       Bp2BuildDefaultTrue,
 		"hardware/interfaces/neuralnetworks/1.3":       Bp2BuildDefaultTrue,
+		"hardware/interfaces/neuralnetworks/aidl":      Bp2BuildDefaultTrue,
 
 		"libnativehelper": Bp2BuildDefaultTrueRecursively,
 
@@ -219,6 +222,8 @@
 		"packages/screensavers/Basic":                      Bp2BuildDefaultTrue,
 		"packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321)
 
+		"platform_testing/tests/example": Bp2BuildDefaultTrueRecursively,
+
 		"prebuilts/clang/host/linux-x86":           Bp2BuildDefaultTrueRecursively,
 		"prebuilts/runtime/mainline/platform/sdk":  Bp2BuildDefaultTrueRecursively,
 		"prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue,
@@ -240,6 +245,7 @@
 		"system/core/libprocessgroup/cgrouprc":                   Bp2BuildDefaultTrue,
 		"system/core/libprocessgroup/cgrouprc_format":            Bp2BuildDefaultTrue,
 		"system/core/libsystem":                                  Bp2BuildDefaultTrueRecursively,
+		"system/core/libsysutils":                                Bp2BuildDefaultTrueRecursively,
 		"system/core/libutils":                                   Bp2BuildDefaultTrueRecursively,
 		"system/core/libvndksupport":                             Bp2BuildDefaultTrueRecursively,
 		"system/core/property_service/libpropertyinfoparser":     Bp2BuildDefaultTrueRecursively,
@@ -262,15 +268,17 @@
 		"system/libhwbinder":                                     Bp2BuildDefaultTrueRecursively,
 		"system/libprocinfo":                                     Bp2BuildDefaultTrue,
 		"system/libziparchive":                                   Bp2BuildDefaultTrueRecursively,
-		"system/logging/liblog":                                  Bp2BuildDefaultTrueRecursively,
+		"system/logging":                                         Bp2BuildDefaultTrueRecursively,
 		"system/media/audio":                                     Bp2BuildDefaultTrueRecursively,
 		"system/media/audio_utils":                               Bp2BuildDefaultTrueRecursively,
 		"system/memory/libion":                                   Bp2BuildDefaultTrueRecursively,
 		"system/memory/libmemunreachable":                        Bp2BuildDefaultTrueRecursively,
 		"system/sepolicy/apex":                                   Bp2BuildDefaultTrueRecursively,
+		"system/testing/gtest_extras":                            Bp2BuildDefaultTrueRecursively,
 		"system/timezone/apex":                                   Bp2BuildDefaultTrueRecursively,
 		"system/timezone/output_data":                            Bp2BuildDefaultTrueRecursively,
 		"system/tools/sysprop":                                   Bp2BuildDefaultTrue,
+		"system/tools/aidl/build/tests_bp2build":                 Bp2BuildDefaultTrue,
 		"system/unwinding/libunwindstack":                        Bp2BuildDefaultTrueRecursively,
 
 		"tools/apksig": Bp2BuildDefaultTrue,
@@ -432,25 +440,43 @@
 
 		// needed for aidl_interface's ndk backend
 		"libbinder_ndk",
+
+		"libusb",
+
+		// needed by liblogd
+		"ILogcatManagerService_aidl",
+		"libincremental_aidl-cpp",
+		"incremental_aidl",
+
+		//frameworks/native/cmds/cmd
+		"libcmd",
 	}
 
 	Bp2buildModuleTypeAlwaysConvertList = []string{
 		"linker_config",
 		"java_import",
 		"java_import_host",
+		"sysprop_library",
 		"aidl_interface_headers",
 	}
 
 	Bp2buildModuleDoNotConvertList = []string{
 		// cc bugs
-		"libactivitymanager_aidl",                   // TODO(b/207426160): Unsupported use of aidl sources (via Dactivity_manager_procstate_aidl) in a cc_library
-		"gen-kotlin-build-file.py",                  // TODO(b/198619163) module has same name as source
+		"libactivitymanager_aidl", // TODO(b/207426160): Unsupported use of aidl sources (via Dactivity_manager_procstate_aidl) in a cc_library
+
+		// TODO(b/198619163) module has same name as source
+		"logtagd.rc",
+
 		"libgtest_ndk_c++", "libgtest_main_ndk_c++", // TODO(b/201816222): Requires sdk_version support.
-		"linkerconfig", "mdnsd", // TODO(b/202876379): has arch-variant static_executable
+
+		// TODO(b/202876379): has arch-variant static_executable
+		"linkerconfig",
+		"mdnsd",
+		"libcutils_test_static",
+		"KernelLibcutilsTest",
+
 		"linker",                 // TODO(b/228316882): cc_binary uses link_crt
-		"libdebuggerd",           // TODO(b/228314770): support product variable-specific header_libs
 		"versioner",              // TODO(b/228313961):  depends on prebuilt shared library libclang-cpp_host as a shared library, which does not supply expected providers for a shared library
-		"libvpx",                 // TODO(b/240756936): Arm neon variant not supported
 		"art_libartbase_headers", // TODO(b/236268577): Header libraries do not support export_shared_libs_headers
 		"apexer_test",            // Requires aapt2
 		"apexer_test_host_tools",
@@ -503,7 +529,6 @@
 
 		// unconverted deps
 		"CarHTMLViewer",                                              // depends on unconverted modules android.car-stubs, car-ui-lib
-		"abb",                                                        // depends on unconverted modules: libcmd, libbinder
 		"adb",                                                        // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi
 		"android_icu4j_srcgen",                                       // depends on unconverted modules: currysrc
 		"android_icu4j_srcgen_binary",                                // depends on unconverted modules: android_icu4j_srcgen, currysrc
@@ -516,7 +541,6 @@
 		"generated_android_icu4j_resources",                          // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
 		"generated_android_icu4j_test_resources",                     // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
 		"host-libprotobuf-java-nano",                                 // b/220869005, depends on libprotobuf-java-nano
-		"libadb_host",                                                // depends on unconverted modules: AdbWinApi, libopenscreen-discovery, libopenscreen-platform-impl, libusb
 		"libapexutil",                                                // depends on unconverted modules: apex-info-list-tinyxml
 		"libart",                                                     // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support
 		"libart-runtime-gtest",                                       // depends on unconverted modules: libgtest_isolated, libart-compiler, libdexfile, libprofile, libartbase, libartbase-art-gtest
@@ -525,6 +549,7 @@
 		"libartbased-art-gtest",                                      // depends on unconverted modules: libgtest_isolated, libartd, libartd-compiler, libdexfiled, libprofiled
 		"libartd",                                                    // depends on unconverted modules: art_operator_srcs, libcpu_features, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfiled, libnativebridge, libnativeloader, libsigchain, libartbased, libprofiled, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api
 		"libartd-runtime-gtest",                                      // depends on unconverted modules: libgtest_isolated, libartd-compiler, libdexfiled, libprofiled, libartbased, libartbased-art-gtest
+		"libdebuggerd",                                               // depends on unconverted module: libdexfile
 		"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
@@ -548,30 +573,462 @@
 		"truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt
 		"truth-prebuilt",      // depends on unconverted modules: asm-7.0, guava
 
-		// b/215723302; awaiting tz{data,_version} to then rename targets conflicting with srcs
-		"tzdata",
-		"tz_version",
-
 		// '//bionic/libc:libc_bp2build_cc_library_static' is duplicated in the 'deps' attribute of rule
 		"toybox-static",
 
-		// Do not convert the following modules because of duplicate labels checking in Bazel.
-		// See b/241283350. They should be removed from this list once the bug is fixed.
-		"libartpalette",
-		"libartbase",
-		"libdexfile",
-		"libartbased",
-		"libdexfile_static",
-		"libartbase-testing",
-		"libartbased-testing",
-		"libdexfile_support",
-		"libunwindstack",
-		"libunwindstack_local",
-		"libfdtrack",
-		"libc_malloc_debug",
-		"libutilscallstack",
-		"libunwindstack_utils",
-		"unwind_for_offline",
+		// cc_test related.
+		// Failing host cc_tests
+		"memunreachable_unit_test",
+		"libprocinfo_test",
+		"ziparchive-tests",
+		"gtest_isolated_tests",
+		"libunwindstack_unit_test",
+		"task_profiles_test",
+		"power_tests", // failing test on server, but not on host
+
+		// reflect: call of reflect.Value.NumField on interface Value
+		// affects all cc_tests that depend on art_defaults
+		"libnativebridge-tests",
+		"libnativeloader_test",
+		"art_libnativebridge_cts_tests",
+		"art_standalone_libdexfile_external_tests",
+		"art_standalone_libdexfile_support_tests",
+		"libnativebridge-lazy-tests",
+		"libnativebridge-test-case",
+		"libnativebridge2-test-case",
+		"libnativebridge3-test-case",
+		"libnativebridge6-test-case",
+		"libnativebridge6prezygotefork",
+
+		// cc_test with unconverted deps, or are device-only (and not verified to pass yet)
+		"AMRWBEncTest",
+		"AmrnbDecoderTest",     // depends on unconverted modules: libaudioutils, libsndfile
+		"AmrnbEncoderTest",     // depends on unconverted modules: libaudioutils, libsndfile
+		"AmrwbDecoderTest",     // depends on unconverted modules: libsndfile, libaudioutils
+		"AmrwbEncoderTest",     // depends on unconverted modules: libaudioutils, libsndfile
+		"Mp3DecoderTest",       // depends on unconverted modules: libsndfile, libaudioutils
+		"Mpeg4H263DecoderTest", // depends on unconverted modules: libstagefright_foundation
+		"Mpeg4H263EncoderTest",
+		"avcdec",
+		"avcenc",
+		"bionic-benchmarks-tests",
+		"bionic-fortify-runtime-asan-test",
+		"bionic-stress-tests",
+		"bionic-unit-tests",
+		"bionic-unit-tests-glibc",
+		"bionic-unit-tests-static",
+		"boringssl_crypto_test",
+		"boringssl_ssl_test",
+		"cfi_test_helper",
+		"cfi_test_helper2",
+		"cintltst32",
+		"cintltst64",
+		"compare",
+		"cpuid",
+		"debuggerd_test", // depends on unconverted modules: libdebuggerd
+		"elftls_dlopen_ie_error_helper",
+		"exec_linker_helper",
+		"fastdeploy_test", // depends on unconverted modules: AdbWinApi, libadb_host, libandroidfw, libfastdeploy_host, libopenscreen-discovery, libopenscreen-platform-impl, libusb
+		"fdtrack_test",
+		"google-benchmark-test",
+		"googletest-param-test-test_ndk", // depends on unconverted modules: libgtest_ndk_c++
+		"gtest-typed-test_test",
+		"gtest-typed-test_test_ndk", // depends on unconverted modules: libgtest_ndk_c++, libgtest_main_ndk_c++
+		"gtest_ndk_tests",           // depends on unconverted modules: libgtest_ndk_c++, libgtest_main_ndk_c++
+		"gtest_ndk_tests_no_main",   // depends on unconverted modules: libgtest_ndk_c++
+		"gtest_prod_test_ndk",       // depends on unconverted modules: libgtest_ndk_c++, libgtest_main_ndk_c++
+		"gtest_tests",
+		"gtest_tests_no_main",
+		"gwp_asan_unittest",
+		"half_test",
+		"hashcombine_test",
+		"hevcdec",
+		"hevcenc",
+		"hwbinderThroughputTest", // depends on unconverted modules: android.hardware.tests.libhwbinder@1.0-impl.test, android.hardware.tests.libhwbinder@1.0
+		"i444tonv12_eg",
+		"icu4c_sample_break",
+		"intltest32",
+		"intltest64",
+		"ion-unit-tests",
+		"jemalloc5_integrationtests",
+		"jemalloc5_unittests",
+		"ld_config_test_helper",
+		"ld_preload_test_helper",
+		"libBionicCtsGtestMain", // depends on unconverted modules: libgtest_isolated
+		"libBionicLoaderTests",  // depends on unconverted modules: libmeminfo
+		"libapexutil_tests",     // depends on unconverted modules: apex-info-list-tinyxml, libapexutil
+		"libavservices_minijail_unittest",
+		"libcutils_sockets_test",
+		"libexpectedutils_test",
+		"libhwbinder_latency",
+		"liblog-host-test", // failing tests
+		"libminijail_test",
+		"libminijail_unittest_gtest",
+		"libpackagelistparser_test",
+		"libprotobuf_vendor_suffix_test",
+		"libstagefright_amrnbdec_test", // depends on unconverted modules: libsndfile, libaudioutils
+		"libstagefright_amrnbenc_test",
+		"libstagefright_amrwbdec_test", // depends on unconverted modules: libsndfile, libaudioutils
+		"libstagefright_m4vh263enc_test",
+		"libstagefright_mp3dec_test", // depends on unconverted modules: libsndfile, libaudioutils
+		"libstatssocket_test",
+		"libvndksupport-tests",
+		"libyuv_unittest",
+		"linker-unit-tests",
+		"malloc_debug_system_tests",
+		"malloc_debug_unit_tests",
+		"malloc_hooks_system_tests",
+		"mat_test",
+		"mathtest",
+		"memunreachable_binder_test", // depends on unconverted modules: libbinder
+		"memunreachable_test",
+		"metadata_tests",
+		"minijail0_cli_unittest_gtest",
+		"mpeg2dec",
+		"mvcdec",
+		"ns_hidden_child_helper",
+		"pngtest",
+		"preinit_getauxval_test_helper",
+		"preinit_syscall_test_helper",
+		"psnr",
+		"quat_test",
+		"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",
+		"sysprop_test", // depends on unconverted modules: libcom.android.sysprop.tests
+		"thread_exit_cb_helper",
+		"tls_properties_helper",
+		"ulp",
+		"vec_test",
+		"yuvconstants",
+		"yuvconvert",
+		"zipalign_tests",
+
+		// cc_test_library
+		"clang_diagnostic_tests",
+		"exec_linker_helper_lib",
+		"fortify_disabled_for_tidy",
+		"ld_config_test_helper_lib1",
+		"ld_config_test_helper_lib2",
+		"ld_config_test_helper_lib3",
+		"ld_preload_test_helper_lib1",
+		"ld_preload_test_helper_lib2",
+		"libBionicElfTlsLoaderTests",
+		"libBionicElfTlsTests",
+		"libBionicElfTlsTests",
+		"libBionicFramePointerTests",
+		"libBionicFramePointerTests",
+		"libBionicStandardTests",
+		"libBionicStandardTests",
+		"libBionicTests",
+		"libart-broken",
+		"libatest_simple_zip",
+		"libcfi-test",
+		"libcfi-test-bad",
+		"libcrash_test",
+		// "libcrypto_fuzz_unsafe",
+		"libdl_preempt_test_1",
+		"libdl_preempt_test_2",
+		"libdl_test_df_1_global",
+		"libdlext_test",
+		"libdlext_test_different_soname",
+		"libdlext_test_fd",
+		"libdlext_test_norelro",
+		"libdlext_test_recursive",
+		"libdlext_test_zip",
+		"libfortify1-new-tests-clang",
+		"libfortify1-new-tests-clang",
+		"libfortify1-tests-clang",
+		"libfortify1-tests-clang",
+		"libfortify2-new-tests-clang",
+		"libfortify2-new-tests-clang",
+		"libfortify2-tests-clang",
+		"libfortify2-tests-clang",
+		"libgnu-hash-table-library",
+		"libicutest_static",
+		"liblinker_reloc_bench_000",
+		"liblinker_reloc_bench_001",
+		"liblinker_reloc_bench_002",
+		"liblinker_reloc_bench_003",
+		"liblinker_reloc_bench_004",
+		"liblinker_reloc_bench_005",
+		"liblinker_reloc_bench_006",
+		"liblinker_reloc_bench_007",
+		"liblinker_reloc_bench_008",
+		"liblinker_reloc_bench_009",
+		"liblinker_reloc_bench_010",
+		"liblinker_reloc_bench_011",
+		"liblinker_reloc_bench_012",
+		"liblinker_reloc_bench_013",
+		"liblinker_reloc_bench_014",
+		"liblinker_reloc_bench_015",
+		"liblinker_reloc_bench_016",
+		"liblinker_reloc_bench_017",
+		"liblinker_reloc_bench_018",
+		"liblinker_reloc_bench_019",
+		"liblinker_reloc_bench_020",
+		"liblinker_reloc_bench_021",
+		"liblinker_reloc_bench_022",
+		"liblinker_reloc_bench_023",
+		"liblinker_reloc_bench_024",
+		"liblinker_reloc_bench_025",
+		"liblinker_reloc_bench_026",
+		"liblinker_reloc_bench_027",
+		"liblinker_reloc_bench_028",
+		"liblinker_reloc_bench_029",
+		"liblinker_reloc_bench_030",
+		"liblinker_reloc_bench_031",
+		"liblinker_reloc_bench_032",
+		"liblinker_reloc_bench_033",
+		"liblinker_reloc_bench_034",
+		"liblinker_reloc_bench_035",
+		"liblinker_reloc_bench_036",
+		"liblinker_reloc_bench_037",
+		"liblinker_reloc_bench_038",
+		"liblinker_reloc_bench_039",
+		"liblinker_reloc_bench_040",
+		"liblinker_reloc_bench_041",
+		"liblinker_reloc_bench_042",
+		"liblinker_reloc_bench_043",
+		"liblinker_reloc_bench_044",
+		"liblinker_reloc_bench_045",
+		"liblinker_reloc_bench_046",
+		"liblinker_reloc_bench_047",
+		"liblinker_reloc_bench_048",
+		"liblinker_reloc_bench_049",
+		"liblinker_reloc_bench_050",
+		"liblinker_reloc_bench_051",
+		"liblinker_reloc_bench_052",
+		"liblinker_reloc_bench_053",
+		"liblinker_reloc_bench_054",
+		"liblinker_reloc_bench_055",
+		"liblinker_reloc_bench_056",
+		"liblinker_reloc_bench_057",
+		"liblinker_reloc_bench_058",
+		"liblinker_reloc_bench_059",
+		"liblinker_reloc_bench_060",
+		"liblinker_reloc_bench_061",
+		"liblinker_reloc_bench_062",
+		"liblinker_reloc_bench_063",
+		"liblinker_reloc_bench_064",
+		"liblinker_reloc_bench_065",
+		"liblinker_reloc_bench_066",
+		"liblinker_reloc_bench_067",
+		"liblinker_reloc_bench_068",
+		"liblinker_reloc_bench_069",
+		"liblinker_reloc_bench_070",
+		"liblinker_reloc_bench_071",
+		"liblinker_reloc_bench_072",
+		"liblinker_reloc_bench_073",
+		"liblinker_reloc_bench_074",
+		"liblinker_reloc_bench_075",
+		"liblinker_reloc_bench_076",
+		"liblinker_reloc_bench_077",
+		"liblinker_reloc_bench_078",
+		"liblinker_reloc_bench_079",
+		"liblinker_reloc_bench_080",
+		"liblinker_reloc_bench_081",
+		"liblinker_reloc_bench_082",
+		"liblinker_reloc_bench_083",
+		"liblinker_reloc_bench_084",
+		"liblinker_reloc_bench_085",
+		"liblinker_reloc_bench_086",
+		"liblinker_reloc_bench_087",
+		"liblinker_reloc_bench_088",
+		"liblinker_reloc_bench_089",
+		"liblinker_reloc_bench_090",
+		"liblinker_reloc_bench_091",
+		"liblinker_reloc_bench_092",
+		"liblinker_reloc_bench_093",
+		"liblinker_reloc_bench_094",
+		"liblinker_reloc_bench_095",
+		"liblinker_reloc_bench_096",
+		"liblinker_reloc_bench_097",
+		"liblinker_reloc_bench_098",
+		"liblinker_reloc_bench_099",
+		"liblinker_reloc_bench_100",
+		"liblinker_reloc_bench_101",
+		"liblinker_reloc_bench_102",
+		"liblinker_reloc_bench_103",
+		"liblinker_reloc_bench_104",
+		"liblinker_reloc_bench_105",
+		"liblinker_reloc_bench_106",
+		"liblinker_reloc_bench_107",
+		"liblinker_reloc_bench_108",
+		"liblinker_reloc_bench_109",
+		"liblinker_reloc_bench_110",
+		"liblinker_reloc_bench_111",
+		"liblinker_reloc_bench_112",
+		"liblinker_reloc_bench_113",
+		"liblinker_reloc_bench_114",
+		"liblinker_reloc_bench_115",
+		"liblinker_reloc_bench_116",
+		"liblinker_reloc_bench_117",
+		"liblinker_reloc_bench_118",
+		"liblinker_reloc_bench_119",
+		"liblinker_reloc_bench_120",
+		"liblinker_reloc_bench_121",
+		"liblinker_reloc_bench_122",
+		"liblinker_reloc_bench_123",
+		"liblinker_reloc_bench_124",
+		"liblinker_reloc_bench_125",
+		"liblinker_reloc_bench_126",
+		"liblinker_reloc_bench_127",
+		"liblinker_reloc_bench_128",
+		"liblinker_reloc_bench_129",
+		"liblinker_reloc_bench_130",
+		"liblinker_reloc_bench_131",
+		"liblinker_reloc_bench_132",
+		"liblinker_reloc_bench_133",
+		"liblinker_reloc_bench_134",
+		"liblinker_reloc_bench_135",
+		"liblinker_reloc_bench_136",
+		"liblinker_reloc_bench_137",
+		"liblinker_reloc_bench_138",
+		"liblinker_reloc_bench_139",
+		"liblinker_reloc_bench_140",
+		"liblinker_reloc_bench_141",
+		"liblinker_reloc_bench_142",
+		"liblinker_reloc_bench_143",
+		"liblinker_reloc_bench_144",
+		"liblinker_reloc_bench_145",
+		"liblinker_reloc_bench_146",
+		"liblinker_reloc_bench_147",
+		"liblinker_reloc_bench_148",
+		"liblinker_reloc_bench_149",
+		"liblinker_reloc_bench_150",
+		"liblinker_reloc_bench_151",
+		"liblinker_reloc_bench_152",
+		"liblinker_reloc_bench_153",
+		"liblinker_reloc_bench_154",
+		"liblinker_reloc_bench_155",
+		"liblinker_reloc_bench_156",
+		"liblinker_reloc_bench_157",
+		"liblinker_reloc_bench_158",
+		"liblinker_reloc_bench_159",
+		"liblinker_reloc_bench_160",
+		"liblinker_reloc_bench_161",
+		"liblinker_reloc_bench_162",
+		"liblinker_reloc_bench_163",
+		"liblinker_reloc_bench_164",
+		"liblinker_reloc_bench_165",
+		"liblinker_reloc_bench_166",
+		"liblinker_reloc_bench_167",
+		"liblinker_reloc_bench_168",
+		"libns_hidden_child_app",
+		"libns_hidden_child_global",
+		"libns_hidden_child_internal",
+		"libns_hidden_child_public",
+		"libnstest_dlopened",
+		"libnstest_ns_a_public1",
+		"libnstest_ns_a_public1_internal",
+		"libnstest_ns_b_public2",
+		"libnstest_ns_b_public3",
+		"libnstest_private",
+		"libnstest_private_external",
+		"libnstest_public",
+		"libnstest_public_internal",
+		"libnstest_root",
+		"libnstest_root_not_isolated",
+		"librelocations-ANDROID_REL",
+		"librelocations-ANDROID_RELR",
+		"librelocations-RELR",
+		"librelocations-fat",
+		"libsegment_gap_inner",
+		"libsegment_gap_outer",
+		// "libssl_fuzz_unsafe",
+		"libstatssocket_private",
+		"libsysv-hash-table-library",
+		"libtest_atexit",
+		"libtest_check_order_dlsym",
+		"libtest_check_order_dlsym_1_left",
+		"libtest_check_order_dlsym_2_right",
+		"libtest_check_order_dlsym_3_c",
+		"libtest_check_order_dlsym_a",
+		"libtest_check_order_dlsym_b",
+		"libtest_check_order_dlsym_d",
+		"libtest_check_order_reloc_root",
+		"libtest_check_order_reloc_root_1",
+		"libtest_check_order_reloc_root_2",
+		"libtest_check_order_reloc_siblings",
+		"libtest_check_order_reloc_siblings_1",
+		"libtest_check_order_reloc_siblings_2",
+		"libtest_check_order_reloc_siblings_3",
+		"libtest_check_order_reloc_siblings_a",
+		"libtest_check_order_reloc_siblings_b",
+		"libtest_check_order_reloc_siblings_c",
+		"libtest_check_order_reloc_siblings_c_1",
+		"libtest_check_order_reloc_siblings_c_2",
+		"libtest_check_order_reloc_siblings_d",
+		"libtest_check_order_reloc_siblings_e",
+		"libtest_check_order_reloc_siblings_f",
+		"libtest_check_rtld_next_from_library",
+		"libtest_dlopen_df_1_global",
+		"libtest_dlopen_from_ctor",
+		"libtest_dlopen_from_ctor_main",
+		"libtest_dlopen_weak_undefined_func",
+		"libtest_dlsym_df_1_global",
+		"libtest_dlsym_from_this",
+		"libtest_dlsym_from_this_child",
+		"libtest_dlsym_from_this_grandchild",
+		"libtest_dlsym_weak_func",
+		"libtest_dt_runpath_a",
+		"libtest_dt_runpath_b",
+		"libtest_dt_runpath_c",
+		"libtest_dt_runpath_d",
+		"libtest_dt_runpath_d_zip",
+		"libtest_dt_runpath_x",
+		"libtest_dt_runpath_y",
+		"libtest_elftls_dynamic",
+		"libtest_elftls_dynamic_filler_1",
+		"libtest_elftls_dynamic_filler_2",
+		"libtest_elftls_dynamic_filler_3",
+		"libtest_elftls_shared_var",
+		"libtest_elftls_shared_var_ie",
+		"libtest_elftls_tprel",
+		"libtest_empty",
+		"libtest_ifunc",
+		"libtest_ifunc_variable",
+		"libtest_ifunc_variable_impl",
+		"libtest_indirect_thread_local_dtor",
+		"libtest_init_fini_order_child",
+		"libtest_init_fini_order_grand_child",
+		"libtest_init_fini_order_root",
+		"libtest_init_fini_order_root2",
+		"libtest_missing_symbol",
+		"libtest_missing_symbol_child_private",
+		"libtest_missing_symbol_child_public",
+		"libtest_missing_symbol_root",
+		"libtest_nodelete_1",
+		"libtest_nodelete_2",
+		"libtest_nodelete_dt_flags_1",
+		"libtest_pthread_atfork",
+		"libtest_relo_check_dt_needed_order",
+		"libtest_relo_check_dt_needed_order_1",
+		"libtest_relo_check_dt_needed_order_2",
+		"libtest_simple",
+		"libtest_thread_local_dtor",
+		"libtest_thread_local_dtor2",
+		"libtest_two_parents_child",
+		"libtest_two_parents_parent1",
+		"libtest_two_parents_parent2",
+		"libtest_versioned_lib",
+		"libtest_versioned_libv1",
+		"libtest_versioned_libv2",
+		"libtest_versioned_otherlib",
+		"libtest_versioned_otherlib_empty",
+		"libtest_versioned_uselibv1",
+		"libtest_versioned_uselibv2",
+		"libtest_versioned_uselibv2_other",
+		"libtest_versioned_uselibv3_other",
+		"libtest_with_dependency",
+		"libtest_with_dependency_loop",
+		"libtest_with_dependency_loop_a",
+		"libtest_with_dependency_loop_b",
+		"libtest_with_dependency_loop_b_tmp",
+		"libtest_with_dependency_loop_c",
+		"libtestshared",
 	}
 
 	Bp2buildCcLibraryStaticOnlyList = []string{}
@@ -623,7 +1080,6 @@
 	}
 
 	ProdMixedBuildsEnabledList = []string{
-		// This list left intentionally empty for now. Add specific module names
-		// to have them built by Bazel in Prod Mixed Builds mode.
+		"com.android.adbd",
 	}
 )
diff --git a/android/arch.go b/android/arch.go
index 1952b17..9bc9d89 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -19,6 +19,7 @@
 	"fmt"
 	"reflect"
 	"runtime"
+	"sort"
 	"strings"
 
 	"android/soong/bazel"
@@ -2084,13 +2085,22 @@
 	// For each arch type (x86, arm64, etc.)
 	for _, arch := range ArchTypeList() {
 		// Arch properties are sometimes sharded (see createArchPropTypeDesc() ).
-		// Iterate over ever shard and extract a struct with the same type as the
+		// Iterate over every shard and extract a struct with the same type as the
 		// input one that contains the data specific to that arch.
 		propertyStructs := make([]reflect.Value, 0)
+		archFeaturePropertyStructs := make(map[string][]reflect.Value, 0)
 		for _, archProperty := range archProperties {
 			archTypeStruct, ok := getArchTypeStruct(ctx, archProperty, arch)
 			if ok {
 				propertyStructs = append(propertyStructs, archTypeStruct)
+
+				// For each feature this arch supports (arm: neon, x86: ssse3, sse4, ...)
+				for _, feature := range archFeatures[arch] {
+					prefix := "arch." + arch.Name + "." + feature
+					if featureProperties, ok := getChildPropertyStruct(ctx, archTypeStruct, feature, prefix); ok {
+						archFeaturePropertyStructs[feature] = append(archFeaturePropertyStructs[feature], featureProperties)
+					}
+				}
 			}
 			multilibStruct, ok := getMultilibStruct(ctx, archProperty, arch)
 			if ok {
@@ -2098,10 +2108,31 @@
 			}
 		}
 
-		// Create a new instance of the requested property set
-		value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
+		archToProp[arch.Name] = mergeStructs(ctx, propertyStructs, propertySet)
 
-		archToProp[arch.Name] = mergeStructs(ctx, propertyStructs, value)
+		// In soong, if multiple features match the current configuration, they're
+		// all used. In bazel, we have to have unambiguous select() statements, so
+		// we can't have two features that are both active in the same select().
+		// One alternative is to split out each feature into a separate select(),
+		// but then it's difficult to support exclude_srcs, which may need to
+		// exclude things from the regular arch select() statement if a certain
+		// feature is active. Instead, keep the features in the same select
+		// statement as the arches, but emit the power set of all possible
+		// combinations of features, so that bazel can match the most precise one.
+		allFeatures := make([]string, 0, len(archFeaturePropertyStructs))
+		for feature := range archFeaturePropertyStructs {
+			allFeatures = append(allFeatures, feature)
+		}
+		for _, features := range bazel.PowerSetWithoutEmptySet(allFeatures) {
+			sort.Strings(features)
+			propsForCurrentFeatureSet := make([]reflect.Value, 0)
+			propsForCurrentFeatureSet = append(propsForCurrentFeatureSet, propertyStructs...)
+			for _, feature := range features {
+				propsForCurrentFeatureSet = append(propsForCurrentFeatureSet, archFeaturePropertyStructs[feature]...)
+			}
+			archToProp[arch.Name+"-"+strings.Join(features, "-")] =
+				mergeStructs(ctx, propsForCurrentFeatureSet, propertySet)
+		}
 	}
 	axisToProps[bazel.ArchConfigurationAxis] = archToProp
 
diff --git a/android/bazel.go b/android/bazel.go
index 27ec92b..eb6aca4 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -75,7 +75,7 @@
 
 // Properties contains common module properties for Bazel migration purposes.
 type properties struct {
-	// In USE_BAZEL_ANALYSIS=1 mode, this represents the Bazel target replacing
+	// In "Bazel mixed build" mode, this represents the Bazel target replacing
 	// this Soong module.
 	Bazel_module bazelModuleProperties
 }
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 93b6779..3e490dd 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -694,6 +694,31 @@
 	formatString := `
 # This file is generated by soong_build. Do not edit.
 
+# a drop-in replacement for json.encode(), not available in cquery environment
+# TODO(cparsons): bring json module in and remove this function
+def json_encode(input):
+  # Avoiding recursion by limiting
+  #  - a dict to contain anything except a dict
+  #  - a list to contain only primitives
+  def encode_primitive(p):
+    t = type(p)
+    if t == "string" or t == "int":
+      return repr(p)
+    fail("unsupported value '%%s' of type '%%s'" %% (p, type(p)))
+
+  def encode_list(list):
+    return "[%%s]" %% ", ".join([encode_primitive(item) for item in list])
+
+  def encode_list_or_primitive(v):
+    return encode_list(v) if type(v) == "list" else encode_primitive(v)
+
+  if type(input) == "dict":
+    # TODO(juu): the result is read line by line so can't use '\n' yet
+    kv_pairs = [("%%s: %%s" %% (encode_primitive(k), encode_list_or_primitive(v))) for (k, v) in input.items()]
+    return "{ %%s }" %% ", ".join(kv_pairs)
+  else:
+    return encode_list_or_primitive(input)
+
 # Label Map Section
 %s
 
@@ -727,15 +752,6 @@
     fail("expected platform name of the form 'android_<arch>' or 'linux_<arch>', but was " + str(platforms))
     return "UNKNOWN"
 
-def json_for_file(key, file):
-    return '"' + key + '":"' + file.path + '"'
-
-def json_for_files(key, files):
-    return '"' + key + '":[' + ",".join(['"' + f.path + '"' for f in files]) + ']'
-
-def json_for_labels(key, ll):
-    return '"' + key + '":[' + ",".join(['"' + str(x) + '"' for x in ll]) + ']'
-
 def format(target):
   id_string = str(target.label) + "|" + get_arch(target)
 
diff --git a/android/config.go b/android/config.go
index 745410f..ee432a2 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1619,6 +1619,14 @@
 	return uncheckedFinalApiLevel(apiLevel)
 }
 
+func (c *deviceConfig) BuildBrokenClangAsFlags() bool {
+	return c.config.productVariables.BuildBrokenClangAsFlags
+}
+
+func (c *deviceConfig) BuildBrokenClangCFlags() bool {
+	return c.config.productVariables.BuildBrokenClangCFlags
+}
+
 func (c *deviceConfig) BuildBrokenClangProperty() bool {
 	return c.config.productVariables.BuildBrokenClangProperty
 }
diff --git a/android/gen_notice.go b/android/gen_notice.go
index e2b839f..2eb6bec 100644
--- a/android/gen_notice.go
+++ b/android/gen_notice.go
@@ -179,7 +179,7 @@
 	// The visibility property needs to be checked and parsed by the visibility module.
 	setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility)
 
-	initAndroidModuleBase(module)
+	InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
 	InitDefaultableModule(module)
 
 	return module
diff --git a/android/gen_notice_test.go b/android/gen_notice_test.go
index 4ad2ecf..b45ce4f 100644
--- a/android/gen_notice_test.go
+++ b/android/gen_notice_test.go
@@ -12,19 +12,6 @@
 	expectedErrors []string
 }{
 	{
-		name: "gen_notice must not accept licenses property",
-		fs: map[string][]byte{
-			"top/Android.bp": []byte(`
-				gen_notice {
-					name: "top_license",
-					licenses: ["other_license"],
-				}`),
-		},
-		expectedErrors: []string{
-			`unrecognized property "licenses"`,
-		},
-	},
-	{
 		name: "bad gen_notice",
 		fs: map[string][]byte{
 			"top/Android.bp": []byte(`
diff --git a/android/proto.go b/android/proto.go
index 8ad16a6..25cecf4 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -15,9 +15,10 @@
 package android
 
 import (
-	"android/soong/bazel"
 	"strings"
 
+	"android/soong/bazel"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
@@ -161,6 +162,13 @@
 type protoAttrs struct {
 	Srcs                bazel.LabelListAttribute
 	Strip_import_prefix *string
+	Deps                bazel.LabelListAttribute
+}
+
+// For each package in the include_dirs property a proto_library target should
+// be added to the BUILD file in that package and a mapping should be added here
+var includeDirsToProtoDeps = map[string]string{
+	"external/protobuf/src": "//external/protobuf:libprotobuf-proto",
 }
 
 // Bp2buildProtoProperties converts proto properties, creating a proto_library and returning the
@@ -191,6 +199,14 @@
 					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.")
 			}
diff --git a/android/testing.go b/android/testing.go
index 3708501..7b74c89 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -1037,7 +1037,7 @@
 		}
 	}
 	if !found {
-		t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs))
+		t.Errorf("could not match the expected error regex %q (checked %d error(s))", pattern, len(errs))
 		for i, err := range errs {
 			t.Errorf("errs[%d] = %q", i, err)
 		}
diff --git a/android/variable.go b/android/variable.go
index 7a080fe..37ecab5 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -430,6 +430,8 @@
 
 	ShippingApiLevel *string `json:",omitempty"`
 
+	BuildBrokenClangAsFlags            bool     `json:",omitempty"`
+	BuildBrokenClangCFlags             bool     `json:",omitempty"`
 	BuildBrokenClangProperty           bool     `json:",omitempty"`
 	BuildBrokenDepfile                 *bool    `json:",omitempty"`
 	BuildBrokenEnforceSyspropOwner     bool     `json:",omitempty"`
@@ -592,6 +594,9 @@
 	// "acme__board__soc_a", "acme__board__soc_b", and
 	// "acme__board__conditions_default"
 	FullConfig string
+
+	// keeps track of whether this product variable is nested under an arch variant
+	OuterAxis bazel.ConfigurationAxis
 }
 
 func (p *ProductConfigProperty) AlwaysEmit() bool {
@@ -600,11 +605,11 @@
 
 func (p *ProductConfigProperty) ConfigurationAxis() bazel.ConfigurationAxis {
 	if p.Namespace == "" {
-		return bazel.ProductVariableConfigurationAxis(p.FullConfig)
+		return bazel.ProductVariableConfigurationAxis(p.FullConfig, p.OuterAxis)
 	} else {
 		// Soong config variables can be uniquely identified by the namespace
 		// (e.g. acme, android) and the product variable name (e.g. board, size)
-		return bazel.ProductVariableConfigurationAxis(p.Namespace + "__" + p.Name)
+		return bazel.ProductVariableConfigurationAxis(p.Namespace+"__"+p.Name, bazel.NoConfigAxis)
 	}
 }
 
@@ -663,9 +668,11 @@
 			moduleBase.variableProperties,
 			"",
 			"",
-			&productConfigProperties)
+			&productConfigProperties,
+			bazel.ConfigurationAxis{},
+		)
 
-		for _, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) {
+		for axis, configToProps := range moduleBase.GetArchVariantProperties(ctx, moduleBase.variableProperties) {
 			for config, props := range configToProps {
 				// GetArchVariantProperties is creating an instance of the requested type
 				// and productVariablesValues expects an interface, so no need to cast
@@ -674,7 +681,8 @@
 					props,
 					"",
 					config,
-					&productConfigProperties)
+					&productConfigProperties,
+					axis)
 			}
 		}
 	}
@@ -687,7 +695,8 @@
 					namespacedVariableProp,
 					namespace,
 					"",
-					&productConfigProperties)
+					&productConfigProperties,
+					bazel.NoConfigAxis)
 			}
 		}
 	}
@@ -803,6 +812,7 @@
 					p.Name,
 					p.FullConfig,
 					zeroValue,
+					bazel.NoConfigAxis,
 				)
 			}
 		}
@@ -810,7 +820,7 @@
 }
 
 func (p *ProductConfigProperties) AddProductConfigProperty(
-	propertyName, namespace, productVariableName, config string, property interface{}) {
+	propertyName, namespace, productVariableName, config string, property interface{}, outerAxis bazel.ConfigurationAxis) {
 	if (*p)[propertyName] == nil {
 		(*p)[propertyName] = make(map[ProductConfigProperty]interface{})
 	}
@@ -819,6 +829,7 @@
 		Namespace:  namespace,           // e.g. acme, android
 		Name:       productVariableName, // e.g. size, feature1, feature2, FEATURE3, board
 		FullConfig: config,              // e.g. size, feature1-x86, size__conditions_default
+		OuterAxis:  outerAxis,
 	}
 
 	if existing, ok := (*p)[propertyName][productConfigProp]; ok && namespace != "" {
@@ -869,7 +880,7 @@
 	return v, true
 }
 
-func (productConfigProperties *ProductConfigProperties) AddProductConfigProperties(namespace, suffix string, variableValues reflect.Value) {
+func (productConfigProperties *ProductConfigProperties) AddProductConfigProperties(namespace, suffix string, variableValues reflect.Value, outerAxis bazel.ConfigurationAxis) {
 	// variableValues can either be a product_variables or
 	// soong_config_variables struct.
 	//
@@ -974,7 +985,8 @@
 						namespace,           // e.g. acme, android
 						productVariableName, // e.g. size, feature1, FEATURE2, board
 						config,
-						field.Field(k).Interface(), // e.g. ["-DDEFAULT"], ["foo", "bar"]
+						field.Field(k).Interface(), // e.g. ["-DDEFAULT"], ["foo", "bar"],
+						outerAxis,
 					)
 				}
 			} else if property.Kind() != reflect.Interface {
@@ -988,6 +1000,7 @@
 					productVariableName,
 					config,
 					property.Interface(),
+					outerAxis,
 				)
 			}
 		}
@@ -998,14 +1011,14 @@
 // product_variables and soong_config_variables to structs that can be generated
 // as select statements.
 func productVariableValues(
-	fieldName string, variableProps interface{}, namespace, suffix string, productConfigProperties *ProductConfigProperties) {
+	fieldName string, variableProps interface{}, namespace, suffix string, productConfigProperties *ProductConfigProperties, outerAxis bazel.ConfigurationAxis) {
 	if suffix != "" {
 		suffix = "-" + suffix
 	}
 
 	// variableValues represent the product_variables or soong_config_variables struct.
 	variableValues := reflect.ValueOf(variableProps).Elem().FieldByName(fieldName)
-	productConfigProperties.AddProductConfigProperties(namespace, suffix, variableValues)
+	productConfigProperties.AddProductConfigProperties(namespace, suffix, variableValues, outerAxis)
 }
 
 func VariableMutator(mctx BottomUpMutatorContext) {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 49a5d2a..1805291 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -8843,9 +8843,7 @@
 		android.FixtureWithRootAndroidBp(bp),
 		dexpreopt.FixtureSetApexBootJars("myapex:mybootclasspathlib"),
 		dexpreopt.FixtureSetApexSystemServerJars("myapex:mysystemserverclasspathlib"),
-		android.FixtureMergeEnv(map[string]string{
-			"EMMA_INSTRUMENT": "true",
-		}),
+		java.PrepareForTestWithJacocoInstrumentation,
 	).RunTest(t)
 
 	// Make sure jacoco ran on both mylib and mybootclasspathlib
diff --git a/bazel/configurability.go b/bazel/configurability.go
index d9b0a12..7ff202b 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -16,6 +16,8 @@
 
 import (
 	"fmt"
+	"math"
+	"sort"
 	"strings"
 )
 
@@ -69,6 +71,71 @@
 	AndroidAndNonApex = "android-non_apex"
 )
 
+func PowerSetWithoutEmptySet[T any](items []T) [][]T {
+	resultSize := int(math.Pow(2, float64(len(items))))
+	powerSet := make([][]T, 0, resultSize-1)
+	for i := 1; i < resultSize; i++ {
+		combination := make([]T, 0)
+		for j := 0; j < len(items); j++ {
+			if (i>>j)%2 == 1 {
+				combination = append(combination, items[j])
+			}
+		}
+		powerSet = append(powerSet, combination)
+	}
+	return powerSet
+}
+
+func createPlatformArchMap() map[string]string {
+	// Copy of archFeatures from android/arch_list.go because the bazel
+	// package can't access the android package
+	archFeatures := map[string][]string{
+		"arm": {
+			"neon",
+		},
+		"arm64": {
+			"dotprod",
+		},
+		"x86": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"avx",
+			"avx2",
+			"avx512",
+			"popcnt",
+			"movbe",
+		},
+		"x86_64": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"avx",
+			"avx2",
+			"avx512",
+			"popcnt",
+		},
+	}
+	result := make(map[string]string)
+	for arch, allFeatures := range archFeatures {
+		result[arch] = "//build/bazel/platforms/arch:" + arch
+		// Sometimes we want to select on multiple features being active, so
+		// add the power set of all possible features to the map. More details
+		// in android.ModuleBase.GetArchVariantProperties
+		for _, features := range PowerSetWithoutEmptySet(allFeatures) {
+			sort.Strings(features)
+			archFeaturesName := arch + "-" + strings.Join(features, "-")
+			result[archFeaturesName] = "//build/bazel/platforms/arch/variants:" + archFeaturesName
+		}
+	}
+	result[ConditionsDefaultConfigKey] = ConditionsDefaultSelectKey
+	return result
+}
+
 var (
 	// These are the list of OSes and architectures with a Bazel config_setting
 	// and constraint value equivalent. These exist in arch.go, but the android
@@ -77,13 +144,7 @@
 
 	// A map of architectures to the Bazel label of the constraint_value
 	// for the @platforms//cpu:cpu constraint_setting
-	platformArchMap = map[string]string{
-		archArm:                    "//build/bazel/platforms/arch:arm",
-		archArm64:                  "//build/bazel/platforms/arch:arm64",
-		archX86:                    "//build/bazel/platforms/arch:x86",
-		archX86_64:                 "//build/bazel/platforms/arch:x86_64",
-		ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of as arch select map.
-	}
+	platformArchMap = createPlatformArchMap()
 
 	// A map of target operating systems to the Bazel label of the
 	// constraint_value for the @platforms//os:os constraint_setting
@@ -234,10 +295,11 @@
 )
 
 // ProductVariableConfigurationAxis returns an axis for the given product variable
-func ProductVariableConfigurationAxis(variable string) ConfigurationAxis {
+func ProductVariableConfigurationAxis(variable string, outerAxis ConfigurationAxis) ConfigurationAxis {
 	return ConfigurationAxis{
 		configurationType: productVariables,
 		subType:           variable,
+		outerAxisType:     outerAxis.configurationType,
 	}
 }
 
@@ -248,6 +310,8 @@
 	// some configuration types (e.g. productVariables) have multiple independent axes, subType helps
 	// distinguish between them without needing to list all 17 product variables.
 	subType string
+	// used to keep track of which product variables are arch variant
+	outerAxisType configurationType
 }
 
 func (ca *ConfigurationAxis) less(other ConfigurationAxis) bool {
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 5cee6ac..cf8e9f7 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -235,14 +235,14 @@
 //   - The function body should not be indented outside of its own scope.
 func (g getApexInfoType) StarlarkFunctionBody() string {
 	return `info = providers(target)["//build/bazel/rules/apex:apex.bzl%ApexInfo"]
-return "{%s}" % ",".join([
-    json_for_file("signed_output", info.signed_output),
-    json_for_file("unsigned_output", info.unsigned_output),
-    json_for_labels("provides_native_libs", info.provides_native_libs),
-    json_for_labels("requires_native_libs", info.requires_native_libs),
-    json_for_files("bundle_key_pair", info.bundle_key_pair),
-    json_for_files("container_key_pair", info.container_key_pair)
-    ])`
+return json_encode({
+    "signed_output": info.signed_output.path,
+    "unsigned_output": info.unsigned_output.path,
+    "provides_native_libs": [str(lib) for lib in info.provides_native_libs],
+    "requires_native_libs": [str(lib) for lib in info.requires_native_libs],
+    "bundle_key_pair": [f.path for f in info.bundle_key_pair],
+    "container_key_pair": [f.path for f in info.container_key_pair]
+})`
 }
 
 type ApexCqueryInfo struct {
@@ -259,7 +259,9 @@
 // Starlark given in StarlarkFunctionBody.
 func (g getApexInfoType) ParseResult(rawString string) ApexCqueryInfo {
 	var info ApexCqueryInfo
-	if err := json.Unmarshal([]byte(rawString), &info); err != nil {
+	decoder := json.NewDecoder(strings.NewReader(rawString))
+	decoder.DisallowUnknownFields() //useful to detect typos, e.g. in unit tests
+	if err := decoder.Decode(&info); err != nil {
 		panic(fmt.Errorf("cannot parse cquery result '%s': %s", rawString, err))
 	}
 	return info
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
index 34248ce..46eb0b6 100644
--- a/bazel/cquery/request_type_test.go
+++ b/bazel/cquery/request_type_test.go
@@ -161,7 +161,7 @@
 		actualOutput, err := GetCcInfo.ParseResult(tc.input)
 		if (err == nil && tc.expectedErrorMessage != "") ||
 			(err != nil && err.Error() != tc.expectedErrorMessage) {
-			t.Errorf("%q:\nexpected Error %s\n, got %s", tc.description, tc.expectedErrorMessage, err)
+			t.Errorf("%q:\n%12s: %q\n%12s: %q", tc.description, "expect Error", tc.expectedErrorMessage, "but got", err)
 		} else if err == nil && !reflect.DeepEqual(tc.expectedOutput, actualOutput) {
 			t.Errorf("%q:\n expected %#v\n!= actual %#v", tc.description, tc.expectedOutput, actualOutput)
 		}
diff --git a/bazel/properties.go b/bazel/properties.go
index 13e36b5..11f6247 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -309,7 +309,19 @@
 	_, containsProductVariables := axisTypes[productVariables]
 	if containsProductVariables {
 		if containsOs || containsArch || containsOsArch {
-			return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
+			if containsArch {
+				allProductVariablesAreArchVariant := true
+				for k := range la.ConfigurableValues {
+					if k.configurationType == productVariables && k.outerAxisType != arch {
+						allProductVariablesAreArchVariant = false
+					}
+				}
+				if !allProductVariablesAreArchVariant {
+					return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
+				}
+			} else {
+				return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
+			}
 		}
 	}
 	if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
@@ -725,7 +737,7 @@
 	case noConfig:
 		return lla.Value
 	case arch, os, osArch, productVariables, osAndInApex:
-		return (lla.ConfigurableValues[axis][config])
+		return lla.ConfigurableValues[axis][config]
 	default:
 		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
 	}
diff --git a/bazel/properties_test.go b/bazel/properties_test.go
index dc4d5b0..8729381 100644
--- a/bazel/properties_test.go
+++ b/bazel/properties_test.go
@@ -247,13 +247,13 @@
 			OsArchConfigurationAxis: labelListSelectValues{
 				"linux_x86": makeLabelList([]string{"linux_x86_include"}, []string{}),
 			},
-			ProductVariableConfigurationAxis("product_with_defaults"): labelListSelectValues{
+			ProductVariableConfigurationAxis("product_with_defaults", NoConfigAxis): labelListSelectValues{
 				"a":                        makeLabelList([]string{}, []string{"not_in_value"}),
 				"b":                        makeLabelList([]string{"b_val"}, []string{}),
 				"c":                        makeLabelList([]string{"c_val"}, []string{}),
 				ConditionsDefaultConfigKey: makeLabelList([]string{"c_val", "default", "default2"}, []string{}),
 			},
-			ProductVariableConfigurationAxis("product_only_with_excludes"): labelListSelectValues{
+			ProductVariableConfigurationAxis("product_only_with_excludes", NoConfigAxis): labelListSelectValues{
 				"a": makeLabelList([]string{}, []string{"not_in_value"}),
 			},
 		},
@@ -281,7 +281,7 @@
 			"linux_x86":                makeLabels("linux_x86_include"),
 			ConditionsDefaultConfigKey: nilLabels,
 		},
-		ProductVariableConfigurationAxis("product_with_defaults"): {
+		ProductVariableConfigurationAxis("product_with_defaults", NoConfigAxis): {
 			"a":                        nilLabels,
 			"b":                        makeLabels("b_val"),
 			"c":                        makeLabels("c_val"),
@@ -674,7 +674,7 @@
 			OsArchConfigurationAxis: stringListSelectValues{
 				"linux_x86": {"linux_x86_include"},
 			},
-			ProductVariableConfigurationAxis("a"): stringListSelectValues{
+			ProductVariableConfigurationAxis("a", NoConfigAxis): stringListSelectValues{
 				"a": []string{"not_in_value"},
 			},
 		},
@@ -699,7 +699,7 @@
 			"linux": []string{"linux_include"},
 		},
 		OsArchConfigurationAxis: stringListSelectValues{},
-		ProductVariableConfigurationAxis("a"): stringListSelectValues{
+		ProductVariableConfigurationAxis("a", NoConfigAxis): stringListSelectValues{
 			"a": []string{"not_in_value"},
 		},
 	}
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index cb25627..3d9fc5a 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -51,6 +51,7 @@
         "cc_prebuilt_library_conversion_test.go",
         "cc_prebuilt_library_shared_test.go",
         "cc_prebuilt_library_static_test.go",
+        "cc_test_conversion_test.go",
         "cc_yasm_conversion_test.go",
         "conversion_test.go",
         "filegroup_conversion_test.go",
@@ -63,6 +64,7 @@
         "java_plugin_conversion_test.go",
         "java_proto_conversion_test.go",
         "linker_config_conversion_test.go",
+        "ndk_headers_conversion_test.go",
         "performance_test.go",
         "prebuilt_etc_conversion_test.go",
         "python_binary_conversion_test.go",
diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go
index 8e7c2b5..ff82694 100644
--- a/bp2build/aar_conversion_test.go
+++ b/bp2build/aar_conversion_test.go
@@ -53,7 +53,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget(
+			MakeBazelTarget(
 				"android_library",
 				"TestLib",
 				AttrNameToString{
@@ -120,7 +120,7 @@
 }
 `,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget(
+				MakeBazelTarget(
 					"aar_import",
 					"TestImport",
 					AttrNameToString{
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index a37af12..e112be3 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -47,7 +47,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("android_binary", "TestApp", AttrNameToString{
+			MakeBazelTarget("android_binary", "TestApp", AttrNameToString{
 				"srcs":           `["app.java"]`,
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `["res/res.png"]`,
@@ -79,7 +79,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("android_binary", "TestApp", AttrNameToString{
+			MakeBazelTarget("android_binary", "TestApp", AttrNameToString{
 				"srcs":     `["app.java"]`,
 				"manifest": `"manifest/AndroidManifest.xml"`,
 				"resource_files": `[
@@ -119,7 +119,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("android_binary", "TestApp", AttrNameToString{
+			MakeBazelTarget("android_binary", "TestApp", AttrNameToString{
 				"srcs": `select({
         "//build/bazel/platforms/arch:arm": ["arm.java"],
         "//build/bazel/platforms/arch:x86": ["x86.java"],
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index 415e695..b0a2966 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -141,7 +141,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"android_manifest": `"ApogeeAndroidManifest.xml"`,
 				"binaries": `[
         ":cc_binary_1",
@@ -203,7 +203,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"file_contexts": `"//a/b:com.android.apogee-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 			}),
@@ -223,7 +223,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"file_contexts": `"file_contexts_file"`,
 				"manifest":      `"apex_manifest.json"`,
 			}),
@@ -252,7 +252,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 			}),
@@ -275,7 +275,7 @@
 		},
 		Blueprint: createMultilibBlueprint("both"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"native_shared_libs_32": `[
         ":native_shared_lib_1",
         ":native_shared_lib_3",
@@ -319,7 +319,7 @@
 		},
 		Blueprint: createMultilibBlueprint("first"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"native_shared_libs_32": `select({
         "//build/bazel/platforms/arch:arm": [
             ":native_shared_lib_1",
@@ -368,7 +368,7 @@
 		},
 		Blueprint: createMultilibBlueprint("32"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"native_shared_libs_32": `[
         ":native_shared_lib_1",
         ":native_shared_lib_3",
@@ -399,7 +399,7 @@
 		},
 		Blueprint: createMultilibBlueprint("64"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 				"native_shared_libs_64": `select({
         "//build/bazel/platforms/arch:arm64": [
             ":native_shared_lib_1",
@@ -439,7 +439,7 @@
 	manifest: "apogee_manifest.json",
 }
 `,
-		ExpectedBazelTargets: []string{makeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+		ExpectedBazelTargets: []string{MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
 			"manifest":      `"apogee_manifest.json"`,
 			"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 		}),
@@ -467,7 +467,7 @@
 	bazel_module: { bp2build_available: true },
 }
 `,
-		ExpectedBazelTargets: []string{makeBazelTarget("apex", "apogee", AttrNameToString{
+		ExpectedBazelTargets: []string{MakeBazelTarget("apex", "apogee", AttrNameToString{
 			"manifest":      `"manifest.json"`,
 			"file_contexts": `"//system/sepolicy/apex:apogee-file_contexts"`,
 		}),
@@ -624,7 +624,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"android_manifest": `"ApogeeAndroidManifest.xml"`,
 				"binaries": `[
         ":cc_binary_1",
@@ -684,7 +684,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"//a/b:apex_manifest.json"`,
 			}),
@@ -718,7 +718,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"//a/b:apogee_manifest.json"`,
 			}),
@@ -750,7 +750,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 			}),
@@ -783,7 +783,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"apogee_manifest.json"`,
 			}),
@@ -816,7 +816,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 				"package_name":  `"com.google.android.apogee"`,
@@ -855,7 +855,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 				"prebuilts":     `[":prebuilt_file"]`,
@@ -900,7 +900,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 				"prebuilts":     `[":prebuilt_file2"]`,
@@ -940,7 +940,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":      `"apex_manifest.json"`,
 				"prebuilts":     `[]`,
@@ -974,7 +974,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts":  `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":       `"apex_manifest.json"`,
 				"logging_parent": `"foo.bar.baz"`,
@@ -1009,7 +1009,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+			MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
 				"file_contexts":  `"//system/sepolicy/apex:com.android.apogee-file_contexts"`,
 				"manifest":       `"apex_manifest.json"`,
 				"logging_parent": `"foo.bar.baz.override"`,
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index cf46533..ca8185e 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -289,7 +289,9 @@
 						return
 					}
 				}
-				targets = generateBazelTargets(bpCtx, aModule)
+				var targetErrs []error
+				targets, targetErrs = generateBazelTargets(bpCtx, aModule)
+				errs = append(errs, targetErrs...)
 				for _, t := range targets {
 					// A module can potentially generate more than 1 Bazel
 					// target, each of a different rule class.
@@ -306,7 +308,10 @@
 				// be mapped cleanly to a bazel label.
 				return
 			}
-			t := generateSoongModuleTarget(bpCtx, m)
+			t, err := generateSoongModuleTarget(bpCtx, m)
+			if err != nil {
+				errs = append(errs, err)
+			}
 			targets = append(targets, t)
 		default:
 			errs = append(errs, fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
@@ -347,12 +352,18 @@
 	}, errs
 }
 
-func generateBazelTargets(ctx bpToBuildContext, m android.Module) []BazelTarget {
+func generateBazelTargets(ctx bpToBuildContext, m android.Module) ([]BazelTarget, []error) {
 	var targets []BazelTarget
+	var errs []error
 	for _, m := range m.Bp2buildTargets() {
-		targets = append(targets, generateBazelTarget(ctx, m))
+		target, err := generateBazelTarget(ctx, m)
+		if err != nil {
+			errs = append(errs, err)
+			return targets, errs
+		}
+		targets = append(targets, target)
 	}
-	return targets
+	return targets, errs
 }
 
 type bp2buildModule interface {
@@ -363,13 +374,16 @@
 	BazelAttributes() []interface{}
 }
 
-func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) BazelTarget {
+func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) (BazelTarget, error) {
 	ruleClass := m.BazelRuleClass()
 	bzlLoadLocation := m.BazelRuleLoadLocation()
 
 	// extract the bazel attributes from the module.
 	attrs := m.BazelAttributes()
-	props := extractModuleProperties(attrs, true)
+	props, err := extractModuleProperties(attrs, true)
+	if err != nil {
+		return BazelTarget{}, err
+	}
 
 	// name is handled in a special manner
 	delete(props.Attrs, "name")
@@ -389,13 +403,13 @@
 			targetName,
 			attributes,
 		),
-	}
+	}, nil
 }
 
 // Convert a module and its deps and props into a Bazel macro/rule
 // representation in the BUILD file.
-func generateSoongModuleTarget(ctx bpToBuildContext, m blueprint.Module) BazelTarget {
-	props := getBuildProperties(ctx, m)
+func generateSoongModuleTarget(ctx bpToBuildContext, m blueprint.Module) (BazelTarget, error) {
+	props, err := getBuildProperties(ctx, m)
 
 	// TODO(b/163018919): DirectDeps can have duplicate (module, variant)
 	// items, if the modules are added using different DependencyTag. Figure
@@ -429,21 +443,21 @@
 			ctx.ModuleSubDir(m),
 			depLabelList,
 			attributes),
-	}
+	}, err
 }
 
-func getBuildProperties(ctx bpToBuildContext, m blueprint.Module) BazelAttributes {
+func getBuildProperties(ctx bpToBuildContext, m blueprint.Module) (BazelAttributes, error) {
 	// TODO: this omits properties for blueprint modules (blueprint_go_binary,
 	// bootstrap_go_binary, bootstrap_go_package), which will have to be handled separately.
 	if aModule, ok := m.(android.Module); ok {
 		return extractModuleProperties(aModule.GetProperties(), false)
 	}
 
-	return BazelAttributes{}
+	return BazelAttributes{}, nil
 }
 
 // Generically extract module properties and types into a map, keyed by the module property name.
-func extractModuleProperties(props []interface{}, checkForDuplicateProperties bool) BazelAttributes {
+func extractModuleProperties(props []interface{}, checkForDuplicateProperties bool) (BazelAttributes, error) {
 	ret := map[string]string{}
 
 	// Iterate over this android.Module's property structs.
@@ -456,24 +470,29 @@
 		// manipulate internal props, if needed.
 		if isStructPtr(propertiesValue.Type()) {
 			structValue := propertiesValue.Elem()
-			for k, v := range extractStructProperties(structValue, 0) {
+			ok, err := extractStructProperties(structValue, 0)
+			if err != nil {
+				return BazelAttributes{}, err
+			}
+			for k, v := range ok {
 				if existing, exists := ret[k]; checkForDuplicateProperties && exists {
-					panic(fmt.Errorf(
+					return BazelAttributes{}, fmt.Errorf(
 						"%s (%v) is present in properties whereas it should be consolidated into a commonAttributes",
-						k, existing))
+						k, existing)
 				}
 				ret[k] = v
 			}
 		} else {
-			panic(fmt.Errorf(
-				"properties must be a pointer to a struct, got %T",
-				propertiesValue.Interface()))
+			return BazelAttributes{},
+				fmt.Errorf(
+					"properties must be a pointer to a struct, got %T",
+					propertiesValue.Interface())
 		}
 	}
 
 	return BazelAttributes{
 		Attrs: ret,
-	}
+	}, nil
 }
 
 func isStructPtr(t reflect.Type) bool {
@@ -531,7 +550,12 @@
 		}
 
 		// Sort and print the struct props by the key.
-		structProps := extractStructProperties(propertyValue, indent)
+		structProps, err := extractStructProperties(propertyValue, indent)
+
+		if err != nil {
+			return "", err
+		}
+
 		if len(structProps) == 0 {
 			return "", nil
 		}
@@ -550,11 +574,13 @@
 // which each property value correctly pretty-printed and indented at the right nest level,
 // since property structs can be nested. In Starlark, nested structs are represented as nested
 // dicts: https://docs.bazel.build/skylark/lib/dict.html
-func extractStructProperties(structValue reflect.Value, indent int) map[string]string {
+func extractStructProperties(structValue reflect.Value, indent int) (map[string]string, error) {
 	if structValue.Kind() != reflect.Struct {
-		panic(fmt.Errorf("Expected a reflect.Struct type, but got %s", structValue.Kind()))
+		return map[string]string{}, fmt.Errorf("Expected a reflect.Struct type, but got %s", structValue.Kind())
 	}
 
+	var err error
+
 	ret := map[string]string{}
 	structType := structValue.Type()
 	for i := 0; i < structValue.NumField(); i++ {
@@ -575,7 +601,10 @@
 				fieldValue = fieldValue.Elem()
 			}
 			if fieldValue.Type().Kind() == reflect.Struct {
-				propsToMerge := extractStructProperties(fieldValue, indent)
+				propsToMerge, err := extractStructProperties(fieldValue, indent)
+				if err != nil {
+					return map[string]string{}, err
+				}
 				for prop, value := range propsToMerge {
 					ret[prop] = value
 				}
@@ -584,20 +613,20 @@
 		}
 
 		propertyName := proptools.PropertyNameForField(field.Name)
-		prettyPrintedValue, err := prettyPrint(fieldValue, indent+1, false)
+		var prettyPrintedValue string
+		prettyPrintedValue, err = prettyPrint(fieldValue, indent+1, false)
 		if err != nil {
-			panic(
-				fmt.Errorf(
-					"Error while parsing property: %q. %s",
-					propertyName,
-					err))
+			return map[string]string{}, fmt.Errorf(
+				"Error while parsing property: %q. %s",
+				propertyName,
+				err)
 		}
 		if prettyPrintedValue != "" {
 			ret[propertyName] = prettyPrintedValue
 		}
 	}
 
-	return ret
+	return ret, nil
 }
 
 func isZero(value reflect.Value) bool {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 0467cf0..dd28c3c 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -238,7 +238,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "foo", AttrNameToString{
+				MakeBazelTarget("custom", "foo", AttrNameToString{
 					"string_literal_prop": `""`,
 				}),
 			},
@@ -251,7 +251,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "foo", AttrNameToString{
+				MakeBazelTarget("custom", "foo", AttrNameToString{
 					"string_literal_prop": `"PROP"`,
 				}),
 			},
@@ -267,7 +267,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "foo", AttrNameToString{
+				MakeBazelTarget("custom", "foo", AttrNameToString{
 					"string_literal_prop": `select({
         "//build/bazel/platforms/arch:arm": "ARM",
         "//build/bazel/platforms/arch:arm64": "ARM64",
@@ -284,7 +284,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "foo", AttrNameToString{
+				MakeBazelTarget("custom", "foo", AttrNameToString{
 					"string_ptr_prop": `""`,
 				}),
 			},
@@ -298,7 +298,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "foo", AttrNameToString{
+				MakeBazelTarget("custom", "foo", AttrNameToString{
 					"string_list_prop": `[
         "a",
         "b",
@@ -316,7 +316,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "foo", AttrNameToString{
+				MakeBazelTarget("custom", "foo", AttrNameToString{
 					"string_list_prop": `[
         "\t",
         "\n",
@@ -339,10 +339,10 @@
   bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "dep", AttrNameToString{
+				MakeBazelTarget("custom", "dep", AttrNameToString{
 					"arch_paths": `["abc"]`,
 				}),
-				makeBazelTarget("custom", "has_dep", AttrNameToString{
+				MakeBazelTarget("custom", "has_dep", AttrNameToString{
 					"arch_paths": `[":dep"]`,
 				}),
 			},
@@ -355,7 +355,7 @@
   bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "has_dep", AttrNameToString{
+				MakeBazelTarget("custom", "has_dep", AttrNameToString{
 					"arch_paths": `[":dep__BP2BUILD__MISSING__DEP"]`,
 				}),
 			},
@@ -391,7 +391,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "arch_paths", AttrNameToString{
+				MakeBazelTarget("custom", "arch_paths", AttrNameToString{
 					"arch_paths": `select({
         "//build/bazel/platforms/arch:arm": [
             "arm.txt",
@@ -469,10 +469,10 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "dep", AttrNameToString{
+				MakeBazelTarget("custom", "dep", AttrNameToString{
 					"arch_paths": `["abc"]`,
 				}),
-				makeBazelTarget("custom", "has_dep", AttrNameToString{
+				MakeBazelTarget("custom", "has_dep", AttrNameToString{
 					"arch_paths": `select({
         "//build/bazel/platforms/arch:x86": [":dep"],
         "//conditions:default": [],
@@ -488,7 +488,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "embedded_props", AttrNameToString{
+				MakeBazelTarget("custom", "embedded_props", AttrNameToString{
 					"embedded_attr": `"abc"`,
 				}),
 			},
@@ -501,7 +501,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("custom", "ptr_to_embedded_props", AttrNameToString{
+				MakeBazelTarget("custom", "ptr_to_embedded_props", AttrNameToString{
 					"other_embedded_attr": `"abc"`,
 				}),
 			},
@@ -751,7 +751,7 @@
 
 	for _, tc := range testCases {
 		t.Run(tc.Description, func(t *testing.T) {
-			runBp2BuildTestCaseSimple(t, tc)
+			RunBp2BuildTestCaseSimple(t, tc)
 		})
 	}
 }
@@ -1494,7 +1494,7 @@
 
 	for _, testCase := range testCases {
 		t.Run(testCase.Description, func(t *testing.T) {
-			runBp2BuildTestCaseSimple(t, testCase)
+			RunBp2BuildTestCaseSimple(t, testCase)
 		})
 	}
 }
@@ -1536,7 +1536,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("py_library", "fg_foo", map[string]string{
+				MakeBazelTarget("py_library", "fg_foo", map[string]string{
 					"data": `select({
         "//build/bazel/platforms/arch:arm": [":reqdarm"],
         "//build/bazel/platforms/arch:x86": [":reqdx86"],
@@ -1563,7 +1563,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("py_library", "fg_foo", map[string]string{
+				MakeBazelTarget("py_library", "fg_foo", map[string]string{
 					"data": `[
         "data.bin",
         ":reqd",
@@ -1593,7 +1593,7 @@
 
 	for _, tc := range testCases {
 		t.Run(tc.Description, func(t *testing.T) {
-			runBp2BuildTestCaseSimple(t, tc)
+			RunBp2BuildTestCaseSimple(t, tc)
 		})
 	}
 }
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index c1b4cd0..880ae75 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -355,7 +355,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
 				"copts": `[
         "bothflag",
         "staticflag",
@@ -377,7 +377,7 @@
         ":whole_and_static_lib_for_both",
         ":whole_static_lib_for_static",
     ]`}),
-			makeBazelTarget("cc_library_shared", "a", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"copts": `[
         "bothflag",
         "sharedflag",
@@ -463,7 +463,7 @@
 			simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_both") +
 			simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_both"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
 				"copts": `[
         "bothflag",
         "staticflag",
@@ -495,7 +495,7 @@
         ":whole_static_dep_for_static",
     ]`,
 			}),
-			makeBazelTarget("cc_library_shared", "a", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"copts": `[
         "bothflag",
         "sharedflag",
@@ -560,13 +560,13 @@
 		},
 		Blueprint: soongCcLibraryPreamble,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+			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{
+			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"whole_archive_deps": `[
         ":whole_static_lib_for_both_alwayslink",
         ":whole_static_lib_for_shared_alwayslink",
@@ -654,7 +654,7 @@
 		},
 		Blueprint: soongCcLibraryPreamble,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
 				"copts": `[
         "bothflag",
         "staticflag",
@@ -678,7 +678,7 @@
         "//conditions:default": [],
     })`,
 			}),
-			makeBazelTarget("cc_library_shared", "a", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"copts": `[
         "bothflag",
         "sharedflag",
@@ -807,7 +807,7 @@
 		},
 		Blueprint: soongCcLibraryPreamble,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
 				"local_includes": `["."]`,
 				"srcs": `[
         "both_source.cpp",
@@ -832,7 +832,7 @@
         ":static_filegroup_c_srcs",
     ]`,
 			}),
-			makeBazelTarget("cc_library_shared", "a", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"local_includes": `["."]`,
 				"srcs": `[
         "both_source.cpp",
@@ -1199,6 +1199,40 @@
 	)
 }
 
+func TestCcLibraryProductVariablesHeaderLibs(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Filesystem:                 map[string]string{},
+		Blueprint: soongCcLibraryStaticPreamble + `
+cc_library {
+    name: "foo_static",
+    srcs: ["common.c"],
+    product_variables: {
+        malloc_not_svelte: {
+            header_libs: ["malloc_not_svelte_header_lib"],
+        },
+    },
+    include_build_directory: false,
+}
+
+cc_library {
+    name: "malloc_not_svelte_header_lib",
+    bazel_module: { bp2build_available: false },
+}
+`,
+		ExpectedBazelTargets: makeCcLibraryTargets("foo_static", AttrNameToString{
+			"implementation_deps": `select({
+        "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_header_lib"],
+        "//conditions:default": [],
+    })`,
+			"srcs_c":                 `["common.c"]`,
+			"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+		}),
+	},
+	)
+}
+
 func TestCCLibraryNoCrtTrue(t *testing.T) {
 	runCcLibraryTestCase(t, Bp2buildTestCase{
 		Description:                "cc_library - nocrt: true emits attribute",
@@ -1315,8 +1349,8 @@
 			staticAttrs[key] = val
 		}
 	}
-	sharedTarget := makeBazelTarget("cc_library_shared", name, sharedAttrs)
-	staticTarget := makeBazelTarget("cc_library_static", name+"_bp2build_cc_library_static", staticAttrs)
+	sharedTarget := MakeBazelTarget("cc_library_shared", name, sharedAttrs)
+	staticTarget := MakeBazelTarget("cc_library_static", name+"_bp2build_cc_library_static", staticAttrs)
 
 	return []string{staticTarget, sharedTarget}
 }
@@ -1338,7 +1372,7 @@
 			stubSuiteAttrs[STUB_SUITE_ATTRS[key]] = attrs[key]
 		}
 	}
-	return makeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
+	return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
 }
 
 func TestCCLibraryNoLibCrtFalse(t *testing.T) {
@@ -1649,10 +1683,10 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "static_empty_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "static_empty_bp2build_cc_library_static", AttrNameToString{
 				"system_dynamic_deps": "[]",
 			}),
-			makeBazelTarget("cc_library_shared", "static_empty", AttrNameToString{}),
+			MakeBazelTarget("cc_library_shared", "static_empty", AttrNameToString{}),
 		},
 	})
 }
@@ -1672,8 +1706,8 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", AttrNameToString{}),
-			makeBazelTarget("cc_library_shared", "shared_empty", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", AttrNameToString{}),
+			MakeBazelTarget("cc_library_shared", "shared_empty", AttrNameToString{
 				"system_dynamic_deps": "[]",
 			}),
 		},
@@ -1699,8 +1733,8 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", AttrNameToString{}),
-			makeBazelTarget("cc_library_shared", "shared_empty", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "shared_empty_bp2build_cc_library_static", AttrNameToString{}),
+			MakeBazelTarget("cc_library_shared", "shared_empty", AttrNameToString{
 				"system_dynamic_deps": "[]",
 			}),
 		},
@@ -1782,10 +1816,10 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"system_dynamic_deps": `[":libc"]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"system_dynamic_deps": `[
         ":libc",
         ":libm",
@@ -2000,7 +2034,7 @@
 }
 `, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
 				ExpectedBazelTargets: []string{
-					makeBazelTarget("cc_library_static", name_prefix+"_static", attrs),
+					MakeBazelTarget("cc_library_static", name_prefix+"_static", attrs),
 				},
 			})
 
@@ -2019,7 +2053,7 @@
 }
 `, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
 				ExpectedBazelTargets: []string{
-					makeBazelTarget("cc_library_shared", name_prefix+"_shared", attrs),
+					MakeBazelTarget("cc_library_shared", name_prefix+"_shared", attrs),
 				},
 			})
 		})
@@ -2036,14 +2070,14 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs": `["foo.proto"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
 				"deps":                              `[":libprotobuf-cpp-lite"]`,
-			}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
@@ -2061,15 +2095,15 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs":                `["foo.proto"]`,
 				"strip_import_prefix": `""`,
-			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
 				"deps":                              `[":libprotobuf-cpp-lite"]`,
-			}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
@@ -2087,14 +2121,14 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs": `["foo.proto"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
 				"deps":                              `[":libprotobuf-cpp-lite"]`,
-			}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
@@ -2114,14 +2148,14 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs": `["foo.proto"]`,
-			}), makeBazelTarget("cc_proto_library", "foo_cc_proto", AttrNameToString{
+			}), MakeBazelTarget("cc_proto_library", "foo_cc_proto", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto"]`,
 				"deps":                              `[":libprotobuf-cpp-full"]`,
-			}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"dynamic_deps": `[":libprotobuf-cpp-full"]`,
 			}),
 		},
@@ -2141,14 +2175,14 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs": `["foo.proto"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
 				"deps":                              `[":libprotobuf-cpp-lite"]`,
-			}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
 			}),
 		},
@@ -2168,14 +2202,14 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs": `["foo.proto"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"deps":               `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
-			}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
 			}),
@@ -2183,6 +2217,50 @@
 	})
 }
 
+func TestCcLibraryProtoIncludeDirs(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: soongCcProtoPreamble + `cc_library {
+	name: "foo",
+	srcs: ["foo.proto"],
+	proto: {
+		include_dirs: ["external/protobuf/src"],
+	},
+	include_build_directory: false,
+}`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+				"srcs": `["foo.proto"]`,
+				"deps": `["//external/protobuf:libprotobuf-proto"]`,
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+				"deps": `[":foo_proto"]`,
+			}), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"deps":                              `[":libprotobuf-cpp-lite"]`,
+				"implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+			}),
+		},
+	})
+}
+
+func TestCcLibraryProtoIncludeDirsUnknown(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: soongCcProtoPreamble + `cc_library {
+	name: "foo",
+	srcs: ["foo.proto"],
+	proto: {
+		include_dirs: ["external/protobuf/abc"],
+	},
+	include_build_directory: false,
+}`,
+		ExpectedErr: fmt.Errorf("module \"foo\": Could not find the proto_library target for include dir: external/protobuf/abc"),
+	})
+}
+
 func TestCcLibraryProtoFilegroups(t *testing.T) {
 	runCcLibraryTestCase(t, Bp2buildTestCase{
 		ModuleTypeUnderTest:        "cc_library",
@@ -2228,65 +2306,65 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "a_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "a_proto", AttrNameToString{
 				"srcs": `[":a_fg_proto"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", AttrNameToString{
 				"deps": `[":a_proto"]`,
-			}), makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
 				"deps":               `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
 				"srcs":               `[":a_fg_proto_cpp_srcs"]`,
 				"srcs_as":            `[":a_fg_proto_as_srcs"]`,
 				"srcs_c":             `[":a_fg_proto_c_srcs"]`,
-			}), makeBazelTarget("cc_library_shared", "a", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
 				"srcs":               `[":a_fg_proto_cpp_srcs"]`,
 				"srcs_as":            `[":a_fg_proto_as_srcs"]`,
 				"srcs_c":             `[":a_fg_proto_c_srcs"]`,
-			}), makeBazelTarget("proto_library", "b_proto", AttrNameToString{
+			}), MakeBazelTarget("proto_library", "b_proto", AttrNameToString{
 				"srcs": `[":b_protos"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "b_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "b_cc_proto_lite", AttrNameToString{
 				"deps": `[":b_proto"]`,
-			}), makeBazelTarget("cc_library_static", "b_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "b_bp2build_cc_library_static", AttrNameToString{
 				"deps":               `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":b_cc_proto_lite"]`,
 				"srcs":               `[":b_protos_cpp_srcs"]`,
 				"srcs_as":            `[":b_protos_as_srcs"]`,
 				"srcs_c":             `[":b_protos_c_srcs"]`,
-			}), makeBazelTarget("cc_library_shared", "b", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":b_cc_proto_lite"]`,
 				"srcs":               `[":b_protos_cpp_srcs"]`,
 				"srcs_as":            `[":b_protos_as_srcs"]`,
 				"srcs_c":             `[":b_protos_c_srcs"]`,
-			}), makeBazelTarget("proto_library", "c_proto", AttrNameToString{
+			}), MakeBazelTarget("proto_library", "c_proto", AttrNameToString{
 				"srcs": `[":c-proto-srcs"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "c_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "c_cc_proto_lite", AttrNameToString{
 				"deps": `[":c_proto"]`,
-			}), makeBazelTarget("cc_library_static", "c_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "c_bp2build_cc_library_static", AttrNameToString{
 				"deps":               `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":c_cc_proto_lite"]`,
 				"srcs":               `[":c-proto-srcs_cpp_srcs"]`,
 				"srcs_as":            `[":c-proto-srcs_as_srcs"]`,
 				"srcs_c":             `[":c-proto-srcs_c_srcs"]`,
-			}), makeBazelTarget("cc_library_shared", "c", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "c", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":c_cc_proto_lite"]`,
 				"srcs":               `[":c-proto-srcs_cpp_srcs"]`,
 				"srcs_as":            `[":c-proto-srcs_as_srcs"]`,
 				"srcs_c":             `[":c-proto-srcs_c_srcs"]`,
-			}), makeBazelTarget("proto_library", "d_proto", AttrNameToString{
+			}), MakeBazelTarget("proto_library", "d_proto", AttrNameToString{
 				"srcs": `[":proto-srcs-d"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "d_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "d_cc_proto_lite", AttrNameToString{
 				"deps": `[":d_proto"]`,
-			}), makeBazelTarget("cc_library_static", "d_bp2build_cc_library_static", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "d_bp2build_cc_library_static", AttrNameToString{
 				"deps":               `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":d_cc_proto_lite"]`,
 				"srcs":               `[":proto-srcs-d_cpp_srcs"]`,
 				"srcs_as":            `[":proto-srcs-d_as_srcs"]`,
 				"srcs_c":             `[":proto-srcs-d_c_srcs"]`,
-			}), makeBazelTarget("cc_library_shared", "d", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "d", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":d_cc_proto_lite"]`,
 				"srcs":               `[":proto-srcs-d_cpp_srcs"]`,
@@ -2385,10 +2463,10 @@
   },
 	include_build_directory: false,
 }`,
-		ExpectedBazelTargets: []string{makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+		ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 			"srcs":                   `["foo.cpp"]`,
 			"target_compatible_with": `["@platforms//:incompatible"]`,
-		}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+		}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 			"srcs": `["foo.cpp"]`,
 			"target_compatible_with": `select({
         "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
@@ -2425,13 +2503,13 @@
 	},
 	include_build_directory: false,
 }`,
-		ExpectedBazelTargets: []string{makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+		ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 			"srcs": `["foo.cpp"]`,
 			"target_compatible_with": `select({
         "//build/bazel/platforms/os:windows": ["@platforms//:incompatible"],
         "//conditions:default": [],
     })`,
-		}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+		}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 			"srcs": `["foo.cpp"]`,
 			"target_compatible_with": `select({
         "//build/bazel/platforms/os_arch:darwin_arm64": [],
@@ -2513,14 +2591,14 @@
 	bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: append([]string{
-			makeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
+			MakeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
 				"srcs": `[
         "foo1.l",
         "foo2.l",
     ]`,
 				"lexopts": `["--foo_flags"]`,
 			}),
-			makeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
+			MakeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
 				"srcs": `[
         "bar1.ll",
         "bar2.ll",
@@ -2552,14 +2630,14 @@
   runtime_libs: ["foo"],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "bar", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
 				"local_includes": `["."]`,
 			}),
-			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"runtime_deps":   `[":foo"]`,
 				"local_includes": `["."]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"runtime_deps":   `[":foo"]`,
 				"local_includes": `["."]`,
 			}),
@@ -2608,10 +2686,10 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 				"suffix": `""`,
 			}),
@@ -2634,10 +2712,10 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 				"suffix": `"-suf"`,
 			}),
@@ -2663,10 +2741,10 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 				"suffix": `select({
         "//build/bazel/platforms/arch:arm": "-32",
@@ -2701,22 +2779,23 @@
 				"srcs":                `["aidl/A.aidl"]`,
 				"strip_import_prefix": `"aidl"`,
 			}),
-			makeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
+			MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
 				"srcs": `["B.aidl"]`,
 			}),
-			makeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
+			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
 				"deps": `[
         ":A_aidl",
         ":foo_aidl_library",
     ]`,
 			}),
-			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
-				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
-				"local_includes":     `["."]`,
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
+				"local_includes":                    `["."]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
-				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
-				"local_includes":     `["."]`,
+			// TODO(b/239311679) Add implementation_whole_archive_deps to cc_library_shared
+			// for bp2build to be fully correct. This fallback is affecting proto as well.
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"local_includes": `["."]`,
 			}),
 		},
 	})
@@ -2730,27 +2809,62 @@
 		Filesystem: map[string]string{
 			"path/to/A/Android.bp": `
 filegroup {
-	name: "A_aidl",
-	srcs: ["aidl/A.aidl"],
-	path: "aidl",
+    name: "A_aidl",
+    srcs: ["aidl/A.aidl"],
+    path: "aidl",
 }`,
 		},
 		Blueprint: `
 cc_library {
-	name: "foo",
-	srcs: [
-		":A_aidl",
-	],
+    name: "foo",
+    srcs: [
+        ":A_aidl",
+    ],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
+			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
 				"deps": `["//path/to/A:A_aidl"]`,
 			}),
-			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`,
+				"local_includes":                    `["."]`,
+			}),
+			// TODO(b/239311679) Add implementation_whole_archive_deps to cc_library_shared
+			// for bp2build to be fully correct. This fallback is affecting proto as well.
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"local_includes": `["."]`,
+			}),
+		},
+	})
+}
+
+func TestCcLibraryWithExportAidlHeaders(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library with export aidl headers",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: `
+cc_library {
+    name: "foo",
+    srcs: [
+        "Foo.aidl",
+    ],
+    aidl: {
+        export_aidl_headers: true,
+    }
+}`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
+				"srcs": `["Foo.aidl"]`,
+			}),
+			MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{
+				"deps": `[":foo_aidl_library"]`,
+			}),
+			MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
 				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
 				"local_includes":     `["."]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"whole_archive_deps": `[":foo_cc_aidl_library"]`,
 				"local_includes":     `["."]`,
 			}),
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 5846f83..5fa7cac 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -106,7 +106,7 @@
     // TODO: Also support export_header_lib_headers
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"export_includes": `[
         "dir-1",
         "dir-2",
@@ -183,7 +183,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"deps": `[":base-lib"] + select({
         "//build/bazel/platforms/os:android": [":android-lib"],
         "//build/bazel/platforms/os:darwin": [":darwin-lib"],
@@ -223,7 +223,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"deps": `select({
         "//build/bazel/platforms/os:android": [":exported-lib"],
         "//conditions:default": [],
@@ -276,7 +276,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"export_system_includes": `["shared_include_dir"] + select({
         "//build/bazel/platforms/arch:arm": ["arm_include_dir"],
         "//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
@@ -318,7 +318,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "lib-1", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "lib-1", AttrNameToString{
 				"export_includes": `["lib-1"]`,
 			}),
 		},
@@ -340,7 +340,7 @@
 }
 ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"deps": `[":foo_export"]`,
 			}),
 		},
@@ -362,7 +362,7 @@
 }
 ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"deps": `[":foo_export"]`,
 			}),
 		},
@@ -384,7 +384,7 @@
 }
 ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"deps": `[":foo_export"]`,
 			}),
 		},
@@ -405,7 +405,7 @@
 }
 ` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+			MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
 				"deps": `[":foo_export"]`,
 			}),
 		},
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index ed983bf..4d8e59b 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -142,7 +142,7 @@
     // TODO: Also support export_header_lib_headers
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"absolute_includes": `[
         "include_dir_1",
         "include_dir_2",
@@ -202,7 +202,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"implementation_dynamic_deps": `select({
         "//build/bazel/platforms/arch:arm64": [":shared_dep"],
         "//conditions:default": [],
@@ -231,7 +231,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"implementation_dynamic_deps": `select({
         "//build/bazel/platforms/os:android": [":shared_dep"],
         "//conditions:default": [],
@@ -266,7 +266,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"implementation_dynamic_deps": `[":shared_dep"] + select({
         "//build/bazel/platforms/arch:arm64": [":shared_dep3"],
         "//conditions:default": [],
@@ -295,7 +295,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"srcs_c": `[
         "common.c",
         "foo-a.c",
@@ -322,7 +322,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"strip": `{
         "all": True,
         "keep_symbols": False,
@@ -351,7 +351,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"additional_linker_inputs": `["version_script"]`,
 				"linkopts":                 `["-Wl,--version-script,$(location version_script)"]`,
 			}),
@@ -374,7 +374,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"link_crt": `False`,
 				"srcs":     `["impl.cpp"]`,
 			}),
@@ -397,7 +397,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"srcs": `["impl.cpp"]`,
 			}),
 		},
@@ -440,11 +440,11 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs": `["foo.proto"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"dynamic_deps":       `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
 			}),
@@ -460,7 +460,7 @@
         include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"use_version_lib": "True",
 			}),
 		},
@@ -484,7 +484,7 @@
 `,
 		},
 		Blueprint: soongCcLibraryPreamble,
-		ExpectedBazelTargets: []string{makeBazelTarget("cc_library_shared", "a", AttrNameToString{
+		ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
 			"has_stubs": `True`,
 		}),
 		},
@@ -510,7 +510,7 @@
     defaults: ["empty_defaults"],
 }
 `,
-		ExpectedBazelTargets: []string{makeBazelTarget("cc_library_shared", "empty", AttrNameToString{
+		ExpectedBazelTargets: []string{MakeBazelTarget("cc_library_shared", "empty", AttrNameToString{
 			"system_dynamic_deps": "[]",
 		})},
 	})
@@ -537,21 +537,21 @@
 	bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
+			MakeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
 				"srcs": `[
         "foo1.l",
         "foo2.l",
     ]`,
 				"lexopts": `["--foo_flags"]`,
 			}),
-			makeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
+			MakeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
 				"srcs": `[
         "bar1.ll",
         "bar2.ll",
     ]`,
 				"lexopts": `["--foo_flags"]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo_lib", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_lib", AttrNameToString{
 				"srcs": `[
         "bar.cc",
         ":foo_lib_genlex_ll",
@@ -576,7 +576,7 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"conlyflags": `["-a"]`,
 				"copts":      `["-b"]`,
 				"cppflags":   `["-c"]`,
@@ -600,7 +600,7 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"additional_linker_inputs": `["version_script"]`,
 				"conlyflags": `[
         "-include",
@@ -631,10 +631,10 @@
   runtime_libs: ["foo"],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "bar", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
 				"local_includes": `["."]`,
 			}),
-			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
 				"runtime_deps":   `[":foo"]`,
 				"local_includes": `["."]`,
 			}),
@@ -656,7 +656,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 				"suffix": `""`,
 			}),
@@ -678,7 +678,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 				"suffix": `"-suf"`,
 			}),
@@ -703,7 +703,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
 				"srcs_c": `["foo.c"]`,
 				"suffix": `select({
         "//build/bazel/platforms/arch:arm": "-32",
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 1c160ec..0637ba2 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -173,7 +173,7 @@
     // TODO: Also support export_header_lib_headers
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"absolute_includes": `[
         "include_dir_1",
         "include_dir_2",
@@ -238,7 +238,7 @@
     ],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"absolute_includes": `["subpackage"]`,
 				"local_includes":    `["."]`,
 			}),
@@ -262,7 +262,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"export_includes": `["subpackage"]`,
 			}),
 		},
@@ -285,7 +285,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"export_system_includes": `["subpackage"]`,
 			}),
 		},
@@ -320,7 +320,7 @@
 		},
 		Blueprint: soongCcLibraryStaticPreamble,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"absolute_includes": `[
         "subpackage/subsubpackage",
         "subpackage2",
@@ -352,7 +352,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"absolute_includes": `["subpackage"]`,
 				"local_includes":    `["subpackage2"]`,
 			}),
@@ -379,7 +379,7 @@
     include_build_directory: true,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"absolute_includes": `["subpackage"]`,
 				"local_includes": `[
         "subpackage2",
@@ -409,7 +409,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"implementation_deps": `select({
         "//build/bazel/platforms/arch:arm64": [":static_dep"],
         "//conditions:default": [],
@@ -442,7 +442,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"implementation_deps": `select({
         "//build/bazel/platforms/os:android": [":static_dep"],
         "//conditions:default": [],
@@ -486,7 +486,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"implementation_deps": `[":static_dep"] + select({
         "//build/bazel/platforms/arch:arm64": [":static_dep4"],
         "//conditions:default": [],
@@ -516,7 +516,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `[
         "common.c",
         "foo-a.c",
@@ -541,7 +541,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `["common.c"] + select({
         "//build/bazel/platforms/arch:arm": ["foo-arm.c"],
         "//conditions:default": [],
@@ -571,7 +571,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `["common.c"] + select({
         "//build/bazel/platforms/arch:arm": ["for-arm.c"],
         "//conditions:default": ["not-for-arm.c"],
@@ -603,7 +603,7 @@
     include_build_directory: false,
 } `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `["common.c"] + select({
         "//build/bazel/platforms/arch:arm": [
             "not-for-x86.c",
@@ -652,7 +652,7 @@
     include_build_directory: false,
 } `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `["common.c"] + select({
         "//build/bazel/platforms/arch:arm": [
             "not-for-arm64.c",
@@ -709,7 +709,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs": `["common.cc"] + select({
         "//build/bazel/platforms/arch:arm": [],
         "//conditions:default": ["foo-no-arm.cc"],
@@ -740,7 +740,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs": `["common.cc"] + select({
         "//build/bazel/platforms/arch:arm": [],
         "//build/bazel/platforms/arch:x86": [
@@ -769,7 +769,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"implementation_deps": `[":static_dep"]`,
 			}),
 		},
@@ -794,7 +794,7 @@
     include_build_directory: false,
 } `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `["common.c"] + select({
         "//build/bazel/platforms/arch:arm": ["for-lib32.c"],
         "//build/bazel/platforms/arch:x86": ["for-lib32.c"],
@@ -826,7 +826,7 @@
     include_build_directory: false,
 } `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `["common.c"] + select({
         "//build/bazel/platforms/arch:arm": [
             "not-for-lib64.c",
@@ -891,7 +891,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `["common.c"] + select({
         "//build/bazel/platforms/arch:arm": [
             "not-for-arm64.c",
@@ -962,7 +962,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"export_includes": `["."]`,
 				"local_includes":  `["."]`,
 				"hdrs":            `[":export_generated_hdr"]`,
@@ -1030,7 +1030,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs": `[
         "common.cpp",
         ":generated_src",
@@ -1093,7 +1093,7 @@
     include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"srcs_c": `select({
         "//build/bazel/platforms/os:android": ["android_src.c"],
         "//conditions:default": [],
@@ -1132,7 +1132,7 @@
     include_build_directory: false,
 } `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"copts": `select({
         "//build/bazel/product_variables:binder32bit": ["-Wbinder32bit"],
         "//conditions:default": [],
@@ -1192,7 +1192,7 @@
     include_build_directory: false,
 } `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"copts": `select({
         "//build/bazel/product_variables:malloc_not_svelte": ["-Wmalloc_not_svelte"],
         "//conditions:default": [],
@@ -1231,7 +1231,7 @@
     include_build_directory: false,
 } `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
 				"asflags": `select({
         "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
         "//conditions:default": [],
@@ -1253,7 +1253,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "root_empty", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "root_empty", AttrNameToString{
 				"system_dynamic_deps": `[]`,
 			}),
 		},
@@ -1277,7 +1277,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "static_empty", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "static_empty", AttrNameToString{
 				"system_dynamic_deps": `[]`,
 			}),
 		},
@@ -1299,7 +1299,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "target_bionic_empty", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "target_bionic_empty", AttrNameToString{
 				"system_dynamic_deps": `[]`,
 			}),
 		},
@@ -1325,7 +1325,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "target_linux_bionic_empty", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "target_linux_bionic_empty", AttrNameToString{
 				"system_dynamic_deps": `[]`,
 			}),
 		},
@@ -1348,7 +1348,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "target_bionic", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "target_bionic", AttrNameToString{
 				"system_dynamic_deps": `select({
         "//build/bazel/platforms/os:android": [":libc"],
         "//build/bazel/platforms/os:linux_bionic": [":libc"],
@@ -1377,7 +1377,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "target_linux_bionic", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "target_linux_bionic", AttrNameToString{
 				"system_dynamic_deps": `[":libc"] + select({
         "//build/bazel/platforms/os:linux_bionic": [":libm"],
         "//conditions:default": [],
@@ -1419,18 +1419,12 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "all", AttrNameToString{
-				"implementation_dynamic_deps": `select({
-        "//build/bazel/platforms/os:android": [],
-        "//build/bazel/platforms/os:linux_bionic": [],
-        "//conditions:default": [":libc"],
-    })`,
-			}),
-			makeBazelTarget("cc_library_static", "keep_for_empty_system_shared_libs", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "all", AttrNameToString{}),
+			MakeBazelTarget("cc_library_static", "keep_for_empty_system_shared_libs", AttrNameToString{
 				"implementation_dynamic_deps": `[":libc"]`,
 				"system_dynamic_deps":         `[]`,
 			}),
-			makeBazelTarget("cc_library_static", "used_in_bionic_oses", AttrNameToString{}),
+			MakeBazelTarget("cc_library_static", "used_in_bionic_oses", AttrNameToString{}),
 		},
 	})
 }
@@ -1446,11 +1440,11 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
 				"srcs": `["foo.proto"]`,
-			}), makeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+			}), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
 				"deps": `[":foo_proto"]`,
-			}), makeBazelTarget("cc_library_static", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
 				"deps":               `[":libprotobuf-cpp-lite"]`,
 				"whole_archive_deps": `[":foo_cc_proto_lite"]`,
 			}),
@@ -1466,7 +1460,7 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
 				"use_version_lib": "True",
 			}),
 		},
@@ -1483,7 +1477,7 @@
 	include_build_directory: false,
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_static", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
 				"conlyflags": `["-std=conly"]`,
 				"cppflags":   `["-std=cpp"]`,
 			}),
@@ -1553,7 +1547,7 @@
 	%s
 }`, tc.prop),
 				ExpectedBazelTargets: []string{
-					makeBazelTarget("cc_library_static", "foo", tc.attr),
+					MakeBazelTarget("cc_library_static", "foo", tc.attr),
 				},
 			})
 		})
@@ -1571,10 +1565,10 @@
   runtime_libs: ["foo"],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_library_shared", "bar", AttrNameToString{
+			MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
 				"local_includes": `["."]`,
 			}),
-			makeBazelTarget("cc_library_static", "foo", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
 				"runtime_deps":   `[":foo"]`,
 				"local_includes": `["."]`,
 			}),
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index 37d5580..b8dc690 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -60,7 +60,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts": `[
         "-fno-addrsig",
         "-Wno-gcc-compat",
@@ -106,7 +106,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts": `[
         "-Werror",
         "-fno-addrsig",
@@ -141,11 +141,11 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "bar", AttrNameToString{
+			MakeBazelTarget("cc_object", "bar", AttrNameToString{
 				"copts":               `["-fno-addrsig"]`,
 				"srcs":                `["x/y/z.c"]`,
 				"system_dynamic_deps": `[]`,
-			}), makeBazelTarget("cc_object", "foo", AttrNameToString{
+			}), MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts":               `["-fno-addrsig"]`,
 				"deps":                `[":bar"]`,
 				"srcs":                `["a/b/c.c"]`,
@@ -170,7 +170,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts":               `["-fno-addrsig"]`,
 				"srcs":                `["a/b/c.c"]`,
 				"system_dynamic_deps": `[]`,
@@ -195,7 +195,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"asflags": `select({
         "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"],
         "//conditions:default": [],
@@ -227,7 +227,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts": `["-fno-addrsig"] + select({
         "//build/bazel/platforms/arch:x86": ["-fPIC"],
         "//conditions:default": [],
@@ -271,7 +271,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts": `["-fno-addrsig"] + select({
         "//build/bazel/platforms/arch:arm": ["-Wall"],
         "//build/bazel/platforms/arch:arm64": ["-Wall"],
@@ -303,7 +303,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts":         `["-fno-addrsig"]`,
 				"linker_script": `"bunny.lds"`,
 				"srcs":          `["base.cpp"]`,
@@ -360,7 +360,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts": `["-fno-addrsig"]`,
 				"deps": `select({
         "//build/bazel/platforms/arch:arm": [":arm_obj"],
@@ -401,7 +401,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("cc_object", "foo", AttrNameToString{
+			MakeBazelTarget("cc_object", "foo", AttrNameToString{
 				"copts": `["-fno-addrsig"]`,
 				"srcs": `["base.cpp"] + select({
         "//build/bazel/platforms/os_arch:android_arm64": [
diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go
index 32c3f4d..dd217c3 100644
--- a/bp2build/cc_prebuilt_library_conversion_test.go
+++ b/bp2build/cc_prebuilt_library_conversion_test.go
@@ -21,7 +21,7 @@
 )
 
 func TestPrebuiltLibraryStaticAndSharedSimple(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library static and shared simple",
 			ModuleTypeUnderTest:        "cc_prebuilt_library",
@@ -36,10 +36,10 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
-				makeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
 				}),
 			},
@@ -47,7 +47,7 @@
 }
 
 func TestPrebuiltLibraryWithArchVariance(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library with arch variance",
 			ModuleTypeUnderTest:        "cc_prebuilt_library",
@@ -66,14 +66,14 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
         "//conditions:default": None,
     })`,
 				}),
-				makeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
@@ -85,7 +85,7 @@
 }
 
 func TestPrebuiltLibraryAdditionalAttrs(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library additional attributes",
 			ModuleTypeUnderTest:        "cc_prebuilt_library",
@@ -104,13 +104,13 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library":         `"libf.so"`,
 					"export_includes":        `["testdir/1/"]`,
 					"export_system_includes": `["testdir/2/"]`,
 				}),
 				// TODO(b/229374533): When fixed, update this test
-				makeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
 				}),
 			},
@@ -118,7 +118,7 @@
 }
 
 func TestPrebuiltLibrarySharedStanzaFails(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library with shared stanza fails because multiple sources",
 			ModuleTypeUnderTest:        "cc_prebuilt_library",
@@ -141,7 +141,7 @@
 }
 
 func TestPrebuiltLibraryStaticStanzaFails(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library with static stanza fails because multiple sources",
 			ModuleTypeUnderTest:        "cc_prebuilt_library",
@@ -164,7 +164,7 @@
 }
 
 func TestPrebuiltLibrarySharedAndStaticStanzas(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library with both shared and static stanzas",
 			ModuleTypeUnderTest:        "cc_prebuilt_library",
@@ -185,10 +185,10 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
-				makeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libg.so"`,
 				}),
 			},
@@ -197,7 +197,7 @@
 
 // TODO(b/228623543): When this bug is fixed, enable this test
 //func TestPrebuiltLibraryOnlyShared(t *testing.T) {
-//	runBp2BuildTestCaseSimple(t,
+//	RunBp2BuildTestCaseSimple(t,
 //		bp2buildTestCase{
 //			description:                "prebuilt library shared only",
 //			moduleTypeUnderTest:        "cc_prebuilt_library",
@@ -224,7 +224,7 @@
 
 // TODO(b/228623543): When this bug is fixed, enable this test
 //func TestPrebuiltLibraryOnlyStatic(t *testing.T) {
-//	runBp2BuildTestCaseSimple(t,
+//	RunBp2BuildTestCaseSimple(t,
 //		bp2buildTestCase{
 //			description:                "prebuilt library static only",
 //			moduleTypeUnderTest:        "cc_prebuilt_library",
diff --git a/bp2build/cc_prebuilt_library_shared_test.go b/bp2build/cc_prebuilt_library_shared_test.go
index bcf0ce2..541ce5e 100644
--- a/bp2build/cc_prebuilt_library_shared_test.go
+++ b/bp2build/cc_prebuilt_library_shared_test.go
@@ -8,7 +8,7 @@
 )
 
 func TestSharedPrebuiltLibrary(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library shared simple",
 			ModuleTypeUnderTest:        "cc_prebuilt_library_shared",
@@ -23,7 +23,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
 				}),
 			},
@@ -31,7 +31,7 @@
 }
 
 func TestSharedPrebuiltLibraryWithArchVariance(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library shared with arch variance",
 			ModuleTypeUnderTest:        "cc_prebuilt_library_shared",
@@ -50,7 +50,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
@@ -62,7 +62,7 @@
 }
 
 func TestSharedPrebuiltLibrarySharedStanzaFails(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library shared with shared stanza fails because multiple sources",
 			ModuleTypeUnderTest:        "cc_prebuilt_library_shared",
diff --git a/bp2build/cc_prebuilt_library_static_test.go b/bp2build/cc_prebuilt_library_static_test.go
index 489a53d..69a1b5e 100644
--- a/bp2build/cc_prebuilt_library_static_test.go
+++ b/bp2build/cc_prebuilt_library_static_test.go
@@ -21,7 +21,7 @@
 )
 
 func TestStaticPrebuiltLibrary(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library static simple",
 			ModuleTypeUnderTest:        "cc_prebuilt_library_static",
@@ -36,7 +36,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_static", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_static", "libtest", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
 			},
@@ -44,7 +44,7 @@
 }
 
 func TestStaticPrebuiltLibraryWithArchVariance(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library static with arch variance",
 			ModuleTypeUnderTest:        "cc_prebuilt_library_static",
@@ -63,7 +63,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				makeBazelTarget("prebuilt_library_static", "libtest", AttrNameToString{
+				MakeBazelTarget("prebuilt_library_static", "libtest", AttrNameToString{
 					"static_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
@@ -75,7 +75,7 @@
 }
 
 func TestStaticPrebuiltLibraryStaticStanzaFails(t *testing.T) {
-	runBp2BuildTestCaseSimple(t,
+	RunBp2BuildTestCaseSimple(t,
 		Bp2buildTestCase{
 			Description:                "prebuilt library with static stanza fails because multiple sources",
 			ModuleTypeUnderTest:        "cc_prebuilt_library_static",
@@ -118,21 +118,21 @@
 	bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
+			MakeBazelTarget("genlex", "foo_lib_genlex_l", AttrNameToString{
 				"srcs": `[
         "foo1.l",
         "foo2.l",
     ]`,
 				"lexopts": `["--foo_flags"]`,
 			}),
-			makeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
+			MakeBazelTarget("genlex", "foo_lib_genlex_ll", AttrNameToString{
 				"srcs": `[
         "bar1.ll",
         "bar2.ll",
     ]`,
 				"lexopts": `["--foo_flags"]`,
 			}),
-			makeBazelTarget("cc_library_static", "foo_lib", AttrNameToString{
+			MakeBazelTarget("cc_library_static", "foo_lib", AttrNameToString{
 				"srcs": `[
         "bar.cc",
         ":foo_lib_genlex_ll",
diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go
new file mode 100644
index 0000000..9b7748f
--- /dev/null
+++ b/bp2build/cc_test_conversion_test.go
@@ -0,0 +1,150 @@
+// Copyright 2022 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 (
+	"fmt"
+	"testing"
+
+	"android/soong/android"
+	"android/soong/cc"
+	"android/soong/genrule"
+)
+
+type ccTestBp2buildTestCase struct {
+	description string
+	blueprint   string
+	targets     []testBazelTarget
+}
+
+func registerCcTestModuleTypes(ctx android.RegistrationContext) {
+	cc.RegisterCCBuildComponents(ctx)
+	ctx.RegisterModuleType("cc_binary", cc.BinaryFactory)
+	ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
+	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+	ctx.RegisterModuleType("cc_test_library", cc.TestLibraryFactory)
+	ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+}
+
+func runCcTestTestCase(t *testing.T, testCase ccTestBp2buildTestCase) {
+	t.Helper()
+	moduleTypeUnderTest := "cc_test"
+
+	description := fmt.Sprintf("%s %s", moduleTypeUnderTest, testCase.description)
+	t.Run(description, func(t *testing.T) {
+		t.Helper()
+		RunBp2BuildTestCase(t, registerCcTestModuleTypes, Bp2buildTestCase{
+			ExpectedBazelTargets:       generateBazelTargetsForTest(testCase.targets, android.HostAndDeviceSupported),
+			ModuleTypeUnderTest:        moduleTypeUnderTest,
+			ModuleTypeUnderTestFactory: cc.TestFactory,
+			Description:                description,
+			Blueprint:                  testCase.blueprint,
+		})
+	})
+}
+
+func TestBasicCcTest(t *testing.T) {
+	runCcTestTestCase(t, ccTestBp2buildTestCase{
+		description: "basic cc_test with commonly used attributes",
+		blueprint: `
+cc_test {
+    name: "mytest",
+    host_supported: true,
+    srcs: ["test.cpp"],
+    target: {
+        android: {
+            srcs: ["android.cpp"],
+            shared_libs: ["foolib"],
+        },
+        linux: {
+            srcs: ["linux.cpp"],
+        },
+        host: {
+            static_libs: ["hostlib"],
+        },
+    },
+    data: [":data_mod", "file.txt"],
+    data_bins: [":cc_bin"],
+    data_libs: [":cc_lib"],
+    cflags: ["-Wall"],
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "foolib") +
+			simpleModuleDoNotConvertBp2build("cc_library_static", "hostlib") +
+			simpleModuleDoNotConvertBp2build("genrule", "data_mod") +
+			simpleModuleDoNotConvertBp2build("cc_binary", "cc_bin") +
+			simpleModuleDoNotConvertBp2build("cc_test_library", "cc_lib"),
+		targets: []testBazelTarget{
+			{"cc_test", "mytest", AttrNameToString{
+				"copts": `["-Wall"]`,
+				"data": `[
+        ":data_mod",
+        "file.txt",
+        ":cc_bin",
+        ":cc_lib",
+    ]`,
+				"deps": `select({
+        "//build/bazel/platforms/os:darwin": [":hostlib"],
+        "//build/bazel/platforms/os:linux": [":hostlib"],
+        "//build/bazel/platforms/os:linux_bionic": [":hostlib"],
+        "//build/bazel/platforms/os:linux_musl": [":hostlib"],
+        "//build/bazel/platforms/os:windows": [":hostlib"],
+        "//conditions:default": [],
+    })`,
+				"gtest":          "True",
+				"isolated":       "True",
+				"local_includes": `["."]`,
+				"dynamic_deps": `select({
+        "//build/bazel/platforms/os:android": [":foolib"],
+        "//conditions:default": [],
+    })`,
+				"srcs": `["test.cpp"] + select({
+        "//build/bazel/platforms/os:android": [
+            "linux.cpp",
+            "android.cpp",
+        ],
+        "//build/bazel/platforms/os:linux": ["linux.cpp"],
+        "//build/bazel/platforms/os:linux_bionic": ["linux.cpp"],
+        "//build/bazel/platforms/os:linux_musl": ["linux.cpp"],
+        "//conditions:default": [],
+    })`,
+			},
+			},
+		},
+	})
+}
+
+func TestBasicCcTestGtestIsolatedDisabled(t *testing.T) {
+	runCcTestTestCase(t, ccTestBp2buildTestCase{
+		description: "cc test with disabled gtest and isolated props",
+		blueprint: `
+cc_test {
+    name: "mytest",
+    host_supported: true,
+    srcs: ["test.cpp"],
+    gtest: false,
+    isolated: false,
+}
+`,
+		targets: []testBazelTarget{
+			{"cc_test", "mytest", AttrNameToString{
+				"gtest":          "False",
+				"isolated":       "False",
+				"local_includes": `["."]`,
+				"srcs":           `["test.cpp"]`,
+			},
+			},
+		},
+	})
+}
diff --git a/bp2build/cc_yasm_conversion_test.go b/bp2build/cc_yasm_conversion_test.go
index 2a71834..55d4feb 100644
--- a/bp2build/cc_yasm_conversion_test.go
+++ b/bp2build/cc_yasm_conversion_test.go
@@ -48,7 +48,7 @@
   srcs: ["main.cpp", "myfile.asm"],
 }`,
 		ExpectedBazelTargets: append([]string{
-			makeBazelTarget("yasm", "foo_yasm", map[string]string{
+			MakeBazelTarget("yasm", "foo_yasm", map[string]string{
 				"include_dirs": `["."]`,
 				"srcs":         `["myfile.asm"]`,
 			}),
@@ -81,7 +81,7 @@
   srcs: ["main.cpp", "myfile.asm"],
 }`,
 		ExpectedBazelTargets: append([]string{
-			makeBazelTarget("yasm", "foo_yasm", map[string]string{
+			MakeBazelTarget("yasm", "foo_yasm", map[string]string{
 				"include_dirs": `[
         "include1/foo",
         ".",
@@ -123,7 +123,7 @@
   },
 }`,
 		ExpectedBazelTargets: append([]string{
-			makeBazelTarget("yasm", "foo_yasm", map[string]string{
+			MakeBazelTarget("yasm", "foo_yasm", map[string]string{
 				"include_dirs": `["."]`,
 				"srcs": `select({
         "//build/bazel/platforms/arch:x86": ["myfile.asm"],
@@ -161,7 +161,7 @@
   },
 }`,
 		ExpectedBazelTargets: append([]string{
-			makeBazelTarget("yasm", "foo_yasm", map[string]string{
+			MakeBazelTarget("yasm", "foo_yasm", map[string]string{
 				"include_dirs": `["."]`,
 				"srcs": `["myfile.asm"] + select({
         "//build/bazel/platforms/arch:x86": ["mysecondfile.asm"],
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 6fb2823..731b17e 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -136,16 +136,17 @@
 var (
 	// Certain module property names are blocklisted/ignored here, for the reasons commented.
 	ignoredPropNames = map[string]bool{
-		"name":       true, // redundant, since this is explicitly generated for every target
-		"from":       true, // reserved keyword
-		"in":         true, // reserved keyword
-		"size":       true, // reserved for tests
-		"arch":       true, // interface prop type is not supported yet.
-		"multilib":   true, // interface prop type is not supported yet.
-		"target":     true, // interface prop type is not supported yet.
-		"visibility": true, // Bazel has native visibility semantics. Handle later.
-		"features":   true, // There is already a built-in attribute 'features' which cannot be overridden.
-		"for":        true, // reserved keyword, b/233579439
+		"name":               true, // redundant, since this is explicitly generated for every target
+		"from":               true, // reserved keyword
+		"in":                 true, // reserved keyword
+		"size":               true, // reserved for tests
+		"arch":               true, // interface prop type is not supported yet.
+		"multilib":           true, // interface prop type is not supported yet.
+		"target":             true, // interface prop type is not supported yet.
+		"visibility":         true, // Bazel has native visibility semantics. Handle later.
+		"features":           true, // There is already a built-in attribute 'features' which cannot be overridden.
+		"for":                true, // reserved keyword, b/233579439
+		"versions_with_info": true, // TODO(b/245730552) struct properties not fully supported
 	}
 )
 
diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go
index 50ea542..86f3d42 100644
--- a/bp2build/java_binary_host_conversion_test.go
+++ b/bp2build/java_binary_host_conversion_test.go
@@ -55,7 +55,7 @@
     java_version: "8",
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_binary", "java-binary-host-1", AttrNameToString{
+			MakeBazelTarget("java_binary", "java-binary-host-1", AttrNameToString{
 				"srcs":       `["a.java"]`,
 				"main_class": `"com.android.test.MainClass"`,
 				"deps":       `["//other:jni-lib-1"]`,
@@ -91,7 +91,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_binary", "java-binary-host-1", AttrNameToString{
+			MakeBazelTarget("java_binary", "java-binary-host-1", AttrNameToString{
 				"main_class":   `"com.android.test.MainClass"`,
 				"runtime_deps": `[":java-dep-1"]`,
 				"target_compatible_with": `select({
diff --git a/bp2build/java_import_conversion_test.go b/bp2build/java_import_conversion_test.go
index 707ecce..05d7142 100644
--- a/bp2build/java_import_conversion_test.go
+++ b/bp2build/java_import_conversion_test.go
@@ -45,7 +45,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_import", "example_import", AttrNameToString{
+			MakeBazelTarget("java_import", "example_import", AttrNameToString{
 				"jars": `["import.jar"]`,
 			}),
 		}})
@@ -74,7 +74,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_import", "example_import", AttrNameToString{
+			MakeBazelTarget("java_import", "example_import", AttrNameToString{
 				"jars": `select({
         "//build/bazel/platforms/os:android": ["android.jar"],
         "//build/bazel/platforms/os:linux": ["linux.jar"],
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index b57cf35..74e2dbd 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -51,11 +51,11 @@
     bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"srcs": `["a.java"]`,
 				"deps": `[":java-lib-2"]`,
 			}),
-			makeBazelTarget("java_library", "java-lib-2", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{
 				"srcs": `["b.java"]`,
 			}),
 		},
@@ -84,7 +84,7 @@
     bazel_module: { bp2build_available: false },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"srcs": `["a.java"]`,
 				"deps": `[
         ":java-lib-2",
@@ -110,7 +110,7 @@
     bazel_module: { bp2build_available: false },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"exports": `[":java-lib-2"]`,
 			}),
 		},
@@ -149,7 +149,7 @@
     bazel_module: { bp2build_available: false },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"plugins": `[":java-plugin-1"]`,
 			}),
 		},
@@ -166,7 +166,7 @@
     java_version: "11",
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"srcs":      `["a.java"]`,
 				"javacopts": `["-source 11 -target 11"]`,
 			}),
@@ -186,7 +186,7 @@
     },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"javacopts": `[
         "-Xsuper-fast",
         "-Xep:SpeedLimit:OFF",
@@ -208,7 +208,7 @@
     },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"javacopts": `["-Xsuper-fast"]`,
 				"srcs":      `["a.java"]`,
 			}),
@@ -228,7 +228,7 @@
     },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"javacopts": `["-Xsuper-fast"]`,
 				"srcs":      `["a.java"]`,
 			}),
@@ -252,13 +252,13 @@
         bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("event_log_tags", "example_lib_logtags", AttrNameToString{
+			MakeBazelTarget("event_log_tags", "example_lib_logtags", AttrNameToString{
 				"srcs": `[
         "a.logtag",
         "b.logtag",
     ]`,
 			}),
-			makeBazelTarget("java_library", "example_lib", AttrNameToString{
+			MakeBazelTarget("java_library", "example_lib", AttrNameToString{
 				"srcs": `[
         "a.java",
         "b.java",
@@ -280,7 +280,7 @@
 	java_resources: ["res/a.res", "res/b.res"],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"resources": `[
         "res/a.res",
         "res/b.res",
@@ -302,7 +302,7 @@
 	java_resource_dirs: ["res"],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"resource_strip_prefix": `"res"`,
 				"resources": `[
         "res/a.res",
@@ -326,7 +326,7 @@
 	exclude_java_resource_dirs: ["res/exclude"],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"resource_strip_prefix": `"res"`,
 				"resources":             `["res/a.res"]`,
 			}),
@@ -347,7 +347,7 @@
 	exclude_java_resources: ["res/dir1/exclude.res"],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
 				"resource_strip_prefix": `"res"`,
 				"resources": `[
         "res/a.res",
@@ -389,16 +389,16 @@
         bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
+			MakeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
 				"srcs": `[
         "a.aidl",
         "b.aidl",
     ]`,
 			}),
-			makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
+			MakeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
 				"deps": `[":example_lib_aidl_library"]`,
 			}),
-			makeBazelTarget("java_library", "example_lib", AttrNameToString{
+			MakeBazelTarget("java_library", "example_lib", AttrNameToString{
 				"deps":    `[":example_lib_java_aidl_library"]`,
 				"exports": `[":example_lib_java_aidl_library"]`,
 				"srcs": `[
@@ -424,13 +424,13 @@
         bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
+			MakeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
 				"srcs": `["b.aidl"]`,
 			}),
-			makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
+			MakeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
 				"deps": `[":example_lib_aidl_library"]`,
 			}),
-			makeBazelTarget("java_library", "example_lib", AttrNameToString{
+			MakeBazelTarget("java_library", "example_lib", AttrNameToString{
 				"deps":    `[":example_lib_java_aidl_library"]`,
 				"exports": `[":example_lib_java_aidl_library"]`,
 				"srcs":    `["a.java"]`,
@@ -478,10 +478,10 @@
         "b.aidl",
     ]`,
 			}),
-			makeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
+			MakeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
 				"deps": `[":aidl_files"]`,
 			}),
-			makeBazelTarget("java_library", "example_lib", AttrNameToString{
+			MakeBazelTarget("java_library", "example_lib", AttrNameToString{
 				"deps":    `[":example_lib_java_aidl_library"]`,
 				"exports": `[":example_lib_java_aidl_library"]`,
 				"srcs": `[
@@ -523,10 +523,10 @@
 	],
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_aidl_library", "foo_java_aidl_library", AttrNameToString{
+			MakeBazelTarget("java_aidl_library", "foo_java_aidl_library", AttrNameToString{
 				"deps": `["//path/to/A:A_aidl"]`,
 			}),
-			makeBazelTarget("java_library", "foo", AttrNameToString{
+			MakeBazelTarget("java_library", "foo", AttrNameToString{
 				"exports": `[":foo_java_aidl_library"]`,
 			}),
 		},
@@ -534,3 +534,118 @@
 		ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	})
 }
+
+func TestConvertArmNeonVariant(t *testing.T) {
+	t.Helper()
+	RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
+		Description:                "Android Library - simple arch feature",
+		ModuleTypeUnderTest:        "android_library",
+		ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
+		Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
+android_library {
+	name: "TestLib",
+	manifest: "manifest/AndroidManifest.xml",
+	srcs: ["lib.java"],
+	arch: {
+		arm: {
+			neon: {
+				srcs: ["arm_neon.java"],
+			},
+		},
+	},
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget(
+				"android_library",
+				"TestLib",
+				AttrNameToString{
+					"srcs": `["lib.java"] + select({
+        "//build/bazel/platforms/arch/variants:arm-neon": ["arm_neon.java"],
+        "//conditions:default": [],
+    })`,
+					"manifest":       `"manifest/AndroidManifest.xml"`,
+					"resource_files": `[]`,
+				}),
+		}})
+}
+
+func TestConvertMultipleArchFeatures(t *testing.T) {
+	t.Helper()
+	RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
+		Description:                "Android Library - multiple arch features",
+		ModuleTypeUnderTest:        "android_library",
+		ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
+		Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
+android_library {
+	name: "TestLib",
+	manifest: "manifest/AndroidManifest.xml",
+	srcs: ["lib.java"],
+	arch: {
+		x86: {
+			ssse3: {
+				srcs: ["ssse3.java"],
+			},
+			sse4_1: {
+				srcs: ["sse4_1.java"],
+			},
+		},
+	},
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget(
+				"android_library",
+				"TestLib",
+				AttrNameToString{
+					"srcs": `["lib.java"] + select({
+        "//build/bazel/platforms/arch/variants:x86-sse4_1": ["sse4_1.java"],
+        "//build/bazel/platforms/arch/variants:x86-sse4_1-ssse3": [
+            "sse4_1.java",
+            "ssse3.java",
+        ],
+        "//build/bazel/platforms/arch/variants:x86-ssse3": ["ssse3.java"],
+        "//conditions:default": [],
+    })`,
+					"manifest":       `"manifest/AndroidManifest.xml"`,
+					"resource_files": `[]`,
+				}),
+		}})
+}
+
+func TestConvertExcludeSrcsArchFeature(t *testing.T) {
+	t.Helper()
+	RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
+		Description:                "Android Library - exclude_srcs with arch feature",
+		ModuleTypeUnderTest:        "android_library",
+		ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
+		Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
+android_library {
+	name: "TestLib",
+	manifest: "manifest/AndroidManifest.xml",
+	srcs: ["lib.java"],
+	arch: {
+		arm: {
+			srcs: ["arm_non_neon.java"],
+			neon: {
+				exclude_srcs: ["arm_non_neon.java"],
+			},
+		},
+	},
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget(
+				"android_library",
+				"TestLib",
+				AttrNameToString{
+					"srcs": `["lib.java"] + select({
+        "//build/bazel/platforms/arch/variants:arm-neon": [],
+        "//build/bazel/platforms/arch:arm": ["arm_non_neon.java"],
+        "//conditions:default": [],
+    })`,
+					"manifest":       `"manifest/AndroidManifest.xml"`,
+					"resource_files": `[]`,
+				}),
+		}})
+}
diff --git a/bp2build/java_library_host_conversion_test.go b/bp2build/java_library_host_conversion_test.go
index 1dcf163..edd8690 100644
--- a/bp2build/java_library_host_conversion_test.go
+++ b/bp2build/java_library_host_conversion_test.go
@@ -46,7 +46,7 @@
     java_version: "9",
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_library", "java-lib-host-1", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-host-1", AttrNameToString{
 				"srcs": `["a.java"]`,
 				"deps": `[":java-lib-host-2"]`,
 				"target_compatible_with": `select({
@@ -54,7 +54,7 @@
         "//conditions:default": [],
     })`,
 			}),
-			makeBazelTarget("java_library", "java-lib-host-2", AttrNameToString{
+			MakeBazelTarget("java_library", "java-lib-host-2", AttrNameToString{
 				"javacopts": `["-source 1.9 -target 1.9"]`,
 				"srcs":      `["c.java"]`,
 				"target_compatible_with": `select({
diff --git a/bp2build/java_plugin_conversion_test.go b/bp2build/java_plugin_conversion_test.go
index 2d2e5ff..d9049d4 100644
--- a/bp2build/java_plugin_conversion_test.go
+++ b/bp2build/java_plugin_conversion_test.go
@@ -54,7 +54,7 @@
     bazel_module: { bp2build_available: false },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_plugin", "java-plug-1", AttrNameToString{
+			MakeBazelTarget("java_plugin", "java-plug-1", AttrNameToString{
 				"target_compatible_with": `select({
         "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
         "//conditions:default": [],
@@ -95,7 +95,7 @@
     bazel_module: { bp2build_available: false },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("java_plugin", "java-plug-1", AttrNameToString{
+			MakeBazelTarget("java_plugin", "java-plug-1", AttrNameToString{
 				"target_compatible_with": `select({
         "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
         "//conditions:default": [],
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
index 6465641..df0df2f 100644
--- a/bp2build/java_proto_conversion_test.go
+++ b/bp2build/java_proto_conversion_test.go
@@ -70,7 +70,7 @@
     srcs: ["a.proto"],
 }`
 
-	protoLibrary := makeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
+	protoLibrary := MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
 		"srcs": `["a.proto"]`,
 	})
 
@@ -82,13 +82,13 @@
 			Blueprint:   fmt.Sprintf(bp, tc.protoType),
 			ExpectedBazelTargets: []string{
 				protoLibrary,
-				makeBazelTarget(
+				MakeBazelTarget(
 					tc.javaLibraryType,
 					javaLibraryName,
 					AttrNameToString{
 						"deps": `[":java-protos_proto"]`,
 					}),
-				makeBazelTarget("java_library", "java-protos", AttrNameToString{
+				MakeBazelTarget("java_library", "java-protos", AttrNameToString{
 					"exports": fmt.Sprintf(`[":%s"]`, javaLibraryName),
 				}),
 			},
@@ -106,16 +106,16 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
+			MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
 				"srcs": `["a.proto"]`,
 			}),
-			makeBazelTarget(
+			MakeBazelTarget(
 				"java_lite_proto_library",
 				"java-protos_java_proto_lite",
 				AttrNameToString{
 					"deps": `[":java-protos_proto"]`,
 				}),
-			makeBazelTarget("java_library", "java-protos", AttrNameToString{
+			MakeBazelTarget("java_library", "java-protos", AttrNameToString{
 				"exports":   `[":java-protos_java_proto_lite"]`,
 				"javacopts": `["-source 1.7 -target 1.7"]`,
 			}),
diff --git a/bp2build/linker_config_conversion_test.go b/bp2build/linker_config_conversion_test.go
index 3b8a363..5e7bcd4 100644
--- a/bp2build/linker_config_conversion_test.go
+++ b/bp2build/linker_config_conversion_test.go
@@ -25,7 +25,7 @@
 	t.Helper()
 	(&tc).ModuleTypeUnderTest = "linker_config"
 	(&tc).ModuleTypeUnderTestFactory = linkerconfig.LinkerConfigFactory
-	runBp2BuildTestCaseSimple(t, tc)
+	RunBp2BuildTestCaseSimple(t, tc)
 }
 
 func TestLinkerConfigConvertsSrc(t *testing.T) {
@@ -37,7 +37,7 @@
 	src: "a.json",
 }
 `,
-			ExpectedBazelTargets: []string{makeBazelTarget("linker_config", "foo", AttrNameToString{
+			ExpectedBazelTargets: []string{MakeBazelTarget("linker_config", "foo", AttrNameToString{
 				"src": `"a.json"`,
 			})},
 		})
diff --git a/bp2build/ndk_headers_conversion_test.go b/bp2build/ndk_headers_conversion_test.go
new file mode 100644
index 0000000..c7cc6b2
--- /dev/null
+++ b/bp2build/ndk_headers_conversion_test.go
@@ -0,0 +1,164 @@
+// Copyright 2022 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 (
+	"fmt"
+	"testing"
+
+	"android/soong/cc"
+)
+
+func TestNdkHeaderFilepaths(t *testing.T) {
+	bpTemplate := `
+	ndk_headers {
+		name: "foo",
+		srcs: %v,
+		exclude_srcs: %v,
+	}
+	`
+	testCases := []struct {
+		desc         string
+		srcs         string
+		excludeSrcs  string
+		expectedHdrs string
+	}{
+		{
+			desc:         "Single header file",
+			srcs:         `["foo.h"]`,
+			excludeSrcs:  `[]`,
+			expectedHdrs: `["foo.h"]`,
+		},
+		{
+			desc:        "Multiple header files",
+			srcs:        `["foo.h", "foo_other.h"]`,
+			excludeSrcs: `[]`,
+			expectedHdrs: `[
+        "foo.h",
+        "foo_other.h",
+    ]`,
+		},
+		{
+			desc:         "Multiple header files with excludes",
+			srcs:         `["foo.h", "foo_other.h"]`,
+			excludeSrcs:  `["foo_other.h"]`,
+			expectedHdrs: `["foo.h"]`,
+		},
+		{
+			desc:        "Multiple header files via Soong-supported globs",
+			srcs:        `["*.h"]`,
+			excludeSrcs: `[]`,
+			expectedHdrs: `[
+        "foo.h",
+        "foo_other.h",
+    ]`,
+		},
+	}
+	for _, testCase := range testCases {
+		fs := map[string]string{
+			"foo.h":       "",
+			"foo_other.h": "",
+		}
+		expectedApiContributionTargetName := "foo.contribution"
+		expectedBazelTarget := MakeBazelTargetNoRestrictions(
+			"cc_api_headers",
+			expectedApiContributionTargetName,
+			AttrNameToString{
+				"hdrs": testCase.expectedHdrs,
+			},
+		)
+		RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+			Description:          testCase.desc,
+			Blueprint:            fmt.Sprintf(bpTemplate, testCase.srcs, testCase.excludeSrcs),
+			ExpectedBazelTargets: []string{expectedBazelTarget},
+			Filesystem:           fs,
+		})
+	}
+}
+
+func TestNdkHeaderIncludeDir(t *testing.T) {
+	bpTemplate := `
+	ndk_headers {
+		name: "foo",
+		from: %v,
+		to: "this/value/is/ignored",
+	}
+	`
+	testCases := []struct {
+		desc               string
+		from               string
+		expectedIncludeDir string
+	}{
+		{
+			desc:               "Empty `from` value",
+			from:               `""`,
+			expectedIncludeDir: `""`,
+		},
+		{
+			desc:               "Non-Empty `from` value",
+			from:               `"include"`,
+			expectedIncludeDir: `"include"`,
+		},
+	}
+	for _, testCase := range testCases {
+		expectedApiContributionTargetName := "foo.contribution"
+		expectedBazelTarget := MakeBazelTargetNoRestrictions(
+			"cc_api_headers",
+			expectedApiContributionTargetName,
+			AttrNameToString{
+				"include_dir": testCase.expectedIncludeDir,
+			},
+		)
+		RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+			Description:          testCase.desc,
+			Blueprint:            fmt.Sprintf(bpTemplate, testCase.from),
+			ExpectedBazelTargets: []string{expectedBazelTarget},
+		})
+	}
+}
+
+func TestVersionedNdkHeaderFilepaths(t *testing.T) {
+	bp := `
+	versioned_ndk_headers {
+		name: "common_libc",
+		from: "include"
+	}
+	`
+	fs := map[string]string{
+		"include/math.h":    "",
+		"include/stdio.h":   "",
+		"include/arm/arm.h": "",
+		"include/x86/x86.h": "",
+	}
+	expectedApiContributionTargetName := "common_libc.contribution"
+	expectedBazelTarget := MakeBazelTargetNoRestrictions(
+		"cc_api_headers",
+		expectedApiContributionTargetName,
+		AttrNameToString{
+			"include_dir": `"include"`,
+			"hdrs": `[
+        "include/math.h",
+        "include/stdio.h",
+        "include/arm/arm.h",
+        "include/x86/x86.h",
+    ]`,
+		},
+	)
+	RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+		Blueprint:            bp,
+		Filesystem:           fs,
+		ExpectedBazelTargets: []string{expectedBazelTarget},
+	})
+}
diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go
index fce4c74..aa0a5b7 100644
--- a/bp2build/prebuilt_etc_conversion_test.go
+++ b/bp2build/prebuilt_etc_conversion_test.go
@@ -15,10 +15,11 @@
 package bp2build
 
 import (
+	"fmt"
+	"testing"
+
 	"android/soong/android"
 	"android/soong/etc"
-
-	"testing"
 )
 
 func runPrebuiltEtcTestCase(t *testing.T, tc Bp2buildTestCase) {
@@ -45,7 +46,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
+			MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
 				"filename":    `"tz_version"`,
 				"installable": `False`,
 				"src":         `"version/tz_version"`,
@@ -75,7 +76,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
+			MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
 				"filename":    `"tz_version"`,
 				"installable": `False`,
 				"src": `select({
@@ -114,7 +115,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
+			MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
 				"filename":    `"tz_version"`,
 				"installable": `False`,
 				"src": `select({
@@ -128,6 +129,32 @@
 				"dir": `"etc/tz"`,
 			})}})
 }
+func TestPrebuiltEtcProductVariables(t *testing.T) {
+	runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+		Description: "prebuilt etc - product variables",
+		Filesystem:  map[string]string{},
+		Blueprint: `
+prebuilt_etc {
+    name: "apex_tz_version",
+    src: "version/tz_version",
+    filename: "tz_version",
+    product_variables: {
+      native_coverage: {
+        src: "src1",
+      },
+    },
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
+				"filename": `"tz_version"`,
+				"src": `select({
+        "//build/bazel/product_variables:native_coverage": "src1",
+        "//conditions:default": "version/tz_version",
+    })`,
+				"dir": `"etc"`,
+			})}})
+}
 
 func runPrebuiltUsrShareTestCase(t *testing.T, tc Bp2buildTestCase) {
 	t.Helper()
@@ -153,7 +180,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
+			MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
 				"filename":    `"tz_version"`,
 				"installable": `False`,
 				"src":         `"version/tz_version"`,
@@ -174,10 +201,148 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
+			MakeBazelTarget("prebuilt_file", "apex_tz_version", AttrNameToString{
 				"filename":    `"tz_version"`,
 				"installable": `False`,
 				"src":         `"version/tz_version"`,
 				"dir":         `"etc"`,
 			})}})
 }
+
+func TestFilenameAsProperty(t *testing.T) {
+	runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+		Description: "prebuilt_etc - filename is specified as a property ",
+		Filesystem:  map[string]string{},
+		Blueprint: `
+prebuilt_etc {
+    name: "foo",
+    src: "fooSrc",
+    filename: "fooFileName",
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("prebuilt_file", "foo", AttrNameToString{
+				"filename": `"fooFileName"`,
+				"src":      `"fooSrc"`,
+				"dir":      `"etc"`,
+			})}})
+}
+
+func TestFileNameFromSrc(t *testing.T) {
+	runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+		Description: "prebuilt_etc - filename_from_src is true  ",
+		Filesystem:  map[string]string{},
+		Blueprint: `
+prebuilt_etc {
+    name: "foo",
+    filename_from_src: true,
+    src: "fooSrc",
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("prebuilt_file", "foo", AttrNameToString{
+				"filename": `"fooSrc"`,
+				"src":      `"fooSrc"`,
+				"dir":      `"etc"`,
+			})}})
+}
+
+func TestFileNameFromSrcMultipleSrcs(t *testing.T) {
+	runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+		Description: "prebuilt_etc - filename_from_src is true but there are multiple srcs",
+		Filesystem:  map[string]string{},
+		Blueprint: `
+prebuilt_etc {
+    name: "foo",
+    filename_from_src: true,
+		arch: {
+        arm: {
+            src: "barSrc",
+        },
+        arm64: {
+            src: "bazSrc",
+        },
+	  }
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("prebuilt_file", "foo", AttrNameToString{
+				"filename_from_src": `True`,
+				"dir":               `"etc"`,
+				"src": `select({
+        "//build/bazel/platforms/arch:arm": "barSrc",
+        "//build/bazel/platforms/arch:arm64": "bazSrc",
+        "//conditions:default": None,
+    })`,
+			})}})
+}
+
+func TestFilenameFromModuleName(t *testing.T) {
+	runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+		Description: "prebuilt_etc - neither filename nor filename_from_src are specified ",
+		Filesystem:  map[string]string{},
+		Blueprint: `
+prebuilt_etc {
+    name: "foo",
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("prebuilt_file", "foo", AttrNameToString{
+				"filename": `"foo"`,
+				"dir":      `"etc"`,
+			})}})
+}
+
+func TestPrebuiltEtcProductVariableArchSrcs(t *testing.T) {
+	runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+		Description: "prebuilt etc- SRcs from arch variant product variables",
+		Filesystem:  map[string]string{},
+		Blueprint: `
+prebuilt_etc {
+    name: "foo",
+    filename: "fooFilename",
+    arch: {
+      arm: {
+        src: "armSrc",
+        product_variables: {
+          native_coverage: {
+            src: "nativeCoverageArmSrc",
+          },
+        },
+      },
+    },
+}`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("prebuilt_file", "foo", AttrNameToString{
+				"filename": `"fooFilename"`,
+				"dir":      `"etc"`,
+				"src": `select({
+        "//build/bazel/platforms/arch:arm": "armSrc",
+        "//build/bazel/product_variables:native_coverage-arm": "nativeCoverageArmSrc",
+        "//conditions:default": None,
+    })`,
+			})}})
+}
+
+func TestPrebuiltEtcProductVariableError(t *testing.T) {
+	runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+		Description: "",
+		Filesystem:  map[string]string{},
+		Blueprint: `
+prebuilt_etc {
+    name: "foo",
+    filename: "fooFilename",
+    arch: {
+      arm: {
+        src: "armSrc",
+      },
+    },
+    product_variables: {
+      native_coverage: {
+        src: "nativeCoverageArmSrc",
+      },
+    },
+}`,
+		ExpectedErr: fmt.Errorf("label attribute could not be collapsed"),
+	})
+}
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 79da5d5..e8b9bc4 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -42,7 +42,7 @@
       bazel_module: { bp2build_available: false },
     }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("py_binary", "foo", AttrNameToString{
+			MakeBazelTarget("py_binary", "foo", AttrNameToString{
 				"data":    `["files/data.txt"]`,
 				"deps":    `[":bar"]`,
 				"main":    `"a.py"`,
@@ -62,7 +62,7 @@
 }
 
 func TestPythonBinaryHostPy2(t *testing.T) {
-	runBp2BuildTestCaseSimple(t, Bp2buildTestCase{
+	RunBp2BuildTestCaseSimple(t, Bp2buildTestCase{
 		Description:                "py2 python_binary_host",
 		ModuleTypeUnderTest:        "python_binary_host",
 		ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory,
@@ -82,7 +82,7 @@
 }
 `,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("py_binary", "foo", AttrNameToString{
+			MakeBazelTarget("py_binary", "foo", AttrNameToString{
 				"python_version": `"PY2"`,
 				"imports":        `["."]`,
 				"srcs":           `["a.py"]`,
@@ -96,7 +96,7 @@
 }
 
 func TestPythonBinaryHostPy3(t *testing.T) {
-	runBp2BuildTestCaseSimple(t, Bp2buildTestCase{
+	RunBp2BuildTestCaseSimple(t, Bp2buildTestCase{
 		Description:                "py3 python_binary_host",
 		ModuleTypeUnderTest:        "python_binary_host",
 		ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory,
@@ -117,7 +117,7 @@
 `,
 		ExpectedBazelTargets: []string{
 			// python_version is PY3 by default.
-			makeBazelTarget("py_binary", "foo", AttrNameToString{
+			MakeBazelTarget("py_binary", "foo", AttrNameToString{
 				"imports": `["."]`,
 				"srcs":    `["a.py"]`,
 				"target_compatible_with": `select({
@@ -130,7 +130,7 @@
 }
 
 func TestPythonBinaryHostArchVariance(t *testing.T) {
-	runBp2BuildTestCaseSimple(t, Bp2buildTestCase{
+	RunBp2BuildTestCaseSimple(t, Bp2buildTestCase{
 		Description:                "test arch variants",
 		ModuleTypeUnderTest:        "python_binary_host",
 		ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory,
@@ -150,7 +150,7 @@
 					},
 				 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("py_binary", "foo-arm", AttrNameToString{
+			MakeBazelTarget("py_binary", "foo-arm", AttrNameToString{
 				"imports": `["."]`,
 				"srcs": `select({
         "//build/bazel/platforms/arch:arm": ["arm.py"],
diff --git a/bp2build/python_library_conversion_test.go b/bp2build/python_library_conversion_test.go
index 1d6061b..a53371d 100644
--- a/bp2build/python_library_conversion_test.go
+++ b/bp2build/python_library_conversion_test.go
@@ -35,7 +35,7 @@
 func convertPythonLibTestCaseToBp2build(tc pythonLibBp2BuildTestCase) Bp2buildTestCase {
 	var bp2BuildTargets []string
 	for _, t := range tc.expectedBazelTargets {
-		bp2BuildTargets = append(bp2BuildTargets, makeBazelTarget(t.typ, t.name, t.attrs))
+		bp2BuildTargets = append(bp2BuildTargets, MakeBazelTarget(t.typ, t.name, t.attrs))
 	}
 	// Copy the filesystem so that we can change stuff in it later without it
 	// affecting the original pythonLibBp2BuildTestCase
@@ -66,7 +66,7 @@
 	testCase.ModuleTypeUnderTest = "python_library"
 	testCase.ModuleTypeUnderTestFactory = python.PythonLibraryFactory
 
-	runBp2BuildTestCaseSimple(t, testCase)
+	RunBp2BuildTestCaseSimple(t, testCase)
 }
 
 func runPythonLibraryHostTestCase(t *testing.T, tc pythonLibBp2BuildTestCase) {
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index d8f701d..92b3a65 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -66,7 +66,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("sh_binary", "foo", AttrNameToString{
+			MakeBazelTarget("sh_binary", "foo", AttrNameToString{
 				"srcs":     `["foo.sh"]`,
 				"filename": `"foo.exe"`,
 				"sub_dir":  `"sub"`,
@@ -85,7 +85,7 @@
     bazel_module: { bp2build_available: true },
 }`,
 		ExpectedBazelTargets: []string{
-			makeBazelTarget("sh_binary", "foo", AttrNameToString{
+			MakeBazelTarget("sh_binary", "foo", AttrNameToString{
 				"srcs": `["foo.sh"]`,
 			})},
 	})
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 0f321de..ac1268c 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -71,7 +71,7 @@
 	return false
 }
 
-func runBp2BuildTestCaseSimple(t *testing.T, tc Bp2buildTestCase) {
+func RunBp2BuildTestCaseSimple(t *testing.T, tc Bp2buildTestCase) {
 	t.Helper()
 	RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
 }
@@ -384,6 +384,9 @@
 func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTargets, []error) {
 	// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
 	res, err := GenerateBazelTargets(codegenCtx, false)
+	if err != nil {
+		return BazelTargets{}, err
+	}
 	return res.buildFileToTargets[dir], err
 }
 
@@ -444,6 +447,6 @@
 
 // makeBazelTargetNoRestrictions returns bazel target build file definition that is device specific
 // as this is the most common default in Soong.
-func makeBazelTarget(typ, name string, attrs AttrNameToString) string {
+func MakeBazelTarget(typ, name string, attrs AttrNameToString) string {
 	return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported)
 }
diff --git a/cc/Android.bp b/cc/Android.bp
index 2963c77..1ead99b 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -45,7 +45,6 @@
         "snapshot_utils.go",
         "stl.go",
         "strip.go",
-        "sysprop.go",
         "tidy.go",
         "util.go",
         "vendor_snapshot.go",
diff --git a/cc/binary.go b/cc/binary.go
index 849aafa..3351fd7 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -18,6 +18,7 @@
 	"path/filepath"
 
 	"android/soong/bazel/cquery"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
@@ -591,7 +592,7 @@
 	handler.module.linker.(*binaryDecorator).unstrippedOutputFile = outputFilePath
 }
 
-func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) {
+func binaryBp2buildAttrs(ctx android.TopDownMutatorContext, m *Module) binaryAttributes {
 	baseAttrs := bp2BuildParseBaseProps(ctx, m)
 	binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
 
@@ -601,7 +602,7 @@
 		baseAttrs.implementationDeps.Add(baseAttrs.protoDependency)
 	}
 
-	attrs := &binaryAttributes{
+	attrs := binaryAttributes{
 		binaryLinkerAttrs: binaryLinkerAttrs,
 
 		Srcs:    baseAttrs.srcs,
@@ -644,12 +645,19 @@
 		sdkAttributes: bp2BuildParseSdkAttributes(m),
 	}
 
+	return attrs
+}
+
+func binaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+	// shared with cc_test
+	binaryAttrs := binaryBp2buildAttrs(ctx, m)
+
 	ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
 		Rule_class:        "cc_binary",
 		Bzl_load_location: "//build/bazel/rules/cc:cc_binary.bzl",
 	},
 		android.CommonAttributes{Name: m.Name()},
-		attrs)
+		&binaryAttrs)
 }
 
 // binaryAttributes contains Bazel attributes corresponding to a cc binary
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 77aaec1..a2e0a31 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -723,15 +723,23 @@
 	(&compilerAttrs.srcs).Add(bp2BuildYasm(ctx, module, compilerAttrs))
 
 	protoDep := bp2buildProto(ctx, module, compilerAttrs.protoSrcs)
-	aidlDep := bp2buildCcAidlLibrary(ctx, module, compilerAttrs.aidlSrcs)
 
 	// bp2buildProto will only set wholeStaticLib or implementationWholeStaticLib, but we don't know
 	// which. This will add the newly generated proto library to the appropriate attribute and nothing
 	// to the other
 	(&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib)
 	(&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib)
-	// TODO(b/243023967) Add aidlDep to implementationWholeArchiveDeps if aidl.export_aidl_headers is true
-	(&linkerAttrs).wholeArchiveDeps.Add(aidlDep)
+
+	aidlDep := bp2buildCcAidlLibrary(ctx, module, compilerAttrs.aidlSrcs)
+	if aidlDep != nil {
+		if lib, ok := module.linker.(*libraryDecorator); ok {
+			if proptools.Bool(lib.Properties.Aidl.Export_aidl_headers) {
+				(&linkerAttrs).wholeArchiveDeps.Add(aidlDep)
+			} else {
+				(&linkerAttrs).implementationWholeArchiveDeps.Add(aidlDep)
+			}
+		}
+	}
 
 	convertedLSrcs := bp2BuildLex(ctx, module.Name(), compilerAttrs)
 	(&compilerAttrs).srcs.Add(&convertedLSrcs.srcName)
@@ -1026,11 +1034,17 @@
 		depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
 	}
 
+	// an intermediate attribute that holds Header_libs info, and will be appended to
+	// implementationDeps at the end, to solve the confliction that both header_libs
+	// and static_libs use implementationDeps.
+	var headerDeps bazel.LabelListAttribute
+
 	productVarToDepFields := map[string]productVarDep{
 		// product variables do not support exclude_shared_libs
 		"Shared_libs":       {attribute: &la.implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
 		"Static_libs":       {"Exclude_static_libs", &la.implementationDeps, bazelLabelForStaticDepsExcludes},
 		"Whole_static_libs": {"Exclude_static_libs", &la.wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
+		"Header_libs":       {attribute: &headerDeps, depResolutionFunc: bazelLabelForHeaderDepsExcludes},
 	}
 
 	for name, dep := range productVarToDepFields {
@@ -1072,14 +1086,18 @@
 			)
 		}
 	}
+	la.implementationDeps.Append(headerDeps)
 }
 
 func (la *linkerAttributes) finalize(ctx android.BazelConversionPathContext) {
 	// if system dynamic deps have the default value, any use of a system dynamic library used will
 	// result in duplicate library errors for bionic OSes. Here, we explicitly exclude those libraries
-	// from bionic OSes.
+	// from bionic OSes and the no config case as these libraries only build for bionic OSes.
 	if la.systemDynamicDeps.IsNil() && len(la.usedSystemDynamicDepAsDynamicDep) > 0 {
 		toRemove := bazelLabelForSharedDeps(ctx, android.SortedStringKeys(la.usedSystemDynamicDepAsDynamicDep))
+		la.dynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
+		la.implementationDynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
+		la.implementationDynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
 		la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "android", toRemove)
 		la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "linux_bionic", toRemove)
 		la.implementationDynamicDeps.Exclude(bazel.OsConfigurationAxis, "android", toRemove)
@@ -1200,6 +1218,12 @@
 	return bazelLabelForSharedDeps(ctx, modules)
 }
 
+func bazelLabelForHeaderDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+	// This is only used when product_variable header_libs is processed, to follow
+	// the pattern of depResolutionFunc
+	return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
+}
+
 func bazelLabelForSharedDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
 	return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
 }
diff --git a/cc/cc.go b/cc/cc.go
index cded946..d42ab6d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -51,7 +51,6 @@
 		ctx.BottomUp("test_per_src", TestPerSrcMutator).Parallel()
 		ctx.BottomUp("version", versionMutator).Parallel()
 		ctx.BottomUp("begin", BeginMutator).Parallel()
-		ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel()
 	})
 
 	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -485,6 +484,7 @@
 	static() bool
 	staticBinary() bool
 	testBinary() bool
+	testLibrary() bool
 	header() bool
 	binary() bool
 	object() bool
@@ -1486,6 +1486,10 @@
 	return ctx.mod.testBinary()
 }
 
+func (ctx *moduleContextImpl) testLibrary() bool {
+	return ctx.mod.testLibrary()
+}
+
 func (ctx *moduleContextImpl) header() bool {
 	return ctx.mod.Header()
 }
@@ -2387,18 +2391,8 @@
 		}
 	}
 
-	// sysprop_library has to support both C++ and Java. So sysprop_library internally creates one
-	// C++ implementation library and one Java implementation library. When a module links against
-	// sysprop_library, the C++ implementation library has to be linked. syspropImplLibraries is a
-	// map from sysprop_library to implementation library; it will be used in whole_static_libs,
-	// static_libs, and shared_libs.
-	syspropImplLibraries := syspropImplLibraries(actx.Config())
-
 	for _, lib := range deps.WholeStaticLibs {
 		depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true, reexportFlags: true}
-		if impl, ok := syspropImplLibraries[lib]; ok {
-			lib = impl
-		}
 
 		lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
 
@@ -2416,10 +2410,6 @@
 			depTag.excludeInApex = true
 		}
 
-		if impl, ok := syspropImplLibraries[lib]; ok {
-			lib = impl
-		}
-
 		lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
 
 		actx.AddVariationDependencies([]blueprint.Variation{
@@ -2449,10 +2439,6 @@
 			depTag.excludeInApex = true
 		}
 
-		if impl, ok := syspropImplLibraries[lib]; ok {
-			lib = impl
-		}
-
 		name, version := StubsLibNameAndVersion(lib)
 		sharedLibNames = append(sharedLibNames, name)
 
@@ -3376,6 +3362,15 @@
 	return false
 }
 
+func (c *Module) testLibrary() bool {
+	if test, ok := c.linker.(interface {
+		testLibrary() bool
+	}); ok {
+		return test.testLibrary()
+	}
+	return false
+}
+
 func (c *Module) benchmarkBinary() bool {
 	if b, ok := c.linker.(interface {
 		benchmarkBinary() bool
@@ -3654,13 +3649,25 @@
 	staticLibrary
 	sharedLibrary
 	headerLibrary
+	testBin // testBinary already declared
 )
 
 func (c *Module) typ() moduleType {
-	if c.Binary() {
+	if c.testBinary() {
+		// testBinary is also a binary, so this comes before the c.Binary()
+		// conditional. A testBinary has additional implicit dependencies and
+		// other test-only semantics.
+		return testBin
+	} else if c.Binary() {
 		return binary
 	} else if c.Object() {
 		return object
+	} else if c.testLibrary() {
+		// TODO(b/244431896) properly convert cc_test_library to its own macro. This
+		// will let them add implicit compile deps on gtest, for example.
+		//
+		// For now, treat them as regular shared libraries.
+		return sharedLibrary
 	} else if c.CcLibrary() {
 		static := false
 		shared := false
@@ -3689,7 +3696,11 @@
 	switch c.typ() {
 	case binary:
 		if !prebuilt {
-			binaryBp2build(ctx, c, ctx.ModuleType())
+			binaryBp2build(ctx, c)
+		}
+	case testBin:
+		if !prebuilt {
+			testBinaryBp2build(ctx, c)
 		}
 	case object:
 		if !prebuilt {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 5d569cc..01ac133 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4386,3 +4386,93 @@
 		})
 	}
 }
+
+func TestCcBuildBrokenClangAsFlags(t *testing.T) {
+	tests := []struct {
+		name                    string
+		clangAsFlags            []string
+		BuildBrokenClangAsFlags bool
+		err                     string
+	}{
+		{
+			name:         "error when clang_asflags is set",
+			clangAsFlags: []string{"-a", "-b"},
+			err:          "clang_asflags: property is deprecated",
+		},
+		{
+			name:                    "no error when BuildBrokenClangAsFlags is explicitly set to true",
+			clangAsFlags:            []string{"-a", "-b"},
+			BuildBrokenClangAsFlags: true,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			bp := fmt.Sprintf(`
+			cc_library {
+			   name: "foo",
+			   clang_asflags: %s,
+			}`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
+
+			if test.err == "" {
+				android.GroupFixturePreparers(
+					prepareForCcTest,
+					android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+						if test.BuildBrokenClangAsFlags {
+							variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
+						}
+					}),
+				).RunTestWithBp(t, bp)
+			} else {
+				prepareForCcTest.
+					ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
+					RunTestWithBp(t, bp)
+			}
+		})
+	}
+}
+
+func TestCcBuildBrokenClangCFlags(t *testing.T) {
+	tests := []struct {
+		name                   string
+		clangCFlags            []string
+		BuildBrokenClangCFlags bool
+		err                    string
+	}{
+		{
+			name:        "error when clang_cflags is set",
+			clangCFlags: []string{"-a", "-b"},
+			err:         "clang_cflags: property is deprecated",
+		},
+		{
+			name:                   "no error when BuildBrokenClangCFlags is explicitly set to true",
+			clangCFlags:            []string{"-a", "-b"},
+			BuildBrokenClangCFlags: true,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			bp := fmt.Sprintf(`
+			cc_library {
+			   name: "foo",
+			   clang_cflags: %s,
+			}`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
+
+			if test.err == "" {
+				android.GroupFixturePreparers(
+					prepareForCcTest,
+					android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+						if test.BuildBrokenClangCFlags {
+							variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
+						}
+					}),
+				).RunTestWithBp(t, bp)
+			} else {
+				prepareForCcTest.
+					ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
+					RunTestWithBp(t, bp)
+			}
+		})
+	}
+}
diff --git a/cc/compiler.go b/cc/compiler.go
index 3c904b8..a751754 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -441,12 +441,24 @@
 	// TODO: debug
 	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Release.Cflags)...)
 
-	CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
-	CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
+	if !ctx.DeviceConfig().BuildBrokenClangCFlags() && len(compiler.Properties.Clang_cflags) != 0 {
+		ctx.PropertyErrorf("clang_cflags", "property is deprecated, see Changes.md file")
+	} else {
+		CheckBadCompilerFlags(ctx, "clang_cflags", compiler.Properties.Clang_cflags)
+	}
+	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() && len(compiler.Properties.Clang_asflags) != 0 {
+		ctx.PropertyErrorf("clang_asflags", "property is deprecated, see Changes.md file")
+	} else {
+		CheckBadCompilerFlags(ctx, "clang_asflags", compiler.Properties.Clang_asflags)
+	}
 
 	flags.Local.CFlags = config.ClangFilterUnknownCflags(flags.Local.CFlags)
-	flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...)
-	flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...)
+	if !ctx.DeviceConfig().BuildBrokenClangCFlags() {
+		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Clang_cflags)...)
+	}
+	if !ctx.DeviceConfig().BuildBrokenClangAsFlags() {
+		flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Clang_asflags)...)
+	}
 	flags.Local.CppFlags = config.ClangFilterUnknownCflags(flags.Local.CppFlags)
 	flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
 	flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
@@ -565,7 +577,7 @@
 			flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs))
 		}
 
-		if Bool(compiler.Properties.Aidl.Generate_traces) {
+		if proptools.BoolDefault(compiler.Properties.Aidl.Generate_traces, true) {
 			flags.aidlFlags = append(flags.aidlFlags, "-t")
 		}
 
diff --git a/cc/config/bionic.go b/cc/config/bionic.go
index e87f571..a1e3851 100644
--- a/cc/config/bionic.go
+++ b/cc/config/bionic.go
@@ -15,6 +15,7 @@
 package config
 
 type toolchainBionic struct {
+	toolchainBase
 }
 
 var (
@@ -29,6 +30,12 @@
 
 func (toolchainBionic) DefaultSharedLibraries() []string { return bionicDefaultSharedLibraries }
 
+func (toolchainBionic) ShlibSuffix() string { return ".so" }
+
+func (toolchainBionic) ExecutableSuffix() string { return "" }
+
+func (toolchainBionic) AvailableLibraries() []string { return nil }
+
 func (toolchainBionic) CrtBeginStaticBinary() []string  { return bionicCrtBeginStaticBinary }
 func (toolchainBionic) CrtBeginSharedBinary() []string  { return bionicCrtBeginSharedBinary }
 func (toolchainBionic) CrtBeginSharedLibrary() []string { return bionicCrtBeginSharedLibrary }
diff --git a/cc/config/darwin_host.go b/cc/config/darwin_host.go
index 5e3f7c7..01b1e63 100644
--- a/cc/config/darwin_host.go
+++ b/cc/config/darwin_host.go
@@ -176,6 +176,8 @@
 type toolchainDarwin struct {
 	cFlags, ldFlags string
 	toolchain64Bit
+	toolchainNoCrt
+	toolchainBase
 }
 
 type toolchainDarwinX86 struct {
@@ -254,6 +256,10 @@
 	return ".dylib"
 }
 
+func (t *toolchainDarwin) ExecutableSuffix() string {
+	return ""
+}
+
 func (t *toolchainDarwin) AvailableLibraries() []string {
 	return darwinAvailableLibraries
 }
diff --git a/cc/config/global.go b/cc/config/global.go
index 357ea44..f920471 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -290,7 +290,12 @@
 		"-Wno-deprecated-non-prototype",
 	}
 
-	llvmNextExtraCommonGlobalCflags = []string{}
+	llvmNextExtraCommonGlobalCflags = []string{
+		// New warnings to be fixed after clang-r468909
+		"-Wno-error=array-parameter",     // http://b/241941550
+		"-Wno-error=deprecated-builtins", // http://b/241601211
+		"-Wno-error=deprecated",          // in external/googletest/googletest
+	}
 
 	IllegalFlags = []string{
 		"-w",
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index 232e686..23bda66 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -164,19 +164,21 @@
 const tidyDefaultNoAnalyzer = "${config.TidyDefaultGlobalChecks},-clang-analyzer-*"
 
 // This is a map of local path prefixes to the set of default clang-tidy checks
-// to be used.
+// to be used.  This is like android.IsThirdPartyPath, but with more patterns.
 // The last matched local_path_prefix should be the most specific to be used.
 var DefaultLocalTidyChecks = []PathBasedTidyCheck{
 	{"external/", tidyExternalVendor},
-	{"external/google", tidyDefault},
-	{"external/webrtc", tidyDefault},
-	{"external/googletest/", tidyExternalVendor},
 	{"frameworks/compile/mclinker/", tidyExternalVendor},
-	{"hardware/qcom", tidyExternalVendor},
+	{"hardware/", tidyExternalVendor},
+	{"hardware/google/", tidyDefault},
+	{"hardware/interfaces/", tidyDefault},
+	{"hardware/ril/", tidyDefault},
+	{"hardware/libhardware", tidyDefault}, // all 'hardware/libhardware*'
 	{"vendor/", tidyExternalVendor},
-	{"vendor/google", tidyDefault},
+	{"vendor/google", tidyDefault}, // all 'vendor/google*'
+	{"vendor/google/external/", tidyExternalVendor},
 	{"vendor/google_arc/libs/org.chromium.arc.mojom", tidyExternalVendor},
-	{"vendor/google_devices", tidyExternalVendor},
+	{"vendor/google_devices/", tidyExternalVendor}, // many have vendor code
 }
 
 var reversedDefaultLocalTidyChecks = reverseTidyChecks(DefaultLocalTidyChecks)
@@ -199,6 +201,13 @@
 	return tidyDefault
 }
 
+func NoClangTidyForDir(dir string) bool {
+	// This function depends on TidyChecksForDir, which selects tidyExternalVendor
+	// checks for external/vendor projects. For those projects we disable clang-tidy
+	// by default, unless some modules enable clang-tidy with tidy:true.
+	return TidyChecksForDir(dir) == tidyExternalVendor
+}
+
 // Returns a globally disabled tidy checks, overriding locally selected checks.
 func TidyGlobalNoChecks() string {
 	if len(globalNoCheckList) > 0 {
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 253bb06..d9eaf53 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -140,14 +140,6 @@
 	return ""
 }
 
-func (toolchainBase) ShlibSuffix() string {
-	return ".so"
-}
-
-func (toolchainBase) ExecutableSuffix() string {
-	return ""
-}
-
 func (toolchainBase) Asflags() string {
 	return ""
 }
@@ -160,16 +152,14 @@
 	return ""
 }
 
-func (toolchainBase) AvailableLibraries() []string {
-	return nil
-}
+type toolchainNoCrt struct{}
 
-func (toolchainBase) CrtBeginStaticBinary() []string  { return nil }
-func (toolchainBase) CrtBeginSharedBinary() []string  { return nil }
-func (toolchainBase) CrtBeginSharedLibrary() []string { return nil }
-func (toolchainBase) CrtEndStaticBinary() []string    { return nil }
-func (toolchainBase) CrtEndSharedBinary() []string    { return nil }
-func (toolchainBase) CrtEndSharedLibrary() []string   { return nil }
+func (toolchainNoCrt) CrtBeginStaticBinary() []string  { return nil }
+func (toolchainNoCrt) CrtBeginSharedBinary() []string  { return nil }
+func (toolchainNoCrt) CrtBeginSharedLibrary() []string { return nil }
+func (toolchainNoCrt) CrtEndStaticBinary() []string    { return nil }
+func (toolchainNoCrt) CrtEndSharedBinary() []string    { return nil }
+func (toolchainNoCrt) CrtEndSharedLibrary() []string   { return nil }
 
 func (toolchainBase) DefaultSharedLibraries() []string {
 	return nil
@@ -188,7 +178,6 @@
 }
 
 type toolchain64Bit struct {
-	toolchainBase
 }
 
 func (toolchain64Bit) Is64Bit() bool {
@@ -196,7 +185,6 @@
 }
 
 type toolchain32Bit struct {
-	toolchainBase
 }
 
 func (toolchain32Bit) Is64Bit() bool {
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 4e8fd77..1b126de 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -158,6 +158,7 @@
 }
 
 type toolchainLinux struct {
+	toolchainBase
 	cFlags, ldFlags string
 }
 
@@ -247,9 +248,18 @@
 	return linuxAvailableLibraries
 }
 
+func (toolchainLinux) ShlibSuffix() string {
+	return ".so"
+}
+
+func (toolchainLinux) ExecutableSuffix() string {
+	return ""
+}
+
 // glibc specialization of the linux toolchain
 
 type toolchainGlibc struct {
+	toolchainNoCrt
 }
 
 func (toolchainGlibc) Glibc() bool { return true }
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index 2c83211..a33606f 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -153,6 +153,8 @@
 
 type toolchainWindows struct {
 	cFlags, ldFlags string
+	toolchainBase
+	toolchainNoCrt
 }
 
 type toolchainWindowsX86 struct {
diff --git a/cc/lto.go b/cc/lto.go
index 455ff7e..b3e5e74 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -101,6 +101,7 @@
 		}
 
 		flags.Local.CFlags = append(flags.Local.CFlags, ltoCFlag)
+		flags.Local.AsFlags = append(flags.Local.AsFlags, ltoCFlag)
 		flags.Local.LdFlags = append(flags.Local.LdFlags, ltoCFlag)
 		flags.Local.LdFlags = append(flags.Local.LdFlags, ltoLdFlag)
 
@@ -140,12 +141,13 @@
 	lib32 := ctx.Arch().ArchType.Multilib == "lib32"
 	// CFI enables full LTO.
 	cfi := ctx.isCfi()
-	// Performance and binary size are less important for host binaries.
+	// Performance and binary size are less important for host binaries and tests.
 	host := ctx.Host()
+	test := ctx.testBinary() || ctx.testLibrary()
 	// FIXME: ThinLTO for VNDK produces different output.
 	// b/169217596
 	vndk := ctx.isVndk()
-	return GlobalThinLTO(ctx) && !lto.Never() && !lib32 && !cfi && !host && !vndk
+	return GlobalThinLTO(ctx) && !lto.Never() && !lib32 && !cfi && !host && !test && !vndk
 }
 
 func (lto *lto) FullLTO() bool {
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index ef38a06..5e06948 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -19,8 +19,10 @@
 	"path/filepath"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
+	"android/soong/bazel"
 )
 
 var (
@@ -79,6 +81,7 @@
 
 type headerModule struct {
 	android.ModuleBase
+	android.BazelModuleBase
 
 	properties headerProperties
 
@@ -144,6 +147,47 @@
 	}
 }
 
+const (
+	apiContributionSuffix = ".contribution"
+)
+
+// apiContributionTargetName returns the name of the cc_api(headers|contribution) bp2build target of ndk modules
+// A suffix is necessary to prevent a name collision with the base ndk_(library|header) target in the same bp2build bazel package
+func apiContributionTargetName(moduleName string) string {
+	return moduleName + apiContributionSuffix
+}
+
+// TODO(b/243196151): Populate `system` and `arch` metadata
+type bazelCcApiHeadersAttributes struct {
+	Hdrs        bazel.LabelListAttribute
+	Include_dir *string
+}
+
+func createCcApiHeadersTarget(ctx android.TopDownMutatorContext, includes []string, excludes []string, include_dir *string) {
+	props := bazel.BazelTargetModuleProperties{
+		Rule_class:        "cc_api_headers",
+		Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl",
+	}
+	attrs := &bazelCcApiHeadersAttributes{
+		Hdrs: bazel.MakeLabelListAttribute(
+			android.BazelLabelForModuleSrcExcludes(
+				ctx,
+				includes,
+				excludes,
+			),
+		),
+		Include_dir: include_dir,
+	}
+	ctx.CreateBazelTargetModule(props, android.CommonAttributes{
+		Name: apiContributionTargetName(ctx.ModuleName()),
+	}, attrs)
+}
+
+func (h *headerModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+	// Generate `cc_api_headers` target for Multi-tree API export
+	createCcApiHeadersTarget(ctx, h.properties.Srcs, h.properties.Exclude_srcs, h.properties.From)
+}
+
 // ndk_headers installs the sets of ndk headers defined in the srcs property
 // to the sysroot base + "usr/include" + to directory + directory component.
 // ndk_headers requires the license file to be specified. Example:
@@ -158,6 +202,7 @@
 	module := &headerModule{}
 	module.AddProperties(&module.properties)
 	android.InitAndroidModule(module)
+	android.InitBazelModule(module)
 	return module
 }
 
@@ -190,6 +235,7 @@
 // Note that this is really only built to handle bionic/libc/include.
 type versionedHeaderModule struct {
 	android.ModuleBase
+	android.BazelModuleBase
 
 	properties versionedHeaderProperties
 
@@ -197,6 +243,11 @@
 	licensePath  android.Path
 }
 
+// Return the glob pattern to find all .h files beneath `dir`
+func headerGlobPattern(dir string) string {
+	return filepath.Join(dir, "**", "*.h")
+}
+
 func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	if String(m.properties.License) == "" {
 		ctx.PropertyErrorf("license", "field is required")
@@ -206,7 +257,7 @@
 
 	fromSrcPath := android.PathForModuleSrc(ctx, String(m.properties.From))
 	toOutputPath := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To))
-	srcFiles := ctx.GlobFiles(filepath.Join(fromSrcPath.String(), "**/*.h"), nil)
+	srcFiles := ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil)
 	var installPaths []android.WritablePath
 	for _, header := range srcFiles {
 		installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To))
@@ -222,6 +273,13 @@
 	processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths)
 }
 
+func (h *versionedHeaderModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+	// Glob all .h files under `From`
+	includePattern := headerGlobPattern(proptools.String(h.properties.From))
+	// Generate `cc_api_headers` target for Multi-tree API export
+	createCcApiHeadersTarget(ctx, []string{includePattern}, []string{}, h.properties.From)
+}
+
 func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path,
 	srcFiles android.Paths, installPaths []android.WritablePath) android.Path {
 	// The versioner depends on a dependencies directory to simplify determining include paths
@@ -271,16 +329,19 @@
 	module.AddProperties(&module.properties)
 
 	android.InitAndroidModule(module)
+	android.InitBazelModule(module)
 
 	return module
 }
 
-//	preprocessed_ndk_header {
-//	    name: "foo",
-//	    preprocessor: "foo.sh",
-//	    srcs: [...],
-//	    to: "android",
-//	}
+// preprocessed_ndk_header {
+//
+//	name: "foo",
+//	preprocessor: "foo.sh",
+//	srcs: [...],
+//	to: "android",
+//
+// }
 //
 // Will invoke the preprocessor as:
 //
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 6c200f5..622558e 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -57,15 +57,18 @@
 )
 
 func init() {
-	android.RegisterModuleType("ndk_headers", ndkHeadersFactory)
-	android.RegisterModuleType("ndk_library", NdkLibraryFactory)
-	android.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory)
-	android.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory)
-	android.RegisterSingletonType("ndk", NdkSingleton)
-
+	RegisterNdkModuleTypes(android.InitRegistrationContext)
 	pctx.Import("android/soong/android")
 }
 
+func RegisterNdkModuleTypes(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("ndk_headers", ndkHeadersFactory)
+	ctx.RegisterModuleType("ndk_library", NdkLibraryFactory)
+	ctx.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory)
+	ctx.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory)
+	ctx.RegisterSingletonType("ndk", NdkSingleton)
+}
+
 func getNdkInstallBase(ctx android.PathContext) android.InstallPath {
 	return android.PathForNdkInstall(ctx)
 }
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 86472a2..436b149 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -77,6 +77,7 @@
 		"-fno-sanitize-recover=integer,undefined"}
 	hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512",
 		"export_memory_stats=0", "max_malloc_fill_size=4096", "malloc_fill_byte=0"}
+	memtagStackCommonFlags = []string{"-march=armv8-a+memtag"}
 )
 
 type SanitizerType int
@@ -89,6 +90,7 @@
 	scs
 	Fuzzer
 	Memtag_heap
+	Memtag_stack
 	cfi // cfi is last to prevent it running before incompatible mutators
 )
 
@@ -100,6 +102,7 @@
 	scs,
 	Fuzzer,
 	Memtag_heap,
+	Memtag_stack,
 	cfi, // cfi is last to prevent it running before incompatible mutators
 }
 
@@ -120,6 +123,8 @@
 		return "scs"
 	case Memtag_heap:
 		return "memtag_heap"
+	case Memtag_stack:
+		return "memtag_stack"
 	case Fuzzer:
 		return "fuzzer"
 	default:
@@ -136,6 +141,8 @@
 		return "hwaddress"
 	case Memtag_heap:
 		return "memtag_heap"
+	case Memtag_stack:
+		return "memtag_stack"
 	case tsan:
 		return "thread"
 	case intOverflow:
@@ -157,7 +164,7 @@
 		sanitizer := &sanitizerSplitMutator{t}
 		ctx.TopDown(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
 		ctx.Transition(t.variationName(), sanitizer)
-	case Memtag_heap, intOverflow:
+	case Memtag_heap, Memtag_stack, intOverflow:
 		// do nothing
 	default:
 		panic(fmt.Errorf("unknown SanitizerType %d", t))
@@ -182,6 +189,8 @@
 		return true
 	case Memtag_heap:
 		return true
+	case Memtag_stack:
+		return true
 	default:
 		return false
 	}
@@ -233,6 +242,9 @@
 	// Memory-tagging, only available on arm64
 	// if diag.memtag unset or false, enables async memory tagging
 	Memtag_heap *bool `android:"arch_variant"`
+	// Memory-tagging stack instrumentation, only available on arm64
+	// Adds instrumentation to detect stack buffer overflows and use-after-scope using MTE.
+	Memtag_stack *bool `android:"arch_variant"`
 
 	// A modifier for ASAN and HWASAN for write only instrumentation
 	Writeonly *bool `android:"arch_variant"`
@@ -318,7 +330,7 @@
 		return
 	}
 
-	// cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap}).
+	// cc_test targets default to SYNC MemTag unless explicitly set to ASYNC (via diag: {memtag_heap: false}).
 	if ctx.testBinary() {
 		if s.Memtag_heap == nil {
 			s.Memtag_heap = proptools.BoolPtr(true)
@@ -404,6 +416,10 @@
 			}
 		}
 
+		if found, globalSanitizers = removeFromList("memtag_stack", globalSanitizers); found && s.Memtag_stack == nil {
+			s.Memtag_stack = proptools.BoolPtr(true)
+		}
+
 		if len(globalSanitizers) > 0 {
 			ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
 		}
@@ -470,14 +486,19 @@
 	}
 
 	// Memtag_heap is only implemented on AArch64.
-	if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
+	// Memtag ABI is Android specific for now, so disable for host.
+	if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() || ctx.Host() {
 		s.Memtag_heap = nil
+		s.Memtag_stack = nil
 	}
 
 	// Also disable CFI if ASAN is enabled.
 	if Bool(s.Address) || Bool(s.Hwaddress) {
 		s.Cfi = nil
 		s.Diag.Cfi = nil
+		// HWASAN and ASAN win against MTE.
+		s.Memtag_heap = nil
+		s.Memtag_stack = nil
 	}
 
 	// Disable sanitizers that depend on the UBSan runtime for windows/darwin builds.
@@ -534,7 +555,7 @@
 
 	if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
 		Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
-		Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap)) {
+		Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs) || Bool(s.Memtag_heap) || Bool(s.Memtag_stack)) {
 		sanitize.Properties.SanitizerEnabled = true
 	}
 
@@ -691,6 +712,25 @@
 		}
 	}
 
+	if Bool(sanitize.Properties.Sanitize.Memtag_stack) {
+		flags.Local.CFlags = append(flags.Local.CFlags, memtagStackCommonFlags...)
+		// TODO(fmayer): remove -Wno-error once https://reviews.llvm.org/D127917 is in Android toolchain.
+		flags.Local.CFlags = append(flags.Local.CFlags, "-Wno-error=frame-larger-than")
+		flags.Local.AsFlags = append(flags.Local.AsFlags, memtagStackCommonFlags...)
+		flags.Local.LdFlags = append(flags.Local.LdFlags, memtagStackCommonFlags...)
+		// This works around LLD complaining about the stack frame size.
+		// TODO(fmayer): remove once https://reviews.llvm.org/D127917 is in Android toolchain.
+		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-fatal-warnings")
+	}
+
+	if (Bool(sanitize.Properties.Sanitize.Memtag_heap) || Bool(sanitize.Properties.Sanitize.Memtag_stack)) && ctx.binary() {
+		if Bool(sanitize.Properties.Sanitize.Diag.Memtag_heap) {
+			flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=sync")
+		} else {
+			flags.Local.LdFlags = append(flags.Local.LdFlags, "-fsanitize-memtag-mode=async")
+		}
+	}
+
 	if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
 		flags.Local.CFlags = append(flags.Local.CFlags, intOverflowCflags...)
 	}
@@ -804,6 +844,8 @@
 		return sanitize.Properties.Sanitize.Scs
 	case Memtag_heap:
 		return sanitize.Properties.Sanitize.Memtag_heap
+	case Memtag_stack:
+		return sanitize.Properties.Sanitize.Memtag_stack
 	case Fuzzer:
 		return sanitize.Properties.Sanitize.Fuzzer
 	default:
@@ -819,6 +861,7 @@
 		!sanitize.isSanitizerEnabled(cfi) &&
 		!sanitize.isSanitizerEnabled(scs) &&
 		!sanitize.isSanitizerEnabled(Memtag_heap) &&
+		!sanitize.isSanitizerEnabled(Memtag_stack) &&
 		!sanitize.isSanitizerEnabled(Fuzzer)
 }
 
@@ -850,6 +893,8 @@
 		sanitize.Properties.Sanitize.Scs = bPtr
 	case Memtag_heap:
 		sanitize.Properties.Sanitize.Memtag_heap = bPtr
+	case Memtag_stack:
+		sanitize.Properties.Sanitize.Memtag_stack = bPtr
 	case Fuzzer:
 		sanitize.Properties.Sanitize.Fuzzer = bPtr
 	default:
@@ -1311,23 +1356,11 @@
 		}
 
 		if Bool(c.sanitize.Properties.Sanitize.Memtag_heap) && c.Binary() {
-			noteDep := "note_memtag_heap_async"
-			if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
-				noteDep = "note_memtag_heap_sync"
-			}
-			// If we're using snapshots, redirect to snapshot whenever possible
-			// TODO(b/178470649): clean manual snapshot redirections
-			snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
-			if lib, ok := snapshot.StaticLibs[noteDep]; ok {
-				noteDep = lib
-			}
-			depTag := StaticDepTag(true)
-			variations := append(mctx.Target().Variations(),
-				blueprint.Variation{Mutator: "link", Variation: "static"})
-			if c.Device() {
-				variations = append(variations, c.ImageVariation())
-			}
-			mctx.AddFarVariationDependencies(variations, depTag, noteDep)
+			sanitizers = append(sanitizers, "memtag-heap")
+		}
+
+		if Bool(c.sanitize.Properties.Sanitize.Memtag_stack) {
+			sanitizers = append(sanitizers, "memtag-stack")
 		}
 
 		if Bool(c.sanitize.Properties.Sanitize.Fuzzer) {
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 5d7e7d8..48ac650 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -344,19 +344,13 @@
 
 func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) {
 	t.Helper()
-	note_async := "note_memtag_heap_async"
-	note_sync := "note_memtag_heap_sync"
 
 	found := None
-	implicits := m.Rule("ld").Implicits
-	for _, lib := range implicits {
-		if strings.Contains(lib.Rel(), note_async) {
-			found = Async
-			break
-		} else if strings.Contains(lib.Rel(), note_sync) {
-			found = Sync
-			break
-		}
+	ldFlags := m.Rule("ld").Args["ldFlags"]
+	if strings.Contains(ldFlags, "-fsanitize-memtag-mode=async") {
+		found = Async
+	} else if strings.Contains(ldFlags, "-fsanitize-memtag-mode=sync") {
+		found = Sync
 	}
 
 	if found != expected {
diff --git a/cc/sysprop.go b/cc/sysprop.go
deleted file mode 100644
index f578b50..0000000
--- a/cc/sysprop.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// 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
-
-// This file contains a map to redirect dependencies towards sysprop_library.
-// As sysprop_library has to support both Java and C++, sysprop_library internally
-// generates cc_library and java_library. For example, the following sysprop_library
-//
-//     sysprop_library {
-//         name: "foo",
-//     }
-//
-// will internally generate with prefix "lib"
-//
-//     cc_library {
-//         name: "libfoo",
-//     }
-//
-// When a cc module links against "foo", build system will redirect the
-// dependency to "libfoo". To do that, SyspropMutator gathers all sysprop_library,
-// records their cc implementation library names to a map. The map will be used in
-// cc.Module.DepsMutator.
-
-import (
-	"sync"
-
-	"android/soong/android"
-)
-
-type syspropLibraryInterface interface {
-	BaseModuleName() string
-	CcImplementationModuleName() string
-}
-
-var (
-	syspropImplLibrariesKey  = android.NewOnceKey("syspropImplLibirares")
-	syspropImplLibrariesLock sync.Mutex
-)
-
-func syspropImplLibraries(config android.Config) map[string]string {
-	return config.Once(syspropImplLibrariesKey, func() interface{} {
-		return make(map[string]string)
-	}).(map[string]string)
-}
-
-// gather list of sysprop libraries
-func SyspropMutator(mctx android.BottomUpMutatorContext) {
-	if m, ok := mctx.Module().(syspropLibraryInterface); ok {
-		syspropImplLibraries := syspropImplLibraries(mctx.Config())
-		syspropImplLibrariesLock.Lock()
-		defer syspropImplLibrariesLock.Unlock()
-
-		// BaseModuleName is the name of sysprop_library
-		// CcImplementationModuleName is the name of cc_library generated by sysprop_library
-		syspropImplLibraries[m.BaseModuleName()] = m.CcImplementationModuleName()
-	}
-}
diff --git a/cc/test.go b/cc/test.go
index f5abc45..28a0e5e 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -22,6 +22,7 @@
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
+	"android/soong/bazel"
 	"android/soong/tradefed"
 )
 
@@ -133,7 +134,7 @@
 // specific functionality on a device. The executable binary gets an implicit
 // static_libs dependency on libgtests unless the gtest flag is set to false.
 func TestFactory() android.Module {
-	module := NewTest(android.HostAndDeviceSupported)
+	module := NewTest(android.HostAndDeviceSupported, true)
 	return module.Init()
 }
 
@@ -156,7 +157,7 @@
 
 // cc_test_host compiles a test host binary.
 func TestHostFactory() android.Module {
-	module := NewTest(android.HostSupported)
+	module := NewTest(android.HostSupported, true)
 	return module.Init()
 }
 
@@ -204,6 +205,10 @@
 	test.binaryDecorator.Properties.Stem = StringPtr("")
 }
 
+func (test *testBinary) testBinary() bool {
+	return true
+}
+
 var _ testPerSrc = (*testBinary)(nil)
 
 func TestPerSrcMutator(mctx android.BottomUpMutatorContext) {
@@ -257,16 +262,10 @@
 }
 
 func (test *testDecorator) isolated(ctx BaseModuleContext) bool {
-	if !ctx.Windows() {
-		return BoolDefault(test.LinkerProperties.Isolated, false)
-	}
 	return BoolDefault(test.LinkerProperties.Isolated, false)
 }
 
-func (test *testDecorator) testBinary() bool {
-	return true
-}
-
+// NOTE: Keep this in sync with cc/cc_test.bzl#gtest_copts
 func (test *testDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
 	if !test.gtest() {
 		return flags
@@ -480,8 +479,8 @@
 	test.binaryDecorator.baseInstaller.install(ctx, file)
 }
 
-func NewTest(hod android.HostOrDeviceSupported) *Module {
-	module, binary := newBinary(hod, false)
+func NewTest(hod android.HostOrDeviceSupported, bazelable bool) *Module {
+	module, binary := newBinary(hod, bazelable)
 	module.multilib = android.MultilibBoth
 	binary.baseInstaller = NewTestInstaller()
 
@@ -504,6 +503,10 @@
 	*libraryDecorator
 }
 
+func (test *testLibrary) testLibrary() bool {
+	return true
+}
+
 func (test *testLibrary) linkerProps() []interface{} {
 	var props []interface{}
 	props = append(props, test.testDecorator.linkerProps()...)
@@ -543,6 +546,7 @@
 	}
 	module.linker = test
 	module.installer = test
+	module.bazelable = true
 	return module
 }
 
@@ -632,3 +636,60 @@
 	module.installer = benchmark
 	return module
 }
+
+// binaryAttributes contains Bazel attributes corresponding to a cc test
+type testBinaryAttributes struct {
+	binaryAttributes
+
+	Gtest    bool
+	Isolated bool
+}
+
+// testBinaryBp2build is the bp2build converter for cc_test modules. A cc_test's
+// dependency graph and compilation/linking steps are functionally similar to a
+// cc_binary, but has additional dependencies on test deps like gtest, and
+// produces additional runfiles like XML plans for Tradefed orchestration
+//
+// TODO(b/244432609): handle `isolated` property.
+// TODO(b/244432134): handle custom runpaths for tests that assume runfile layouts not
+// default to bazel. (see linkerInit function)
+// TODO(b/244432500): handle test.testConfig generation (see install function)
+func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+	var testBinaryAttrs testBinaryAttributes
+	testBinaryAttrs.binaryAttributes = binaryBp2buildAttrs(ctx, m)
+
+	var data bazel.LabelListAttribute
+
+	testBinaryProps := m.GetArchVariantProperties(ctx, &TestBinaryProperties{})
+	for axis, configToProps := range testBinaryProps {
+		for config, props := range configToProps {
+			if p, ok := props.(*TestBinaryProperties); ok {
+				// Combine data, data_bins and data_libs into a single 'data' attribute.
+				var combinedData bazel.LabelList
+				combinedData.Append(android.BazelLabelForModuleSrc(ctx, p.Data))
+				combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_bins))
+				combinedData.Append(android.BazelLabelForModuleDeps(ctx, p.Data_libs))
+				data.SetSelectValue(axis, config, combinedData)
+			}
+		}
+	}
+
+	for _, propIntf := range m.GetProperties() {
+		if testLinkerProps, ok := propIntf.(*TestLinkerProperties); ok {
+			testBinaryAttrs.Gtest = proptools.BoolDefault(testLinkerProps.Gtest, true)
+			testBinaryAttrs.Isolated = proptools.BoolDefault(testLinkerProps.Isolated, true)
+			break
+		}
+	}
+
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "cc_test",
+			Bzl_load_location: "//build/bazel/rules/cc:cc_test.bzl",
+		},
+		android.CommonAttributes{
+			Name: m.Name(),
+			Data: data,
+		},
+		&testBinaryAttrs)
+}
diff --git a/cc/tidy.go b/cc/tidy.go
index 6b5d572..082cf88 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -76,7 +76,11 @@
 	if tidy.Properties.Tidy != nil && !*tidy.Properties.Tidy {
 		return flags
 	}
-
+	// Some projects like external/* and vendor/* have clang-tidy disabled by default.
+	// They can enable clang-tidy explicitly with the "tidy:true" property.
+	if config.NoClangTidyForDir(ctx.ModuleDir()) && !proptools.Bool(tidy.Properties.Tidy) {
+		return flags
+	}
 	// If not explicitly disabled, set flags.Tidy to generate .tidy rules.
 	// Note that libraries and binaries will depend on .tidy files ONLY if
 	// the global WITH_TIDY or module 'tidy' property is true.
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index cb85634..b06e4fe 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -176,10 +176,6 @@
 
 	build.SetupOutDir(buildCtx, config)
 
-	if config.UseBazel() && config.Dist() {
-		defer populateExternalDistDir(buildCtx, config)
-	}
-
 	// Set up files to be outputted in the log directory.
 	logsDir := config.LogsDir()
 
diff --git a/docs/perf.md b/docs/perf.md
index 86a27b4..694dcf1 100644
--- a/docs/perf.md
+++ b/docs/perf.md
@@ -221,6 +221,18 @@
 various .ninja files. The files are (mostly) human-readable, but a (slow) web
 interface can be used by running `NINJA_ARGS="-t browse <target>" m`.
 
+There is also `SOONG_UI_NINJA_ARGS`, which passes ninja arguments to soong ui's
+ninja invocations, e.g. to emit $OUT_DIR/soong/build.ninja, $OUT_DIR/soong/module-graph.json, etc.
+
+```bash
+$ m nothing
+$ touch Android.bp
+$ SOONG_UI_NINJA_ARGS="-d explain" m nothing
+...
+ninja explain: restat of output out/soong/build.ninja older than most recent input Android.bp
+...
+```
+
 #### Builds take a long time
 
 If the long part in the trace view of a build is a relatively solid block, then
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 719771f..7520f58 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -31,6 +31,7 @@
 	"encoding/json"
 	"fmt"
 	"path/filepath"
+	"reflect"
 	"strings"
 
 	"github.com/google/blueprint/proptools"
@@ -670,10 +671,11 @@
 // For Bazel / bp2build
 
 type bazelPrebuiltFileAttributes struct {
-	Src         bazel.LabelAttribute
-	Filename    string
-	Dir         string
-	Installable bazel.BoolAttribute
+	Src               bazel.LabelAttribute
+	Filename          bazel.LabelAttribute
+	Dir               string
+	Installable       bazel.BoolAttribute
+	Filename_from_src bazel.BoolAttribute
 }
 
 // ConvertWithBp2build performs bp2build conversion of PrebuiltEtc
@@ -691,11 +693,37 @@
 				src.SetSelectValue(axis, config, label)
 			}
 		}
+
+		for propName, productConfigProps := range android.ProductVariableProperties(ctx) {
+			for configProp, propVal := range productConfigProps {
+				if propName == "Src" {
+					props, ok := propVal.(*string)
+					if !ok {
+						ctx.PropertyErrorf(" Expected Property to have type string, but was %s\n", reflect.TypeOf(propVal).String())
+						continue
+					}
+					if props != nil {
+						label := android.BazelLabelForModuleSrcSingle(ctx, *props)
+						src.SetSelectValue(configProp.ConfigurationAxis(), configProp.SelectKey(), label)
+					}
+				}
+			}
+		}
 	}
 
 	var filename string
-	if module.properties.Filename != nil {
-		filename = *module.properties.Filename
+	var filenameFromSrc bool
+	moduleProps := module.properties
+
+	if moduleProps.Filename != nil && *moduleProps.Filename != "" {
+		filename = *moduleProps.Filename
+	} else if moduleProps.Filename_from_src != nil && *moduleProps.Filename_from_src {
+		if moduleProps.Src != nil {
+			filename = *moduleProps.Src
+		}
+		filenameFromSrc = true
+	} else {
+		filename = ctx.ModuleName()
 	}
 
 	var dir = module.installDirBase
@@ -714,11 +742,16 @@
 
 	attrs := &bazelPrebuiltFileAttributes{
 		Src:         src,
-		Filename:    filename,
 		Dir:         dir,
 		Installable: installable,
 	}
 
+	if filename != "" {
+		attrs.Filename = bazel.LabelAttribute{Value: &bazel.Label{Label: filename}}
+	} else if filenameFromSrc {
+		attrs.Filename_from_src = bazel.BoolAttribute{Value: moduleProps.Filename_from_src}
+	}
+
 	props := bazel.BazelTargetModuleProperties{
 		Rule_class:        "prebuilt_file",
 		Bzl_load_location: "//build/bazel/rules:prebuilt_file.bzl",
diff --git a/java/base.go b/java/base.go
index febf321..23b4d46 100644
--- a/java/base.go
+++ b/java/base.go
@@ -169,6 +169,8 @@
 		Output_params []string
 	}
 
+	// If true, then jacocoagent is automatically added as a libs dependency so that
+	// r8 will not strip instrumentation classes out of dexed libraries.
 	Instrument bool `blueprint:"mutated"`
 	// If true, then the module supports statically including the jacocoagent
 	// into the library.
@@ -648,6 +650,10 @@
 	return false
 }
 
+func (j *Module) setInstrument(value bool) {
+	j.properties.Instrument = value
+}
+
 func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
 	return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
 }
@@ -1432,10 +1438,6 @@
 		j.headerJarFile = j.implementationJarFile
 	}
 
-	if j.shouldInstrumentInApex(ctx) {
-		j.properties.Instrument = true
-	}
-
 	// enforce syntax check to jacoco filters for any build (http://b/183622051)
 	specs := j.jacocoModuleToZipCommand(ctx)
 	if ctx.Failed() {
diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go
index f95c83f..c63df59 100644
--- a/java/bootclasspath_fragment_test.go
+++ b/java/bootclasspath_fragment_test.go
@@ -96,11 +96,6 @@
 }
 
 func TestBootclasspathFragment_Coverage(t *testing.T) {
-	prepareForTestWithFrameworkCoverage := android.FixtureMergeEnv(map[string]string{
-		"EMMA_INSTRUMENT":           "true",
-		"EMMA_INSTRUMENT_FRAMEWORK": "true",
-	})
-
 	prepareWithBp := android.FixtureWithRootAndroidBp(`
 		bootclasspath_fragment {
 			name: "myfragment",
@@ -179,7 +174,7 @@
 
 	t.Run("with coverage", func(t *testing.T) {
 		result := android.GroupFixturePreparers(
-			prepareForTestWithFrameworkCoverage,
+			prepareForTestWithFrameworkJacocoInstrumentation,
 			preparer,
 		).RunTest(t)
 		checkContents(t, result, "mybootlib", "coveragelib")
diff --git a/java/config/config.go b/java/config/config.go
index 3ca9bad..b026d73 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -124,6 +124,10 @@
 		// This is set up and guaranteed by soong_ui
 		return ctx.Config().Getenv("ANDROID_JAVA_HOME")
 	})
+	pctx.VariableFunc("Java11Home", func(ctx android.PackageVarContext) string {
+		// This is set up and guaranteed by soong_ui
+		return ctx.Config().Getenv("ANDROID_JAVA11_HOME")
+	})
 	pctx.VariableFunc("JlinkVersion", func(ctx android.PackageVarContext) string {
 		if override := ctx.Config().Getenv("OVERRIDE_JLINK_VERSION_NUMBER"); override != "" {
 			return override
@@ -137,18 +141,19 @@
 	})
 
 	pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
+	pctx.SourcePathVariable("Java11Toolchain", "${Java11Home}/bin")
 	pctx.SourcePathVariableWithEnvOverride("JavacCmd",
 		"${JavaToolchain}/javac", "ALTERNATE_JAVAC")
 	pctx.SourcePathVariable("JavaCmd", "${JavaToolchain}/java")
 	pctx.SourcePathVariable("JarCmd", "${JavaToolchain}/jar")
-	pctx.SourcePathVariable("JavadocCmd", "${JavaToolchain}/javadoc")
+	pctx.SourcePathVariable("JavadocCmd", "${Java11Toolchain}/javadoc")
 	pctx.SourcePathVariable("JlinkCmd", "${JavaToolchain}/jlink")
 	pctx.SourcePathVariable("JmodCmd", "${JavaToolchain}/jmod")
 	pctx.SourcePathVariable("JrtFsJar", "${JavaHome}/lib/jrt-fs.jar")
 	pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar")
 	pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
 
-	pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file.py")
+	pctx.HostBinToolVariable("GenKotlinBuildFileCmd", "gen-kotlin-build-file")
 
 	pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")
 	pctx.SourcePathVariable("PackageCheckCmd", "build/soong/scripts/package-check.sh")
@@ -267,7 +272,7 @@
 
 // JavadocCmd returns a SourcePath object with the path to the java command.
 func JavadocCmd(ctx android.PathContext) android.SourcePath {
-	return javaTool(ctx, "javadoc")
+	return java11Tool(ctx, "javadoc")
 }
 
 func javaTool(ctx android.PathContext, tool string) android.SourcePath {
@@ -281,6 +286,17 @@
 
 }
 
+func java11Tool(ctx android.PathContext, tool string) android.SourcePath {
+	type javaToolKey string
+
+	key := android.NewCustomOnceKey(javaToolKey(tool))
+
+	return ctx.Config().OnceSourcePath(key, func() android.SourcePath {
+		return java11Toolchain(ctx).Join(ctx, tool)
+	})
+
+}
+
 var javaToolchainKey = android.NewOnceKey("javaToolchain")
 
 func javaToolchain(ctx android.PathContext) android.SourcePath {
@@ -289,6 +305,14 @@
 	})
 }
 
+var java11ToolchainKey = android.NewOnceKey("java11Toolchain")
+
+func java11Toolchain(ctx android.PathContext) android.SourcePath {
+	return ctx.Config().OnceSourcePath(java11ToolchainKey, func() android.SourcePath {
+		return java11Home(ctx).Join(ctx, "bin")
+	})
+}
+
 var javaHomeKey = android.NewOnceKey("javaHome")
 
 func javaHome(ctx android.PathContext) android.SourcePath {
@@ -297,3 +321,12 @@
 		return android.PathForSource(ctx, ctx.Config().Getenv("ANDROID_JAVA_HOME"))
 	})
 }
+
+var java11HomeKey = android.NewOnceKey("java11Home")
+
+func java11Home(ctx android.PathContext) android.SourcePath {
+	return ctx.Config().OnceSourcePath(java11HomeKey, func() android.SourcePath {
+		// This is set up and guaranteed by soong_ui
+		return android.PathForSource(ctx, ctx.Config().Getenv("ANDROID_JAVA11_HOME"))
+	})
+}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 9b1f43b..fc95184 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -755,6 +755,7 @@
 	return rule.Command().
 		BuiltTool("dokka").
 		Flag(config.JavacVmFlags).
+		Flag("-J--add-opens=java.base/java.lang=ALL-UNNAMED").
 		Flag(srcJarDir.String()).
 		FlagWithInputList("-classpath ", dokkaClasspath, ":").
 		FlagWithArg("-format ", "dac").
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 12590ca..d9efb40 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"path/filepath"
+	"regexp"
 	"strings"
 
 	"github.com/google/blueprint/proptools"
@@ -142,6 +143,10 @@
 	// if set to true, collect the values used by the Dev tools and
 	// write them in files packaged with the SDK. Defaults to false.
 	Write_sdk_values *bool
+
+	// path or filegroup to file defining extension an SDK name <-> numerical ID mapping and
+	// what APIs exist in which SDKs; passed to metalava via --sdk-extensions-info
+	Extensions_info_file *string `android:"path"`
 }
 
 // Used by xsd_config
@@ -398,9 +403,20 @@
 	filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
 
 	var dirs []string
+	var extensions_dir string
 	ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
 		if t, ok := m.(*ExportedDroiddocDir); ok {
+			extRegex := regexp.MustCompile(t.dir.String() + `/extensions/[0-9]+/public/.*\.jar`)
+
+			// Grab the first extensions_dir and we find while scanning ExportedDroiddocDir.deps;
+			// ideally this should be read from prebuiltApis.properties.Extensions_*
 			for _, dep := range t.deps {
+				if extRegex.MatchString(dep.String()) && d.properties.Extensions_info_file != nil {
+					if extensions_dir == "" {
+						extensions_dir = t.dir.String() + "/extensions"
+					}
+					cmd.Implicit(dep)
+				}
 				if dep.Base() == filename {
 					cmd.Implicit(dep)
 				}
@@ -445,6 +461,16 @@
 			cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, filename))
 		}
 	}
+
+	if d.properties.Extensions_info_file != nil {
+		if extensions_dir == "" {
+			ctx.ModuleErrorf("extensions_info_file set, but no SDK extension dirs found")
+		}
+		info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
+		cmd.Implicit(info_file)
+		cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
+		cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
+	}
 }
 
 func metalavaUseRbe(ctx android.ModuleContext) bool {
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 9fdfdde..2443692 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -259,3 +259,33 @@
 		t.Errorf("inputs of %q must be []string{%q}, but was %#v.", moduleName, systemJar, systemJars)
 	}
 }
+
+func TestDroidstubsWithSdkExtensions(t *testing.T) {
+	ctx, _ := testJavaWithFS(t, `
+		droiddoc_exported_dir {
+			name: "sdk-dir",
+			path: "sdk",
+		}
+
+		droidstubs {
+			name: "baz-stubs",
+			api_levels_annotations_dirs: ["sdk-dir"],
+			api_levels_annotations_enabled: true,
+			extensions_info_file: ":info-file",
+		}
+
+		filegroup {
+			name: "info-file",
+			srcs: ["sdk/extensions/info.txt"],
+		}
+		`,
+		map[string][]byte{
+			"sdk/extensions/1/public/some-mainline-module-stubs.jar": nil,
+			"sdk/extensions/info.txt":                                nil,
+		})
+	m := ctx.ModuleForTests("baz-stubs", "android_common")
+	manifest := m.Output("metalava.sbox.textproto")
+	cmdline := String(android.RuleBuilderSboxProtoForTests(t, manifest).Commands[0].Command)
+	android.AssertStringDoesContain(t, "sdk-extensions-root present", cmdline, "--sdk-extensions-root sdk/extensions")
+	android.AssertStringDoesContain(t, "sdk-extensions-info present", cmdline, "--sdk-extensions-info sdk/extensions/info.txt")
+}
diff --git a/java/jacoco.go b/java/jacoco.go
index e11c2ce..f8012b8 100644
--- a/java/jacoco.go
+++ b/java/jacoco.go
@@ -47,6 +47,34 @@
 		"strippedJar", "stripSpec", "tmpDir", "tmpJar")
 )
 
+func jacocoDepsMutator(ctx android.BottomUpMutatorContext) {
+	type instrumentable interface {
+		shouldInstrument(ctx android.BaseModuleContext) bool
+		shouldInstrumentInApex(ctx android.BaseModuleContext) bool
+		setInstrument(value bool)
+	}
+
+	j, ok := ctx.Module().(instrumentable)
+	if !ctx.Module().Enabled() || !ok {
+		return
+	}
+
+	if j.shouldInstrumentInApex(ctx) {
+		j.setInstrument(true)
+	}
+
+	if j.shouldInstrument(ctx) && ctx.ModuleName() != "jacocoagent" {
+		// We can use AddFarVariationDependencies here because, since this dep
+		// is added as libs only (i.e. a compiletime CLASSPATH entry only),
+		// the first variant of jacocoagent is sufficient to prevent
+		// compile time errors.
+		// At this stage in the build, AddVariationDependencies is not always
+		// able to procure a variant of jacocoagent that matches the calling
+		// module.
+		ctx.AddFarVariationDependencies(ctx.Module().Target().Variations(), libTag, "jacocoagent")
+	}
+}
+
 // Instruments a jar using the Jacoco command line interface.  Uses stripSpec to extract a subset
 // of the classes in inputJar into strippedJar, instruments strippedJar into tmpJar, and then
 // combines the classes in tmpJar with inputJar (preferring the instrumented classes in tmpJar)
diff --git a/java/java.go b/java/java.go
index 0251b57..d04e52a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -66,6 +66,8 @@
 	// to support the checks in dexpreoptDisabled().
 	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel()
+		// needs access to ApexInfoProvider which is available after variant creation
+		ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel()
 	})
 
 	ctx.RegisterSingletonType("logtags", LogtagsSingleton)
diff --git a/java/testing.go b/java/testing.go
index 511cc5d..1f41191 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -59,11 +59,9 @@
 	}.AddToFixture(),
 )
 
-// Test fixture preparer that will define all default java modules except the
-// fake_tool_binary for dex2oatd.
-var PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd = android.GroupFixturePreparers(
-	// Make sure that all the module types used in the defaults are registered.
-	PrepareForTestWithJavaBuildComponents,
+var prepareForTestWithFrameworkDeps = android.GroupFixturePreparers(
+	// The java default module definitions.
+	android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()),
 	// Additional files needed when test disallows non-existent source.
 	android.MockFS{
 		// Needed for framework-res
@@ -77,8 +75,14 @@
 		"build/make/core/proguard.flags":             nil,
 		"build/make/core/proguard_basic_keeps.flags": nil,
 	}.AddToFixture(),
-	// The java default module definitions.
-	android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()),
+)
+
+// Test fixture preparer that will define all default java modules except the
+// fake_tool_binary for dex2oatd.
+var PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd = android.GroupFixturePreparers(
+	// Make sure that all the module types used in the defaults are registered.
+	PrepareForTestWithJavaBuildComponents,
+	prepareForTestWithFrameworkDeps,
 	// Add dexpreopt compat libs (android.test.base, etc.) and a fake dex2oatd module.
 	dexpreopt.PrepareForTestWithDexpreoptCompatLibs,
 )
@@ -141,6 +145,30 @@
 	"30": {},
 })
 
+var prepareForTestWithFrameworkJacocoInstrumentation = android.GroupFixturePreparers(
+	android.FixtureMergeEnv(map[string]string{
+		"EMMA_INSTRUMENT_FRAMEWORK": "true",
+	}),
+	PrepareForTestWithJacocoInstrumentation,
+)
+
+// PrepareForTestWithJacocoInstrumentation creates a mock jacocoagent library that can be
+// depended on as part of the build process for instrumented Java modules.
+var PrepareForTestWithJacocoInstrumentation = android.GroupFixturePreparers(
+	android.FixtureMergeEnv(map[string]string{
+		"EMMA_INSTRUMENT": "true",
+	}),
+	android.FixtureAddFile("jacocoagent/Test.java", nil),
+	android.FixtureAddFile("jacocoagent/Android.bp", []byte(`
+		java_library {
+			name: "jacocoagent",
+			host_supported: true,
+			srcs: ["Test.java"],
+			sdk_version: "current",
+		}
+	`)),
+)
+
 // FixtureWithPrebuiltApis creates a preparer that will define prebuilt api modules for the
 // specified releases and modules.
 //
diff --git a/multitree/api_imports.go b/multitree/api_imports.go
index 2c4cf80..6674d3e 100644
--- a/multitree/api_imports.go
+++ b/multitree/api_imports.go
@@ -16,6 +16,7 @@
 
 import (
 	"android/soong/android"
+	"strings"
 
 	"github.com/google/blueprint"
 )
@@ -26,6 +27,7 @@
 
 func init() {
 	RegisterApiImportsModule(android.InitRegistrationContext)
+	android.RegisterMakeVarsProvider(pctx, makeVarsProvider)
 }
 
 func RegisterApiImportsModule(ctx android.RegistrationContext) {
@@ -86,3 +88,12 @@
 func GetApiImportSuffix() string {
 	return apiImportNameSuffix
 }
+
+func makeVarsProvider(ctx android.MakeVarsContext) {
+	ctx.VisitAllModules(func(m android.Module) {
+		if i, ok := m.(*ApiImports); ok {
+			ctx.Strict("API_IMPORTED_SHARED_LIBRARIES", strings.Join(i.properties.Shared_libs, " "))
+			ctx.Strict("API_IMPORTED_HEADER_LIBRARIES", strings.Join(i.properties.Header_libs, " "))
+		}
+	})
+}
diff --git a/python/scripts/stub_template_host.txt b/python/scripts/stub_template_host.txt
index 138404b..23897b3 100644
--- a/python/scripts/stub_template_host.txt
+++ b/python/scripts/stub_template_host.txt
@@ -81,7 +81,9 @@
     os.environ.update(new_env)
 
     sys.stdout.flush()
-    retCode = subprocess.call(args)
+    # close_fds=False so that you can run binaries with files provided on the command line:
+    # my_python_app --file <(echo foo)
+    retCode = subprocess.call(args, close_fds=False)
     sys.exit(retCode)
   except:
     raise
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 814bd57..b5b588b 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -168,7 +168,7 @@
 }
 
 python_binary_host {
-    name: "gen-kotlin-build-file.py",
+    name: "gen-kotlin-build-file",
     main: "gen-kotlin-build-file.py",
     srcs: [
         "gen-kotlin-build-file.py",
diff --git a/symbol_inject/cmd/symbol_inject.go b/symbol_inject/cmd/symbol_inject.go
index 1397b37..89b3619 100644
--- a/symbol_inject/cmd/symbol_inject.go
+++ b/symbol_inject/cmd/symbol_inject.go
@@ -94,4 +94,13 @@
 		os.Remove(*output)
 		os.Exit(5)
 	}
+
+	if file.IsMachoFile {
+		err = symbol_inject.CodeSignMachoFile(*output)
+		if err != nil {
+			fmt.Fprintln(os.Stderr, err.Error())
+			os.Remove(*output)
+			os.Exit(6)
+		}
+	}
 }
diff --git a/symbol_inject/macho.go b/symbol_inject/macho.go
index 6ee3f4f..9946d34 100644
--- a/symbol_inject/macho.go
+++ b/symbol_inject/macho.go
@@ -18,6 +18,7 @@
 	"debug/macho"
 	"fmt"
 	"io"
+	"os/exec"
 	"sort"
 	"strings"
 )
@@ -40,7 +41,7 @@
 		return symbols[i].Value < symbols[j].Value
 	})
 
-	file := &File{}
+	file := &File{IsMachoFile: true}
 
 	for _, section := range machoFile.Sections {
 		file.Sections = append(file.Sections, &Section{
@@ -95,3 +96,8 @@
 
 	return nil
 }
+
+func CodeSignMachoFile(path string) error {
+	cmd := exec.Command("/usr/bin/codesign", "--force", "-s", "-", path)
+	return cmd.Run()
+}
diff --git a/symbol_inject/symbol_inject.go b/symbol_inject/symbol_inject.go
index 2a3d67e..77aff6f 100644
--- a/symbol_inject/symbol_inject.go
+++ b/symbol_inject/symbol_inject.go
@@ -161,9 +161,10 @@
 }
 
 type File struct {
-	r        io.ReaderAt
-	Symbols  []*Symbol
-	Sections []*Section
+	r           io.ReaderAt
+	Symbols     []*Symbol
+	Sections    []*Section
+	IsMachoFile bool
 }
 
 type Symbol struct {
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
index 1d5eb31..e5263fe 100644
--- a/sysprop/Android.bp
+++ b/sysprop/Android.bp
@@ -9,6 +9,7 @@
         "blueprint",
         "soong",
         "soong-android",
+        "soong-bp2build",
         "soong-cc",
         "soong-java",
     ],
@@ -18,6 +19,7 @@
     ],
     testSrcs: [
         "sysprop_test.go",
+        "sysprop_library_conversion_test.go",
     ],
     pluginFor: ["soong_build"],
 }
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index a29d4c3..578dc2b 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -23,6 +23,7 @@
 	"path"
 	"sync"
 
+	"android/soong/bazel"
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
@@ -125,6 +126,7 @@
 type syspropLibrary struct {
 	android.ModuleBase
 	android.ApexModuleBase
+	android.BazelModuleBase
 
 	properties syspropLibraryProperties
 
@@ -363,7 +365,10 @@
 // sysprop_library creates schematized APIs from sysprop description files (.sysprop).
 // Both Java and C++ modules can link against sysprop_library, and API stability check
 // against latest APIs (see build/soong/scripts/freeze-sysprop-api-files.sh)
-// is performed.
+// is performed. Note that the generated C++ module has its name prefixed with
+// `lib`, and it is this module that should be depended on from other C++
+// modules; i.e., if the sysprop_library module is named `foo`, C++ modules
+// should depend on `libfoo`.
 func syspropLibraryFactory() android.Module {
 	m := &syspropLibrary{}
 
@@ -372,6 +377,7 @@
 	)
 	android.InitAndroidModule(m)
 	android.InitApexModule(m)
+	android.InitBazelModule(m)
 	android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
 	return m
 }
@@ -403,6 +409,9 @@
 	Host_supported     *bool
 	Apex_available     []string
 	Min_sdk_version    *string
+	Bazel_module       struct {
+		Bp2build_available *bool
+	}
 }
 
 type javaLibraryProperties struct {
@@ -483,6 +492,11 @@
 	ccProps.Host_supported = m.properties.Host_supported
 	ccProps.Apex_available = m.ApexProperties.Apex_available
 	ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
+	// A Bazel macro handles this, so this module does not need to be handled
+	// in bp2build
+	// TODO(b/237810289) perhaps do something different here so that we aren't
+	//                   also disabling these modules in mixed builds
+	ccProps.Bazel_module.Bp2build_available = proptools.BoolPtr(false)
 	ctx.CreateModule(cc.LibraryFactory, &ccProps)
 
 	scope := "internal"
@@ -557,3 +571,45 @@
 		*libraries = append(*libraries, "//"+ctx.ModuleDir()+":"+ctx.ModuleName())
 	}
 }
+
+// TODO(b/240463568): Additional properties will be added for API validation
+type bazelSyspropLibraryAttributes struct {
+	Srcs bazel.LabelListAttribute
+}
+
+type bazelCcSyspropLibraryAttributes struct {
+	Dep             bazel.LabelAttribute
+	Min_sdk_version *string
+}
+
+func (m *syspropLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "sysprop_library",
+			Bzl_load_location: "//build/bazel/rules/sysprop:sysprop_library.bzl",
+		},
+		android.CommonAttributes{Name: m.Name()},
+		&bazelSyspropLibraryAttributes{
+			Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)),
+		})
+
+	attrs := &bazelCcSyspropLibraryAttributes{
+		Dep:             *bazel.MakeLabelAttribute(":" + m.Name()),
+		Min_sdk_version: m.properties.Cpp.Min_sdk_version,
+	}
+
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "cc_sysprop_library_shared",
+			Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
+		},
+		android.CommonAttributes{Name: m.CcImplementationModuleName()},
+		attrs)
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "cc_sysprop_library_static",
+			Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
+		},
+		android.CommonAttributes{Name: m.CcImplementationModuleName() + "_bp2build_cc_library_static"},
+		attrs)
+}
diff --git a/sysprop/sysprop_library_conversion_test.go b/sysprop/sysprop_library_conversion_test.go
new file mode 100644
index 0000000..c72faf3
--- /dev/null
+++ b/sysprop/sysprop_library_conversion_test.go
@@ -0,0 +1,110 @@
+// Copyright 2022 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 sysprop
+
+import (
+	"testing"
+
+	"android/soong/bp2build"
+)
+
+func TestSyspropLibrarySimple(t *testing.T) {
+	bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
+		Description:                "sysprop_library simple",
+		ModuleTypeUnderTest:        "sysprop_library",
+		ModuleTypeUnderTestFactory: syspropLibraryFactory,
+		Filesystem: map[string]string{
+			"foo.sysprop": "",
+			"bar.sysprop": "",
+		},
+		Blueprint: `
+sysprop_library {
+	name: "sysprop_foo",
+	srcs: [
+		"foo.sysprop",
+		"bar.sysprop",
+	],
+	property_owner: "Platform",
+}
+`,
+		ExpectedBazelTargets: []string{
+			bp2build.MakeBazelTargetNoRestrictions("sysprop_library",
+				"sysprop_foo_sysprop_library",
+				bp2build.AttrNameToString{
+					"srcs": `[
+        "foo.sysprop",
+        "bar.sysprop",
+    ]`,
+				}),
+			bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_shared",
+				"libsysprop_foo",
+				bp2build.AttrNameToString{
+					"dep": `":sysprop_foo_sysprop_library"`,
+				}),
+			bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_static",
+				"libsysprop_foo_bp2build_cc_library_static",
+				bp2build.AttrNameToString{
+					"dep": `":sysprop_foo_sysprop_library"`,
+				}),
+		},
+	})
+}
+
+func TestSyspropLibraryCppMinSdkVersion(t *testing.T) {
+	bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
+		Description:                "sysprop_library with min_sdk_version",
+		ModuleTypeUnderTest:        "sysprop_library",
+		ModuleTypeUnderTestFactory: syspropLibraryFactory,
+		Filesystem: map[string]string{
+			"foo.sysprop": "",
+			"bar.sysprop": "",
+		},
+		Blueprint: `
+sysprop_library {
+	name: "sysprop_foo",
+	srcs: [
+		"foo.sysprop",
+		"bar.sysprop",
+	],
+	cpp: {
+		min_sdk_version: "5",
+	},
+	property_owner: "Platform",
+}
+`,
+		ExpectedBazelTargets: []string{
+			bp2build.MakeBazelTargetNoRestrictions("sysprop_library",
+				"sysprop_foo_sysprop_library",
+				bp2build.AttrNameToString{
+					"srcs": `[
+        "foo.sysprop",
+        "bar.sysprop",
+    ]`,
+				}),
+			bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_shared",
+				"libsysprop_foo",
+				bp2build.AttrNameToString{
+					"dep":             `":sysprop_foo_sysprop_library"`,
+					"min_sdk_version": `"5"`,
+				}),
+			bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_static",
+				"libsysprop_foo_bp2build_cc_library_static",
+				bp2build.AttrNameToString{
+					"dep":             `":sysprop_foo_sysprop_library"`,
+					"min_sdk_version": `"5"`,
+				}),
+		},
+	})
+}
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 88ef615..80b86e0 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -209,32 +209,32 @@
 		cc_library {
 			name: "cc-client-platform",
 			srcs: ["d.cpp"],
-			static_libs: ["sysprop-platform"],
+			static_libs: ["libsysprop-platform"],
 		}
 
 		cc_library_static {
 			name: "cc-client-platform-static",
 			srcs: ["d.cpp"],
-			whole_static_libs: ["sysprop-platform"],
+			whole_static_libs: ["libsysprop-platform"],
 		}
 
 		cc_library {
 			name: "cc-client-product",
 			srcs: ["d.cpp"],
 			product_specific: true,
-			static_libs: ["sysprop-platform-on-product", "sysprop-vendor-on-product"],
+			static_libs: ["libsysprop-platform-on-product", "libsysprop-vendor-on-product"],
 		}
 
 		cc_library {
 			name: "cc-client-vendor",
 			srcs: ["d.cpp"],
 			soc_specific: true,
-			static_libs: ["sysprop-platform", "sysprop-vendor"],
+			static_libs: ["libsysprop-platform", "libsysprop-vendor"],
 		}
 
 		cc_binary_host {
 			name: "hostbin",
-			static_libs: ["sysprop-platform"],
+			static_libs: ["libsysprop-platform"],
 		}
 	`)
 
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
index ac3c177..6bc0165 100755
--- a/tests/apex_comparison_tests.sh
+++ b/tests/apex_comparison_tests.sh
@@ -60,7 +60,8 @@
 
 BAZEL_OUT="$(call_bazel info output_path)"
 
-call_bazel build --config=bp2build --config=ci --config=android_arm \
+export TARGET_PRODUCT="module_arm"
+call_bazel build --config=bp2build --config=ci --config=android \
   //packages/modules/adb/apex:com.android.adbd \
   //system/timezone/apex:com.android.tzdata \
   //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex
@@ -86,7 +87,7 @@
 
   # Compare the outputs of `deapexer list`, which lists the contents of the apex filesystem image.
   local SOONG_APEX="$SOONG_OUTPUT_DIR/$APEX"
-  local BAZEL_APEX="$BAZEL_OUT/android_arm-fastbuild/bin/$APEX_DIR/$APEX"
+  local BAZEL_APEX="$BAZEL_OUT/android_target-fastbuild/bin/$APEX_DIR/$APEX"
 
   local SOONG_LIST="$OUTPUT_DIR/soong.list"
   local BAZEL_LIST="$OUTPUT_DIR/bazel.list"
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 3cdf6aa..78af54d 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -103,7 +103,7 @@
   fi
 
   # NOTE: We don't actually use the extra BUILD file for anything here
-  run_bazel build --package_path=out/soong/workspace //foo/...
+  run_bazel build --config=android --package_path=out/soong/workspace //foo/...
 
   local the_answer_file="bazel-out/android_target-fastbuild/bin/foo/convertible_soong_module/the_answer.txt"
   if [[ ! -f "${the_answer_file}" ]]; then
@@ -146,10 +146,10 @@
 
   run_soong bp2build
 
-  run_bazel build --package_path=out/soong/workspace //a:qq
+  run_bazel build --config=android --package_path=out/soong/workspace //a:qq
   local -r output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
 
-  run_bazel build --package_path=out/soong/workspace //a:qq
+  run_bazel build --config=android --package_path=out/soong/workspace //a:qq
   local -r output_mtime2=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
 
   if [[ "$output_mtime1" != "$output_mtime2" ]]; then
@@ -160,7 +160,7 @@
 #define QQ 2
 EOF
 
-  run_bazel build --package_path=out/soong/workspace //a:qq
+  run_bazel build --config=android --package_path=out/soong/workspace //a:qq
   local -r output_mtime3=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
 
   if [[ "$output_mtime1" == "$output_mtime3" ]]; then
diff --git a/ui/build/build.go b/ui/build/build.go
index c61baa1..ff2d5f2 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -104,26 +104,20 @@
 	// Whether to run ninja on the combined ninja.
 	RunNinja = 1 << iota
 	// Whether to run bazel on the combined ninja.
-	RunBazel        = 1 << iota
-	RunBuildTests   = 1 << iota
-	RunAll          = RunProductConfig | RunSoong | RunKati | RunKatiNinja | RunNinja
-	RunAllWithBazel = RunProductConfig | RunSoong | RunKati | RunKatiNinja | RunBazel
+	RunBazel      = 1 << iota
+	RunBuildTests = 1 << iota
+	RunAll        = RunProductConfig | RunSoong | RunKati | RunKatiNinja | RunNinja
 )
 
 // checkBazelMode fails the build if there are conflicting arguments for which bazel
 // build mode to use.
 func checkBazelMode(ctx Context, config Config) {
-	// TODO(cparsons): Remove USE_BAZEL_ANALYSIS handling.
 	if config.Environment().IsEnvTrue("USE_BAZEL_ANALYSIS") {
-		if config.bazelProdMode || config.bazelDevMode {
-			ctx.Fatalf("USE_BAZEL_ANALYSIS is deprecated.\n" +
-				"Unset USE_BAZEL_ANALYSIS when using --bazel-mode or --bazel-mode-dev.")
-		} else {
-			config.bazelDevMode = true
-		}
+		ctx.Fatalln("USE_BAZEL_ANALYSIS is deprecated. Unset USE_BAZEL_ANALYSIS.\n" +
+			"Use --bazel-mode-dev instead. For example: `m --bazel-mode-dev nothing`")
 	}
 	if config.bazelProdMode && config.bazelDevMode {
-		ctx.Fatalf("Conflicting bazel mode.\n" +
+		ctx.Fatalln("Conflicting bazel mode.\n" +
 			"Do not specify both --bazel-mode and --bazel-mode-dev")
 	}
 }
@@ -256,9 +250,6 @@
 	SetupPath(ctx, config)
 
 	what := RunAll
-	if config.UseBazel() {
-		what = RunAllWithBazel
-	}
 	if config.Checkbuild() {
 		what |= RunBuildTests
 	}
diff --git a/ui/build/config.go b/ui/build/config.go
index 590aeb9..14a99d0 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -99,15 +99,9 @@
 
 	pathReplaced bool
 
-	// TODO(b/243077098): Remove useBazel.
-	useBazel      bool
 	bazelProdMode bool
 	bazelDevMode  bool
 
-	// During Bazel execution, Bazel cannot write outside OUT_DIR.
-	// So if DIST_DIR is set to an external dir (outside of OUT_DIR), we need to rig it temporarily and then migrate files at the end of the build.
-	riggedDistDirForBazel string
-
 	// Set by multiproduct_kati
 	emptyNinjaFile bool
 
@@ -439,21 +433,6 @@
 		ctx.Fatalf("Unable to remove bazel profile directory %q: %v", bpd, err)
 	}
 
-	ret.useBazel = ret.environ.IsEnvTrue("USE_BAZEL")
-
-	if ret.UseBazel() {
-		if err := os.MkdirAll(bpd, 0777); err != nil {
-			ctx.Fatalf("Failed to create bazel profile directory %q: %v", bpd, err)
-		}
-	}
-
-	if ret.UseBazel() {
-		ret.riggedDistDirForBazel = filepath.Join(ret.OutDir(), "dist")
-	} else {
-		// Not rigged
-		ret.riggedDistDirForBazel = ret.distDir
-	}
-
 	c := Config{ret}
 	storeConfigMetrics(ctx, c)
 	return c
@@ -486,7 +465,6 @@
 		ForceUseGoma:    proto.Bool(config.ForceUseGoma()),
 		UseGoma:         proto.Bool(config.UseGoma()),
 		UseRbe:          proto.Bool(config.UseRBE()),
-		BazelAsNinja:    proto.Bool(config.UseBazel()),
 		BazelMixedBuild: proto.Bool(config.BazelBuildEnabled()),
 	}
 	c.Targets = append(c.Targets, config.arguments...)
@@ -877,11 +855,7 @@
 }
 
 func (c *configImpl) DistDir() string {
-	if c.UseBazel() {
-		return c.riggedDistDirForBazel
-	} else {
-		return c.distDir
-	}
+	return c.distDir
 }
 
 func (c *configImpl) RealDistDir() string {
@@ -1129,11 +1103,6 @@
 	return false
 }
 
-// TODO(b/243077098): Remove UseBazel.
-func (c *configImpl) UseBazel() bool {
-	return c.useBazel
-}
-
 func (c *configImpl) BazelBuildEnabled() bool {
 	return c.bazelProdMode || c.bazelDevMode
 }
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 63716b0..150ec35 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -1017,7 +1017,6 @@
 				ForceUseGoma:    proto.Bool(false),
 				UseGoma:         proto.Bool(false),
 				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(false),
 				BazelMixedBuild: proto.Bool(false),
 			},
 		},
@@ -1028,7 +1027,6 @@
 				ForceUseGoma:    proto.Bool(true),
 				UseGoma:         proto.Bool(false),
 				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(false),
 				BazelMixedBuild: proto.Bool(false),
 			},
 		},
@@ -1039,7 +1037,6 @@
 				ForceUseGoma:    proto.Bool(false),
 				UseGoma:         proto.Bool(true),
 				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(false),
 				BazelMixedBuild: proto.Bool(false),
 			},
 		},
@@ -1050,7 +1047,6 @@
 				ForceUseGoma:    proto.Bool(false),
 				UseGoma:         proto.Bool(false),
 				UseRbe:          proto.Bool(true),
-				BazelAsNinja:    proto.Bool(false),
 				BazelMixedBuild: proto.Bool(false),
 			},
 		},
@@ -1062,22 +1058,10 @@
 				ForceUseGoma:    proto.Bool(false),
 				UseGoma:         proto.Bool(false),
 				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(true),
 				BazelMixedBuild: proto.Bool(false),
 			},
 		},
 		{
-			name:    "bazel mixed build from env",
-			environ: Environment{"USE_BAZEL_ANALYSIS=1"},
-			expectedBuildConfig: &smpb.BuildConfig{
-				ForceUseGoma:    proto.Bool(false),
-				UseGoma:         proto.Bool(false),
-				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(false),
-				BazelMixedBuild: proto.Bool(true),
-			},
-		},
-		{
 			name:         "bazel mixed build from dev mode",
 			environ:      Environment{},
 			bazelDevMode: true,
@@ -1085,7 +1069,6 @@
 				ForceUseGoma:    proto.Bool(false),
 				UseGoma:         proto.Bool(false),
 				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(false),
 				BazelMixedBuild: proto.Bool(true),
 			},
 		},
@@ -1097,7 +1080,6 @@
 				ForceUseGoma:    proto.Bool(false),
 				UseGoma:         proto.Bool(false),
 				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(false),
 				BazelMixedBuild: proto.Bool(true),
 			},
 		},
@@ -1110,7 +1092,6 @@
 				ForceUseGoma:    proto.Bool(false),
 				UseGoma:         proto.Bool(false),
 				UseRbe:          proto.Bool(false),
-				BazelAsNinja:    proto.Bool(true),
 				BazelMixedBuild: proto.Bool(false),
 				Targets:         []string{"droid", "dist"},
 			},
@@ -1128,7 +1109,6 @@
 				ForceUseGoma:    proto.Bool(true),
 				UseGoma:         proto.Bool(true),
 				UseRbe:          proto.Bool(true),
-				BazelAsNinja:    proto.Bool(true),
 				BazelMixedBuild: proto.Bool(true),
 			},
 		},
@@ -1139,7 +1119,6 @@
 		t.Run(tc.name, func(t *testing.T) {
 			c := &configImpl{
 				environ:       &tc.environ,
-				useBazel:      tc.useBazel,
 				bazelDevMode:  tc.bazelDevMode,
 				bazelProdMode: tc.bazelProdMode,
 				arguments:     tc.arguments,
diff --git a/ui/build/soong.go b/ui/build/soong.go
index ff6d68f..3ef77c7 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -32,7 +32,6 @@
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/bootstrap"
-	"github.com/google/blueprint/deptools"
 	"github.com/google/blueprint/microfactory"
 
 	"google.golang.org/protobuf/proto"
@@ -349,12 +348,9 @@
 			soongDocsInvocation},
 	}
 
-	bootstrapDeps := bootstrap.RunBlueprint(blueprintArgs, bootstrap.DoEverything, blueprintCtx, blueprintConfig)
-	bootstrapDepFile := shared.JoinPath(config.SoongOutDir(), "bootstrap.ninja.d")
-	err := deptools.WriteDepFile(bootstrapDepFile, blueprintArgs.OutFile, bootstrapDeps)
-	if err != nil {
-		ctx.Fatalf("Error writing depfile '%s': %s", bootstrapDepFile, err)
-	}
+	// since `bootstrap.ninja` is regenerated unconditionally, we ignore the deps, i.e. little
+	// reason to write a `bootstrap.ninja.d` file
+	_ = bootstrap.RunBlueprint(blueprintArgs, bootstrap.DoEverything, blueprintCtx, blueprintConfig)
 }
 
 func checkEnvironmentFile(currentEnv *Environment, envFile string) {