Merge "Add a property in ndk_library for header contributions"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index b0c87d4..0cdf792 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -46,19 +46,16 @@
 		"bionic":                                Bp2BuildDefaultTrueRecursively,
 		"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
 
-		"build/bazel/examples/apex/minimal":           Bp2BuildDefaultTrueRecursively,
-		"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
-		"build/bazel/examples/python":                 Bp2BuildDefaultTrueRecursively,
-		"build/bazel/examples/gensrcs":                Bp2BuildDefaultTrueRecursively,
-		"build/make/target/product/security":          Bp2BuildDefaultTrue,
-		"build/make/tools/signapk":                    Bp2BuildDefaultTrue,
-		"build/make/tools/zipalign":                   Bp2BuildDefaultTrueRecursively,
-		"build/soong":                                 Bp2BuildDefaultTrue,
-		"build/soong/cc/libbuildversion":              Bp2BuildDefaultTrue, // Skip tests subdir
-		"build/soong/cc/ndkstubgen":                   Bp2BuildDefaultTrue,
-		"build/soong/cc/symbolfile":                   Bp2BuildDefaultTrue,
-		"build/soong/linkerconfig":                    Bp2BuildDefaultTrueRecursively,
-		"build/soong/scripts":                         Bp2BuildDefaultTrueRecursively,
+		"build/bazel":                        Bp2BuildDefaultTrueRecursively,
+		"build/make/target/product/security": Bp2BuildDefaultTrue,
+		"build/make/tools/signapk":           Bp2BuildDefaultTrue,
+		"build/make/tools/zipalign":          Bp2BuildDefaultTrueRecursively,
+		"build/soong":                        Bp2BuildDefaultTrue,
+		"build/soong/cc/libbuildversion":     Bp2BuildDefaultTrue, // Skip tests subdir
+		"build/soong/cc/ndkstubgen":          Bp2BuildDefaultTrue,
+		"build/soong/cc/symbolfile":          Bp2BuildDefaultTrue,
+		"build/soong/linkerconfig":           Bp2BuildDefaultTrueRecursively,
+		"build/soong/scripts":                Bp2BuildDefaultTrueRecursively,
 
 		"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
 		"development/apps/DevelopmentSettings":        Bp2BuildDefaultTrue,
@@ -165,6 +162,9 @@
 		"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,
@@ -282,24 +282,7 @@
 		// This is actually build/bazel/build.BAZEL symlinked to ./BUILD
 		".":/*recursive = */ false,
 
-		// build/bazel/examples/apex/... BUILD files should be generated, so
-		// build/bazel is not recursive. Instead list each subdirectory under
-		// build/bazel explicitly.
-		"build/bazel":/* recursive = */ false,
-		"build/bazel/ci/dist":/* recursive = */ false,
-		"build/bazel/examples/android_app":/* recursive = */ true,
-		"build/bazel/examples/cc":/* recursive = */ true,
-		"build/bazel/examples/java":/* recursive = */ true,
-		"build/bazel/examples/partitions":/* recursive = */ true,
-		"build/bazel/bazel_skylib":/* recursive = */ true,
-		"build/bazel/rules":/* recursive = */ true,
-		"build/bazel/rules_cc":/* recursive = */ true,
-		"build/bazel/scripts":/* recursive = */ true,
-		"build/bazel/tests":/* recursive = */ true,
-		"build/bazel/platforms":/* recursive = */ true,
-		"build/bazel/product_config":/* recursive = */ true,
-		"build/bazel/product_variables":/* recursive = */ true,
-		"build/bazel/vendor/google":/* recursive = */ true,
+		"build/bazel":/* recursive = */ true,
 		"build/bazel_common_rules":/* recursive = */ true,
 		// build/make/tools/signapk BUILD file is generated, so build/make/tools is not recursive.
 		"build/make/tools":/* recursive = */ false,
@@ -444,6 +427,9 @@
 
 		//frameworks/native/libs/input
 		"inputconstants_aidl",
+
+		// needed for aidl_interface's ndk backend
+		"libbinder_ndk",
 	}
 
 	Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -546,7 +532,7 @@
 		"libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libnativetesthelper_jni, libgmock_ndk
 		"libnativetesthelper_jni",   // depends on unconverted modules: libgtest_ndk_c++
 		"libprotobuf-java-nano",     // b/220869005, depends on non-public_current SDK
-		"libstatslog",               // depends on unconverted modules: libstatspull, statsd-aidl-ndk, libbinder_ndk
+		"libstatslog",               // depends on unconverted modules: libstatspull, statsd-aidl-ndk
 		"libstatslog_art",           // depends on unconverted modules: statslog_art.cpp, statslog_art.h
 		"linker_reloc_bench_main",   // depends on unconverted modules: liblinker_reloc_bench_*
 		"pbtombstone", "crash_dump", // depends on libdebuggerd, libunwindstack
@@ -605,30 +591,8 @@
 		"libadb_pairing_connection_static",
 		"libadb_pairing_server", "libadb_pairing_server_static",
 
-		// TODO(b/204811222) support suffix in cc_binary
-		"acvp_modulewrapper",
-		"android.hardware.media.c2@1.0-service-v4l2",
-		"app_process",
-		"bar_test",
-		"bench_cxa_atexit",
-		"bench_noop",
-		"bench_noop_nostl",
-		"bench_noop_static",
-		"boringssl_self_test",
-		"boringssl_self_test_vendor",
-		"bssl",
-		"cavp",
-		"crash_dump",
+		// TODO(b/240563612) Needing `stem` selection support for cc_binary
 		"crasher",
-		"libcxx_test_template",
-		"linker",
-		"memory_replay",
-		"native_bridge_guest_linker",
-		"native_bridge_stub_library_defaults",
-		"noop",
-		"simpleperf_ndk",
-		"toybox-static",
-		"zlib_bench",
 
 		// java_import[_host] issues
 		// tradefed prebuilts depend on libprotobuf
diff --git a/android/bazel.go b/android/bazel.go
index 3ae3d6f..15729c1 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -211,7 +211,7 @@
 	return "" // no label for unconverted module
 }
 
-type bp2BuildConversionAllowlist struct {
+type Bp2BuildConversionAllowlist struct {
 	// Configure modules in these directories to enable bp2build_available: true or false by default.
 	defaultConfig allowlists.Bp2BuildConfig
 
@@ -241,14 +241,14 @@
 
 // GenerateCcLibraryStaticOnly returns whether a cc_library module should only
 // generate a static version of itself based on the current global configuration.
-func (a bp2BuildConversionAllowlist) GenerateCcLibraryStaticOnly(moduleName string) bool {
+func (a Bp2BuildConversionAllowlist) GenerateCcLibraryStaticOnly(moduleName string) bool {
 	return a.ccLibraryStaticOnly[moduleName]
 }
 
-// NewBp2BuildAllowlist creates a new, empty bp2BuildConversionAllowlist
+// NewBp2BuildAllowlist creates a new, empty Bp2BuildConversionAllowlist
 // which can be populated using builder pattern Set* methods
-func NewBp2BuildAllowlist() bp2BuildConversionAllowlist {
-	return bp2BuildConversionAllowlist{
+func NewBp2BuildAllowlist() Bp2BuildConversionAllowlist {
+	return Bp2BuildConversionAllowlist{
 		allowlists.Bp2BuildConfig{},
 		map[string]bool{},
 		map[string]bool{},
@@ -259,7 +259,7 @@
 }
 
 // SetDefaultConfig copies the entries from defaultConfig into the allowlist
-func (a bp2BuildConversionAllowlist) SetDefaultConfig(defaultConfig allowlists.Bp2BuildConfig) bp2BuildConversionAllowlist {
+func (a Bp2BuildConversionAllowlist) SetDefaultConfig(defaultConfig allowlists.Bp2BuildConfig) Bp2BuildConversionAllowlist {
 	if a.defaultConfig == nil {
 		a.defaultConfig = allowlists.Bp2BuildConfig{}
 	}
@@ -271,7 +271,7 @@
 }
 
 // SetKeepExistingBuildFile copies the entries from keepExistingBuildFile into the allowlist
-func (a bp2BuildConversionAllowlist) SetKeepExistingBuildFile(keepExistingBuildFile map[string]bool) bp2BuildConversionAllowlist {
+func (a Bp2BuildConversionAllowlist) SetKeepExistingBuildFile(keepExistingBuildFile map[string]bool) Bp2BuildConversionAllowlist {
 	if a.keepExistingBuildFile == nil {
 		a.keepExistingBuildFile = map[string]bool{}
 	}
@@ -283,7 +283,7 @@
 }
 
 // SetModuleAlwaysConvertList copies the entries from moduleAlwaysConvert into the allowlist
-func (a bp2BuildConversionAllowlist) SetModuleAlwaysConvertList(moduleAlwaysConvert []string) bp2BuildConversionAllowlist {
+func (a Bp2BuildConversionAllowlist) SetModuleAlwaysConvertList(moduleAlwaysConvert []string) Bp2BuildConversionAllowlist {
 	if a.moduleAlwaysConvert == nil {
 		a.moduleAlwaysConvert = map[string]bool{}
 	}
@@ -295,7 +295,7 @@
 }
 
 // SetModuleTypeAlwaysConvertList copies the entries from moduleTypeAlwaysConvert into the allowlist
-func (a bp2BuildConversionAllowlist) SetModuleTypeAlwaysConvertList(moduleTypeAlwaysConvert []string) bp2BuildConversionAllowlist {
+func (a Bp2BuildConversionAllowlist) SetModuleTypeAlwaysConvertList(moduleTypeAlwaysConvert []string) Bp2BuildConversionAllowlist {
 	if a.moduleTypeAlwaysConvert == nil {
 		a.moduleTypeAlwaysConvert = map[string]bool{}
 	}
@@ -307,7 +307,7 @@
 }
 
 // SetModuleDoNotConvertList copies the entries from moduleDoNotConvert into the allowlist
-func (a bp2BuildConversionAllowlist) SetModuleDoNotConvertList(moduleDoNotConvert []string) bp2BuildConversionAllowlist {
+func (a Bp2BuildConversionAllowlist) SetModuleDoNotConvertList(moduleDoNotConvert []string) Bp2BuildConversionAllowlist {
 	if a.moduleDoNotConvert == nil {
 		a.moduleDoNotConvert = map[string]bool{}
 	}
@@ -319,7 +319,7 @@
 }
 
 // SetCcLibraryStaticOnlyList copies the entries from ccLibraryStaticOnly into the allowlist
-func (a bp2BuildConversionAllowlist) SetCcLibraryStaticOnlyList(ccLibraryStaticOnly []string) bp2BuildConversionAllowlist {
+func (a Bp2BuildConversionAllowlist) SetCcLibraryStaticOnlyList(ccLibraryStaticOnly []string) Bp2BuildConversionAllowlist {
 	if a.ccLibraryStaticOnly == nil {
 		a.ccLibraryStaticOnly = map[string]bool{}
 	}
@@ -330,33 +330,15 @@
 	return a
 }
 
-var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
-var bp2buildAllowlist OncePer
-
-func GetBp2BuildAllowList() bp2BuildConversionAllowlist {
-	return bp2buildAllowlist.Once(bp2BuildAllowListKey, func() interface{} {
-		return NewBp2BuildAllowlist().SetDefaultConfig(allowlists.Bp2buildDefaultConfig).
-			SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
-			SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
-			SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
-			SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList).
-			SetCcLibraryStaticOnlyList(allowlists.Bp2buildCcLibraryStaticOnlyList)
-	}).(bp2BuildConversionAllowlist)
-}
-
 // ShouldKeepExistingBuildFileForDir returns whether an existing BUILD file should be
 // added to the build symlink forest based on the current global configuration.
-func ShouldKeepExistingBuildFileForDir(dir string) bool {
-	return shouldKeepExistingBuildFileForDir(GetBp2BuildAllowList(), dir)
-}
-
-func shouldKeepExistingBuildFileForDir(allowlist bp2BuildConversionAllowlist, dir string) bool {
-	if _, ok := allowlist.keepExistingBuildFile[dir]; ok {
+func (a Bp2BuildConversionAllowlist) ShouldKeepExistingBuildFileForDir(dir string) bool {
+	if _, ok := a.keepExistingBuildFile[dir]; ok {
 		// Exact dir match
 		return true
 	}
 	// Check if subtree match
-	for prefix, recursive := range allowlist.keepExistingBuildFile {
+	for prefix, recursive := range a.keepExistingBuildFile {
 		if recursive {
 			if strings.HasPrefix(dir, prefix+"/") {
 				return true
@@ -367,6 +349,20 @@
 	return false
 }
 
+var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
+var bp2buildAllowlist OncePer
+
+func GetBp2BuildAllowList() Bp2BuildConversionAllowlist {
+	return bp2buildAllowlist.Once(bp2BuildAllowListKey, func() interface{} {
+		return NewBp2BuildAllowlist().SetDefaultConfig(allowlists.Bp2buildDefaultConfig).
+			SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
+			SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
+			SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
+			SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList).
+			SetCcLibraryStaticOnlyList(allowlists.Bp2buildCcLibraryStaticOnlyList)
+	}).(Bp2BuildConversionAllowlist)
+}
+
 // MixedBuildsEnabled returns true if a module is ready to be replaced by a
 // converted or handcrafted Bazel target. As a side effect, calling this
 // method will also log whether this module is mixed build enabled for
@@ -431,7 +427,7 @@
 	}
 
 	moduleName := module.Name()
-	allowlist := ctx.Config().bp2buildPackageConfig
+	allowlist := ctx.Config().Bp2buildPackageConfig
 	moduleNameAllowed := allowlist.moduleAlwaysConvert[moduleName]
 	moduleTypeAllowed := allowlist.moduleTypeAlwaysConvert[ctx.OtherModuleType(module)]
 	allowlistConvert := moduleNameAllowed || moduleTypeAllowed
@@ -447,14 +443,6 @@
 		return false
 	}
 
-	if allowlistConvert && shouldKeepExistingBuildFileForDir(allowlist, packagePath) {
-		if moduleNameAllowed {
-			ctx.ModuleErrorf("A module cannot be in a directory listed in keepExistingBuildFile"+
-				" and also be in moduleAlwaysConvert. Directory: '%s'", packagePath)
-			return false
-		}
-	}
-
 	// This is a tristate value: true, false, or unset.
 	if ok, directoryPath := bp2buildDefaultTrueRecursively(packagePath, allowlist.defaultConfig); ok {
 		if moduleNameAllowed {
diff --git a/android/bazel_test.go b/android/bazel_test.go
index 98f0a46..b578cca 100644
--- a/android/bazel_test.go
+++ b/android/bazel_test.go
@@ -158,7 +158,7 @@
 
 type TestBazelConversionContext struct {
 	omc       bazel.OtherModuleTestContext
-	allowlist bp2BuildConversionAllowlist
+	allowlist Bp2BuildConversionAllowlist
 	errors    []string
 }
 
@@ -183,7 +183,7 @@
 func (bcc *TestBazelConversionContext) Config() Config {
 	return Config{
 		&config{
-			bp2buildPackageConfig: bcc.allowlist,
+			Bp2buildPackageConfig: bcc.allowlist,
 		},
 	}
 }
@@ -202,7 +202,7 @@
 		shouldConvert  bool
 		expectedErrors []string
 		module         TestBazelModule
-		allowlist      bp2BuildConversionAllowlist
+		allowlist      Bp2BuildConversionAllowlist
 	}{
 		{
 			description:   "allowlist enables module",
@@ -215,7 +215,7 @@
 				},
 				BazelModuleBase: bazelableBazelModuleBase,
 			},
-			allowlist: bp2BuildConversionAllowlist{
+			allowlist: Bp2BuildConversionAllowlist{
 				moduleAlwaysConvert: map[string]bool{
 					"foo": true,
 				},
@@ -233,7 +233,7 @@
 				},
 				BazelModuleBase: bazelableBazelModuleBase,
 			},
-			allowlist: bp2BuildConversionAllowlist{
+			allowlist: Bp2BuildConversionAllowlist{
 				moduleAlwaysConvert: map[string]bool{
 					"foo": true,
 				},
@@ -254,7 +254,7 @@
 				},
 				BazelModuleBase: bazelableBazelModuleBase,
 			},
-			allowlist: bp2BuildConversionAllowlist{
+			allowlist: Bp2BuildConversionAllowlist{
 				moduleAlwaysConvert: map[string]bool{
 					"foo": true,
 				},
@@ -264,27 +264,6 @@
 			},
 		},
 		{
-			description:    "module in allowlist and existing BUILD file",
-			shouldConvert:  false,
-			expectedErrors: []string{"A module cannot be in a directory listed in keepExistingBuildFile and also be in moduleAlwaysConvert. Directory: 'existing/build/dir'"},
-			module: TestBazelModule{
-				TestModuleInfo: bazel.TestModuleInfo{
-					ModuleName: "foo",
-					Typ:        "rule1",
-					Dir:        "existing/build/dir",
-				},
-				BazelModuleBase: bazelableBazelModuleBase,
-			},
-			allowlist: bp2BuildConversionAllowlist{
-				moduleAlwaysConvert: map[string]bool{
-					"foo": true,
-				},
-				keepExistingBuildFile: map[string]bool{
-					"existing/build/dir": true,
-				},
-			},
-		},
-		{
 			description:    "module allowlist and enabled directory",
 			shouldConvert:  false,
 			expectedErrors: []string{"A module cannot be in a directory marked Bp2BuildDefaultTrue or Bp2BuildDefaultTrueRecursively and also be in moduleAlwaysConvert. Directory: 'existing/build/dir'"},
@@ -296,7 +275,7 @@
 				},
 				BazelModuleBase: bazelableBazelModuleBase,
 			},
-			allowlist: bp2BuildConversionAllowlist{
+			allowlist: Bp2BuildConversionAllowlist{
 				moduleAlwaysConvert: map[string]bool{
 					"foo": true,
 				},
@@ -317,7 +296,7 @@
 				},
 				BazelModuleBase: bazelableBazelModuleBase,
 			},
-			allowlist: bp2BuildConversionAllowlist{
+			allowlist: Bp2BuildConversionAllowlist{
 				moduleAlwaysConvert: map[string]bool{
 					"foo": true,
 				},
@@ -344,7 +323,7 @@
 					},
 				},
 			},
-			allowlist: bp2BuildConversionAllowlist{
+			allowlist: Bp2BuildConversionAllowlist{
 				moduleAlwaysConvert: map[string]bool{
 					"foo": true,
 				},
diff --git a/android/config.go b/android/config.go
index a07cb6c..745410f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -189,7 +189,7 @@
 	mockBpList string
 
 	BuildMode                      SoongBuildMode
-	bp2buildPackageConfig          bp2BuildConversionAllowlist
+	Bp2buildPackageConfig          Bp2BuildConversionAllowlist
 	Bp2buildSoongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions
 
 	// If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
@@ -482,7 +482,7 @@
 
 	config.BuildMode = buildMode
 	config.BazelContext, err = NewBazelContext(config)
-	config.bp2buildPackageConfig = GetBp2BuildAllowList()
+	config.Bp2buildPackageConfig = GetBp2BuildAllowList()
 
 	return Config{config}, err
 }
diff --git a/android/testing.go b/android/testing.go
index ef5e5a9..3708501 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -213,8 +213,8 @@
 	ctx.finalDeps = append(ctx.finalDeps, f)
 }
 
-func (ctx *TestContext) RegisterBp2BuildConfig(config bp2BuildConversionAllowlist) {
-	ctx.config.bp2buildPackageConfig = config
+func (ctx *TestContext) RegisterBp2BuildConfig(config Bp2BuildConversionAllowlist) {
+	ctx.config.Bp2buildPackageConfig = config
 }
 
 // PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 242ea1e..8de6d18 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -373,6 +373,15 @@
 	if generateFilegroups {
 		// Add a filegroup target that exposes all sources in the subtree of this package
 		// NOTE: This also means we generate a BUILD file for every Android.bp file (as long as it has at least one module)
+		//
+		// This works because: https://bazel.build/reference/be/functions#exports_files
+		// "As a legacy behaviour, also files mentioned as input to a rule are exported with the
+		// default visibility until the flag --incompatible_no_implicit_file_export is flipped. However, this behavior
+		// should not be relied upon and actively migrated away from."
+		//
+		// TODO(b/198619163): We should change this to export_files(glob(["**/*"])) instead, but doing that causes these errors:
+		// "Error in exports_files: generated label '//external/avb:avbtool' conflicts with existing py_binary rule"
+		// So we need to solve all the "target ... is both a rule and a file" warnings first.
 		for dir, _ := range dirs {
 			buildFileToTargets[dir] = append(buildFileToTargets[dir], BazelTarget{
 				name:      "bp2build_all_srcs",
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index 9e449eb..67d4a1c 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -605,8 +605,67 @@
         "//conditions:default": [],
     })`,
 				"local_includes": `["."]`,
-			},
-			},
+			}},
+		},
+	})
+}
+
+func TestCcBinaryEmptySuffix(t *testing.T) {
+	runCcBinaryTests(t, ccBinaryBp2buildTestCase{
+		description: "binary with empty suffix",
+		blueprint: `
+{rule_name} {
+    name: "foo",
+    suffix: "",
+}`,
+		targets: []testBazelTarget{
+			{"cc_binary", "foo", AttrNameToString{
+				"local_includes": `["."]`,
+				"suffix":         `""`,
+			}},
+		},
+	})
+}
+
+func TestCcBinarySuffix(t *testing.T) {
+	runCcBinaryTests(t, ccBinaryBp2buildTestCase{
+		description: "binary with suffix",
+		blueprint: `
+{rule_name} {
+    name: "foo",
+    suffix: "-suf",
+}
+`,
+		targets: []testBazelTarget{
+			{"cc_binary", "foo", AttrNameToString{
+				"local_includes": `["."]`,
+				"suffix":         `"-suf"`,
+			}},
+		},
+	})
+}
+
+func TestCcArchVariantBinarySuffix(t *testing.T) {
+	runCcBinaryTests(t, ccBinaryBp2buildTestCase{
+		description: "binary with suffix",
+		blueprint: `
+{rule_name} {
+    name: "foo",
+    arch: {
+        arm64: { suffix: "-64" },
+        arm:   { suffix: "-32" },
+		},
+}
+`,
+		targets: []testBazelTarget{
+			{"cc_binary", "foo", AttrNameToString{
+				"local_includes": `["."]`,
+				"suffix": `select({
+        "//build/bazel/platforms/arch:arm": "-32",
+        "//build/bazel/platforms/arch:arm64": "-64",
+        "//conditions:default": None,
+    })`,
+			}},
 		},
 	})
 }
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 024d4e0..c1b4cd0 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -2593,6 +2593,91 @@
 	})
 }
 
+func TestCcLibraryEmptySuffix(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library with empty suffix",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Filesystem: map[string]string{
+			"foo.c": "",
+		},
+		Blueprint: `cc_library {
+    name: "foo",
+    suffix: "",
+    srcs: ["foo.c"],
+    include_build_directory: false,
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+			}),
+			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+				"suffix": `""`,
+			}),
+		},
+	})
+}
+
+func TestCcLibrarySuffix(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library with suffix",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Filesystem: map[string]string{
+			"foo.c": "",
+		},
+		Blueprint: `cc_library {
+    name: "foo",
+    suffix: "-suf",
+    srcs: ["foo.c"],
+    include_build_directory: false,
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+			}),
+			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+				"suffix": `"-suf"`,
+			}),
+		},
+	})
+}
+
+func TestCcLibraryArchVariantSuffix(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library with arch-variant suffix",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Filesystem: map[string]string{
+			"foo.c": "",
+		},
+		Blueprint: `cc_library {
+    name: "foo",
+    arch: {
+        arm64: { suffix: "-64" },
+        arm:   { suffix: "-32" },
+		},
+    srcs: ["foo.c"],
+    include_build_directory: false,
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+			}),
+			makeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+				"suffix": `select({
+        "//build/bazel/platforms/arch:arm": "-32",
+        "//build/bazel/platforms/arch:arm64": "-64",
+        "//conditions:default": None,
+    })`,
+			}),
+		},
+	})
+}
+
 func TestCcLibraryWithAidlSrcs(t *testing.T) {
 	runCcLibraryTestCase(t, Bp2buildTestCase{
 		Description:                "cc_library with aidl srcs",
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 7a44f69..ed983bf 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -641,3 +641,76 @@
 		},
 	})
 }
+
+func TestCcLibrarySharedEmptySuffix(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		Description: "cc_library_shared with empty suffix",
+		Filesystem: map[string]string{
+			"foo.c": "",
+		},
+		Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+    name: "foo_shared",
+    suffix: "",
+    srcs: ["foo.c"],
+    include_build_directory: false,
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+				"suffix": `""`,
+			}),
+		},
+	})
+}
+
+func TestCcLibrarySharedSuffix(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		Description: "cc_library_shared with suffix",
+		Filesystem: map[string]string{
+			"foo.c": "",
+		},
+		Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+    name: "foo_shared",
+    suffix: "-suf",
+    srcs: ["foo.c"],
+    include_build_directory: false,
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+				"suffix": `"-suf"`,
+			}),
+		},
+	})
+}
+
+func TestCcLibrarySharedArchVariantSuffix(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		Description: "cc_library_shared with arch-variant suffix",
+		Filesystem: map[string]string{
+			"foo.c": "",
+		},
+		Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+    name: "foo_shared",
+    arch: {
+        arm64: { suffix: "-64" },
+        arm:   { suffix: "-32" },
+		},
+    srcs: ["foo.c"],
+    include_build_directory: false,
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+				"srcs_c": `["foo.c"]`,
+				"suffix": `select({
+        "//build/bazel/platforms/arch:arm": "-32",
+        "//build/bazel/platforms/arch:arm64": "-64",
+        "//conditions:default": None,
+    })`,
+			}),
+		},
+	})
+}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 8cf9bea..d98b6a3 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -2,7 +2,6 @@
 
 import (
 	"encoding/json"
-	"fmt"
 	"reflect"
 	"strings"
 
@@ -80,21 +79,14 @@
 		files = append(files, newFile(bazelRulesSubDir, "soong_module.bzl", generateSoongModuleBzl(ruleShims)))
 	}
 
-	files = append(files, createBuildFiles(cfg, buildToTargets, mode)...)
+	files = append(files, createBuildFiles(buildToTargets, mode)...)
 
 	return files
 }
 
-func createBuildFiles(cfg android.Config, buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
+func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
 	files := make([]BazelFile, 0, len(buildToTargets))
-	warnNotWriting := cfg.IsEnvTrue("BP2BUILD_VERBOSE")
 	for _, dir := range android.SortedStringKeys(buildToTargets) {
-		if mode == Bp2Build && android.ShouldKeepExistingBuildFileForDir(dir) {
-			if warnNotWriting {
-				fmt.Printf("[bp2build] Not writing generated BUILD file for dir: '%s'\n", dir)
-			}
-			continue
-		}
 		targets := buildToTargets[dir]
 		targets.sort()
 
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index f5a5938..b57cf35 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -501,3 +501,36 @@
 		ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 	})
 }
+
+func TestJavaLibraryAidlNonAdjacentAidlFilegroup(t *testing.T) {
+	runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
+		Description:                "java_library with non adjacent aidl filegroup",
+		ModuleTypeUnderTest:        "java_library",
+		ModuleTypeUnderTestFactory: java.LibraryFactory,
+		Filesystem: map[string]string{
+			"path/to/A/Android.bp": `
+filegroup {
+	name: "A_aidl",
+	srcs: ["aidl/A.aidl"],
+	path: "aidl",
+}`,
+		},
+		Blueprint: `
+java_library {
+	name: "foo",
+	srcs: [
+		":A_aidl",
+	],
+}`,
+		ExpectedBazelTargets: []string{
+			makeBazelTarget("java_aidl_library", "foo_java_aidl_library", AttrNameToString{
+				"deps": `["//path/to/A:A_aidl"]`,
+			}),
+			makeBazelTarget("java_library", "foo", AttrNameToString{
+				"exports": `[":foo_java_aidl_library"]`,
+			}),
+		},
+	}, func(ctx android.RegistrationContext) {
+		ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+	})
+}
diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go
index 78e7b0e..023ec96 100644
--- a/bp2build/symlink_forest.go
+++ b/bp2build/symlink_forest.go
@@ -1,12 +1,27 @@
+// 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 (
-	"android/soong/android"
 	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"regexp"
 
+	"android/soong/android"
 	"android/soong/shared"
 )
 
@@ -58,6 +73,57 @@
 	return result
 }
 
+func mergeBuildFiles(output string, srcBuildFile string, generatedBuildFile string, verbose bool) error {
+
+	srcBuildFileContent, err := os.ReadFile(srcBuildFile)
+	if err != nil {
+		return err
+	}
+
+	generatedBuildFileContent, err := os.ReadFile(generatedBuildFile)
+	if err != nil {
+		return err
+	}
+
+	// There can't be a package() call in both the source and generated BUILD files.
+	// bp2build will generate a package() call for licensing information, but if
+	// there's no licensing information, it will still generate a package() call
+	// that just sets default_visibility=public. If the handcrafted build file
+	// also has a package() call, we'll allow it to override the bp2build
+	// generated one if it doesn't have any licensing information. If the bp2build
+	// one has licensing information and the handcrafted one exists, we'll leave
+	// them both in for bazel to throw an error.
+	packageRegex := regexp.MustCompile(`(?m)^package\s*\(`)
+	packageDefaultVisibilityRegex := regexp.MustCompile(`(?m)^package\s*\(\s*default_visibility\s*=\s*\[\s*"//visibility:public",?\s*]\s*\)`)
+	if packageRegex.Find(srcBuildFileContent) != nil {
+		if verbose && packageDefaultVisibilityRegex.Find(generatedBuildFileContent) != nil {
+			fmt.Fprintf(os.Stderr, "Both '%s' and '%s' have a package() target, removing the first one\n",
+				generatedBuildFile, srcBuildFile)
+		}
+		generatedBuildFileContent = packageDefaultVisibilityRegex.ReplaceAll(generatedBuildFileContent, []byte{})
+	}
+
+	outFile, err := os.Create(output)
+	if err != nil {
+		return err
+	}
+
+	_, err = outFile.Write(generatedBuildFileContent)
+	if err != nil {
+		return err
+	}
+
+	if generatedBuildFileContent[len(generatedBuildFileContent)-1] != '\n' {
+		_, err = outFile.WriteString("\n")
+		if err != nil {
+			return err
+		}
+	}
+
+	_, err = outFile.Write(srcBuildFileContent)
+	return err
+}
+
 // Calls readdir() and returns it as a map from the basename of the files in dir
 // to os.FileInfo.
 func readdirToMap(dir string) map[string]os.FileInfo {
@@ -125,6 +191,17 @@
 	srcDirMap := readdirToMap(shared.JoinPath(topdir, srcDir))
 	buildFilesMap := readdirToMap(shared.JoinPath(topdir, buildFilesDir))
 
+	renamingBuildFile := false
+	if _, ok := srcDirMap["BUILD"]; ok {
+		if _, ok := srcDirMap["BUILD.bazel"]; !ok {
+			if _, ok := buildFilesMap["BUILD.bazel"]; ok {
+				renamingBuildFile = true
+				srcDirMap["BUILD.bazel"] = srcDirMap["BUILD"]
+				delete(srcDirMap, "BUILD")
+			}
+		}
+	}
+
 	allEntries := make(map[string]bool)
 	for n := range srcDirMap {
 		allEntries[n] = true
@@ -148,21 +225,28 @@
 		// The full paths of children in the input trees and in the output tree
 		forestChild := shared.JoinPath(forestDir, f)
 		srcChild := shared.JoinPath(srcDir, f)
+		if f == "BUILD.bazel" && renamingBuildFile {
+			srcChild = shared.JoinPath(srcDir, "BUILD")
+		}
 		buildFilesChild := shared.JoinPath(buildFilesDir, f)
 
 		// Descend in the exclusion tree, if there are any excludes left
-		var excludeChild *node
-		if exclude == nil {
-			excludeChild = nil
-		} else {
-			excludeChild = exclude.children[f]
+		var excludeChild *node = nil
+		if exclude != nil {
+			if f == "BUILD.bazel" && renamingBuildFile {
+				excludeChild = exclude.children["BUILD"]
+			} else {
+				excludeChild = exclude.children[f]
+			}
 		}
 
 		srcChildEntry, sExists := srcDirMap[f]
 		buildFilesChildEntry, bExists := buildFilesMap[f]
-		excluded := excludeChild != nil && excludeChild.excluded
 
-		if excluded {
+		if excludeChild != nil && excludeChild.excluded {
+			if bExists {
+				symlinkIntoForest(topdir, forestChild, buildFilesChild)
+			}
 			continue
 		}
 
@@ -198,13 +282,15 @@
 			// Both are directories. Descend.
 			plantSymlinkForestRecursive(cfg, topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
 		} else if !sDir && !bDir {
-			// Neither is a directory. Prioritize BUILD files generated by bp2build
-			// over any BUILD file imported into external/.
-			if cfg.IsEnvTrue("BP2BUILD_VERBOSE") {
-				fmt.Fprintf(os.Stderr, "Both '%s' and '%s' exist, symlinking the former to '%s'\n",
-					buildFilesChild, srcChild, forestChild)
+			// Neither is a directory. Merge them.
+			srcBuildFile := shared.JoinPath(topdir, srcChild)
+			generatedBuildFile := shared.JoinPath(topdir, buildFilesChild)
+			err = mergeBuildFiles(shared.JoinPath(topdir, forestChild), srcBuildFile, generatedBuildFile, cfg.IsEnvTrue("BP2BUILD_VERBOSE"))
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "Error merging %s and %s: %s",
+					srcBuildFile, generatedBuildFile, err)
+				*okay = false
 			}
-			symlinkIntoForest(topdir, forestChild, buildFilesChild)
 		} else {
 			// Both exist and one is a file. This is an error.
 			fmt.Fprintf(os.Stderr,
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 625e7ce..77aaec1 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -339,6 +339,8 @@
 	stubsVersions   bazel.StringListAttribute
 
 	features bazel.StringListAttribute
+
+	suffix bazel.StringAttribute
 }
 
 type filterOutFn func(string) bool
@@ -694,6 +696,9 @@
 					compilerAttrs.stubsSymbolFile = libraryProps.Stubs.Symbol_file
 					compilerAttrs.stubsVersions.SetSelectValue(axis, config, libraryProps.Stubs.Versions)
 				}
+				if suffix := libraryProps.Suffix; suffix != nil {
+					compilerAttrs.suffix.SetSelectValue(axis, config, suffix)
+				}
 			}
 		}
 	}
@@ -1201,6 +1206,7 @@
 
 type binaryLinkerAttrs struct {
 	Linkshared *bool
+	Suffix     bazel.StringAttribute
 }
 
 func bp2buildBinaryLinkerProps(ctx android.BazelConversionPathContext, m *Module) binaryLinkerAttrs {
@@ -1217,6 +1223,9 @@
 			// nonconfigurable attribute. Only 4 AOSP modules use this feature, defer handling
 			ctx.ModuleErrorf("bp2build cannot migrate a module with arch/target-specific static_executable values")
 		}
+		if suffix := linkerProps.Suffix; suffix != nil {
+			attrs.Suffix.SetSelectValue(axis, config, suffix)
+		}
 	})
 
 	return attrs
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 36174d6..5d569cc 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4111,7 +4111,7 @@
 			name: "libfoo",
 			srcs: [
 				"foo.c",
-				"a.sysprop",
+				"path/to/a.sysprop",
 				"b.aidl",
 				"a.proto",
 			],
@@ -4124,11 +4124,11 @@
 			`),
 			expectedSystemIncludeDirs(``),
 			expectedGeneratedHeaders(`
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
 			`),
 			expectedOrderOnlyDeps(`
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/a.sysprop.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
+				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
 			`),
 		)
 	})
diff --git a/cc/gen_test.go b/cc/gen_test.go
index 40a5716..85df333 100644
--- a/cc/gen_test.go
+++ b/cc/gen_test.go
@@ -74,4 +74,26 @@
 
 	})
 
+	t.Run("sysprop", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library {
+			name: "libsysprop",
+			srcs: [
+				"path/to/foo.sysprop",
+			],
+		}`)
+
+		outDir := "out/soong/.intermediates/libsysprop/android_arm64_armv8-a_static/gen"
+		syspropBuildParams := ctx.ModuleForTests("libsysprop", "android_arm64_armv8-a_static").Rule("sysprop")
+
+		android.AssertStringEquals(t, "header output directory does not match", outDir+"/sysprop/include/path/to", syspropBuildParams.Args["headerOutDir"])
+		android.AssertStringEquals(t, "public output directory does not match", outDir+"/sysprop/public/include/path/to", syspropBuildParams.Args["publicOutDir"])
+		android.AssertStringEquals(t, "src output directory does not match", outDir+"/sysprop/path/to", syspropBuildParams.Args["srcOutDir"])
+		android.AssertStringEquals(t, "output include name does not match", "path/to/foo.sysprop.h", syspropBuildParams.Args["includeName"])
+		android.AssertStringEquals(t, "Input file does not match", "path/to/foo.sysprop", syspropBuildParams.Input.String())
+		android.AssertStringEquals(t, "Output file does not match", outDir+"/sysprop/path/to/foo.sysprop.cpp", syspropBuildParams.Output.String())
+		android.AssertStringListContains(t, "Implicit outputs does not contain header file", syspropBuildParams.ImplicitOutputs.Strings(), outDir+"/sysprop/include/path/to/foo.sysprop.h")
+		android.AssertStringListContains(t, "Implicit outputs does not contain public header file", syspropBuildParams.ImplicitOutputs.Strings(), outDir+"/sysprop/public/include/path/to/foo.sysprop.h")
+		android.AssertIntEquals(t, "Implicit outputs contains the incorrect number of elements", 2, len(syspropBuildParams.ImplicitOutputs.Strings()))
+	})
 }
diff --git a/cc/library.go b/cc/library.go
index fc03fa2..c97970e 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -408,6 +408,8 @@
 		sharedTargetAttrs.Has_stubs.SetValue(&hasStubs)
 	}
 
+	sharedTargetAttrs.Suffix = compilerAttrs.suffix
+
 	for axis, configToProps := range m.GetArchVariantProperties(ctx, &LibraryProperties{}) {
 		for config, props := range configToProps {
 			if props, ok := props.(*LibraryProperties); ok {
@@ -2647,6 +2649,8 @@
 			},
 
 			Features: baseAttributes.features,
+
+			Suffix: compilerAttrs.suffix,
 		}
 		if compilerAttrs.stubsSymbolFile != nil && len(compilerAttrs.stubsVersions.Value) > 0 {
 			hasStubs := true
@@ -2729,6 +2733,8 @@
 	Has_stubs bazel.BoolAttribute
 
 	Inject_bssl_hash bazel.BoolAttribute
+
+	Suffix bazel.StringAttribute
 }
 
 type bazelCcStubSuiteAttributes struct {
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index d15dea1..0b8cc88 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -240,7 +240,7 @@
 // doChosenActivity runs Soong for a specific activity, like bp2build, queryview
 // or the actual Soong build for the build.ninja file. Returns the top level
 // output file of the specific activity.
-func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string, logDir string) string {
+func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string) string {
 	if configuration.BuildMode == android.Bp2build {
 		// Run the alternate pipeline of bp2build mutators and singleton to convert
 		// Blueprint to BUILD files before everything else.
@@ -353,7 +353,7 @@
 	ctx := newContext(configuration)
 	ctx.EventHandler.Begin("soong_build")
 
-	finalOutputFile := doChosenActivity(ctx, configuration, extraNinjaDeps, logDir)
+	finalOutputFile := doChosenActivity(ctx, configuration, extraNinjaDeps)
 
 	ctx.EventHandler.End("soong_build")
 	writeMetrics(configuration, *ctx.EventHandler, logDir)
@@ -406,14 +406,10 @@
 	}
 }
 
-// Find BUILD files in the srcDir which...
-//
-// - are not on the allow list (android/bazel.go#ShouldKeepExistingBuildFileForDir())
-//
-// - won't be overwritten by corresponding bp2build generated files
-//
-// And return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
-func getPathsToIgnoredBuildFiles(topDir string, generatedRoot string, srcDirBazelFiles []string, verbose bool) []string {
+// Find BUILD files in the srcDir which are not in the allowlist
+// (android.Bp2BuildConversionAllowlist#ShouldKeepExistingBuildFileForDir)
+// and return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
+func getPathsToIgnoredBuildFiles(config android.Bp2BuildConversionAllowlist, topDir string, srcDirBazelFiles []string, verbose bool) []string {
 	paths := make([]string, 0)
 
 	for _, srcDirBazelFileRelativePath := range srcDirBazelFiles {
@@ -428,21 +424,14 @@
 			// Don't ignore entire directories
 			continue
 		}
-		if !(fileInfo.Name() == "BUILD" || fileInfo.Name() == "BUILD.bazel") {
+		if fileInfo.Name() != "BUILD" && fileInfo.Name() != "BUILD.bazel" {
 			// Don't ignore this file - it is not a build file
 			continue
 		}
-		srcDirBazelFileDir := filepath.Dir(srcDirBazelFileRelativePath)
-		if android.ShouldKeepExistingBuildFileForDir(srcDirBazelFileDir) {
+		if config.ShouldKeepExistingBuildFileForDir(filepath.Dir(srcDirBazelFileRelativePath)) {
 			// Don't ignore this existing build file
 			continue
 		}
-		correspondingBp2BuildFile := shared.JoinPath(topDir, generatedRoot, srcDirBazelFileRelativePath)
-		if _, err := os.Stat(correspondingBp2BuildFile); err == nil {
-			// If bp2build generated an alternate BUILD file, don't exclude this workspace path
-			// BUILD file clash resolution happens later in the symlink forest creation
-			continue
-		}
 		if verbose {
 			fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
 		}
@@ -553,7 +542,7 @@
 			os.Exit(1)
 		}
 
-		pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(topDir, generatedRoot, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
+		pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(configuration.Bp2buildPackageConfig, topDir, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
 		excludes = append(excludes, pathsToIgnoredBuildFiles...)
 
 		excludes = append(excludes, getTemporaryExcludes()...)
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 2e94a46..ff6d68f 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -170,9 +170,8 @@
 
 	commonArgs = append(commonArgs, "-l", filepath.Join(config.FileListDir(), "Android.bp.list"))
 	invocationEnv := make(map[string]string)
-	debugMode := os.Getenv("SOONG_DELVE") != ""
-
-	if debugMode {
+	if os.Getenv("SOONG_DELVE") != "" {
+		//debug mode
 		commonArgs = append(commonArgs, "--delve_listen", os.Getenv("SOONG_DELVE"))
 		commonArgs = append(commonArgs, "--delve_path", shared.ResolveDelveBinary())
 		// GODEBUG=asyncpreemptoff=1 disables the preemption of goroutines. This
@@ -187,7 +186,7 @@
 		invocationEnv["GODEBUG"] = "asyncpreemptoff=1"
 	}
 
-	allArgs := make([]string, 0, 0)
+	var allArgs []string
 	allArgs = append(allArgs, specificArgs...)
 	allArgs = append(allArgs,
 		"--globListDir", name,
diff --git a/ui/status/ninja.go b/ui/status/ninja.go
index 4d99621..fc0e21a 100644
--- a/ui/status/ninja.go
+++ b/ui/status/ninja.go
@@ -35,8 +35,7 @@
 func NewNinjaReader(ctx logger.Logger, status ToolStatus, fifo string) *NinjaReader {
 	os.Remove(fifo)
 
-	err := syscall.Mkfifo(fifo, 0666)
-	if err != nil {
+	if err := syscall.Mkfifo(fifo, 0666); err != nil {
 		ctx.Fatalf("Failed to mkfifo(%q): %v", fifo, err)
 	}