Merge "rust: Hook up InstallIn functions + Product"
diff --git a/android/arch.go b/android/arch.go
index 7ca7336..f7eb963 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1967,6 +1967,7 @@
 		srcType := reflect.ValueOf(generalProp).Type()
 		if srcType == dstType {
 			archProperties = m.archProperties[i]
+			axisToProps[bazel.NoConfigAxis] = ArchVariantProperties{"": generalProp}
 			break
 		}
 	}
diff --git a/android/filegroup.go b/android/filegroup.go
index 97dd136..54d01d3 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -34,24 +34,6 @@
 	Srcs bazel.LabelListAttribute
 }
 
-type bazelFilegroup struct {
-	BazelTargetModuleBase
-	bazelFilegroupAttributes
-}
-
-func BazelFileGroupFactory() Module {
-	module := &bazelFilegroup{}
-	module.AddProperties(&module.bazelFilegroupAttributes)
-	InitBazelTargetModule(module)
-	return module
-}
-
-func (bfg *bazelFilegroup) Name() string {
-	return bfg.BaseModuleName()
-}
-
-func (bfg *bazelFilegroup) GenerateAndroidBuildActions(ctx ModuleContext) {}
-
 func FilegroupBp2Build(ctx TopDownMutatorContext) {
 	fg, ok := ctx.Module().(*fileGroup)
 	if !ok || !fg.ConvertWithBp2build(ctx) {
@@ -69,7 +51,7 @@
 		Bzl_load_location: "//build/bazel/rules:filegroup.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelFileGroupFactory, fg.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(fg.Name(), props, attrs)
 }
 
 type fileGroupProperties struct {
diff --git a/android/module.go b/android/module.go
index 7451e09..b571f15 100644
--- a/android/module.go
+++ b/android/module.go
@@ -491,6 +491,11 @@
 	AddProperties(props ...interface{})
 	GetProperties() []interface{}
 
+	// IsConvertedByBp2build returns whether this module was converted via bp2build
+	IsConvertedByBp2build() bool
+	// Bp2buildTargets returns the target(s) generated for Bazel via bp2build for this module
+	Bp2buildTargets() []bp2buildInfo
+
 	BuildParamsForTests() []BuildParams
 	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
 	VariablesForTests() map[string]string
@@ -878,6 +883,11 @@
 	// for example "" for core or "recovery" for recovery.  It will often be set to one of the
 	// constants in image.go, but can also be set to a custom value by individual module types.
 	ImageVariation string `blueprint:"mutated"`
+
+	// Information about _all_ bp2build targets generated by this module. Multiple targets are
+	// supported as Soong handles some things within a single target that we may choose to split into
+	// multiple targets, e.g. renderscript, protos, yacc within a cc module.
+	Bp2buildInfo []bp2buildInfo `blueprint:"mutated"`
 }
 
 type distProperties struct {
@@ -1204,6 +1214,54 @@
 	vintfFragmentsPaths Paths
 }
 
+// A struct containing all relevant information about a Bazel target converted via bp2build.
+type bp2buildInfo struct {
+	Name       string
+	Dir        string
+	BazelProps bazel.BazelTargetModuleProperties
+	Attrs      interface{}
+}
+
+// TargetName returns the Bazel target name of a bp2build converted target.
+func (b bp2buildInfo) TargetName() string {
+	return b.Name
+}
+
+// TargetPackage returns the Bazel package of a bp2build converted target.
+func (b bp2buildInfo) TargetPackage() string {
+	return b.Dir
+}
+
+// BazelRuleClass returns the Bazel rule class of a bp2build converted target.
+func (b bp2buildInfo) BazelRuleClass() string {
+	return b.BazelProps.Rule_class
+}
+
+// BazelRuleLoadLocation returns the location of the  Bazel rule of a bp2build converted target.
+// This may be empty as native Bazel rules do not need to be loaded.
+func (b bp2buildInfo) BazelRuleLoadLocation() string {
+	return b.BazelProps.Bzl_load_location
+}
+
+// BazelAttributes returns the Bazel attributes of a bp2build converted target.
+func (b bp2buildInfo) BazelAttributes() interface{} {
+	return b.Attrs
+}
+
+func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
+	m.commonProperties.Bp2buildInfo = append(m.commonProperties.Bp2buildInfo, info)
+}
+
+// IsConvertedByBp2build returns whether this module was converted via bp2build.
+func (m *ModuleBase) IsConvertedByBp2build() bool {
+	return len(m.commonProperties.Bp2buildInfo) > 0
+}
+
+// Bp2buildTargets returns the Bazel targets bp2build generated for this module.
+func (m *ModuleBase) Bp2buildTargets() []bp2buildInfo {
+	return m.commonProperties.Bp2buildInfo
+}
+
 func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
 	(*d)["Android"] = map[string]interface{}{}
 }
diff --git a/android/mutator.go b/android/mutator.go
index d895669..20ec621 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -270,7 +270,7 @@
 	// factory method, just like in CreateModule, but also requires
 	// BazelTargetModuleProperties containing additional metadata for the
 	// bp2build codegenerator.
-	CreateBazelTargetModule(ModuleFactory, string, bazel.BazelTargetModuleProperties, interface{}) BazelTargetModule
+	CreateBazelTargetModule(string, bazel.BazelTargetModuleProperties, interface{})
 }
 
 type topDownMutatorContext struct {
@@ -516,26 +516,24 @@
 }
 
 func (t *topDownMutatorContext) CreateBazelTargetModule(
-	factory ModuleFactory,
 	name string,
 	bazelProps bazel.BazelTargetModuleProperties,
-	attrs interface{}) BazelTargetModule {
+	attrs interface{}) {
 	if strings.HasPrefix(name, bazel.BazelTargetModuleNamePrefix) {
 		panic(fmt.Errorf(
 			"The %s name prefix is added automatically, do not set it manually: %s",
 			bazel.BazelTargetModuleNamePrefix,
 			name))
 	}
-	name = bazel.BazelTargetModuleNamePrefix + name
-	nameProp := struct {
-		Name *string
-	}{
-		Name: &name,
+
+	info := bp2buildInfo{
+		Name:       name,
+		Dir:        t.OtherModuleDir(t.Module()),
+		BazelProps: bazelProps,
+		Attrs:      attrs,
 	}
 
-	b := t.createModuleWithoutInheritance(factory, &nameProp, attrs).(BazelTargetModule)
-	b.SetBazelTargetModuleProperties(bazelProps)
-	return b
+	t.Module().base().addBp2buildInfo(info)
 }
 
 func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
diff --git a/apex/apex.go b/apex/apex.go
index add506f..e1fca67 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1100,13 +1100,6 @@
 			mctx.ModuleErrorf("base property is not set")
 			return
 		}
-		// Workaround the issue reported in b/191269918 by using the unprefixed module name of this
-		// module as the default variation to use if dependencies of this module do not have the correct
-		// apex variant name. This name matches the name used to create the variations of modules for
-		// which apexModuleTypeRequiresVariant return true.
-		// TODO(b/191269918): Remove this workaround.
-		unprefixedModuleName := android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName())
-		mctx.SetDefaultDependencyVariation(&unprefixedModuleName)
 		mctx.CreateVariations(apexBundleName)
 		if strings.HasPrefix(apexBundleName, "com.android.art") {
 			// TODO(b/183882457): See note for CreateAliasVariation above.
@@ -3238,18 +3231,6 @@
 	Prebuilts          bazel.LabelListAttribute
 }
 
-type bazelApexBundle struct {
-	android.BazelTargetModuleBase
-	bazelApexBundleAttributes
-}
-
-func BazelApexBundleFactory() android.Module {
-	module := &bazelApexBundle{}
-	module.AddProperties(&module.bazelApexBundleAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func ApexBundleBp2Build(ctx android.TopDownMutatorContext) {
 	module, ok := ctx.Module().(*apexBundle)
 	if !ok {
@@ -3337,11 +3318,5 @@
 		Bzl_load_location: "//build/bazel/rules:apex.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelApexBundleFactory, module.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(module.Name(), props, attrs)
 }
-
-func (m *bazelApexBundle) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelApexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/apex/key.go b/apex/key.go
index 32a7ce1..468bb8a 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -203,18 +203,6 @@
 	Private_key bazel.LabelAttribute
 }
 
-type bazelApexKey struct {
-	android.BazelTargetModuleBase
-	bazelApexKeyAttributes
-}
-
-func BazelApexKeyFactory() android.Module {
-	module := &bazelApexKey{}
-	module.AddProperties(&module.bazelApexKeyAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func ApexKeyBp2Build(ctx android.TopDownMutatorContext) {
 	module, ok := ctx.Module().(*apexKey)
 	if !ok {
@@ -252,11 +240,5 @@
 		Bzl_load_location: "//build/bazel/rules:apex_key.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelApexKeyFactory, module.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(module.Name(), props, attrs)
 }
-
-func (m *bazelApexKey) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelApexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/bloaty/bloaty_merger.py b/bloaty/bloaty_merger.py
index 1034462..46ce57f 100644
--- a/bloaty/bloaty_merger.py
+++ b/bloaty/bloaty_merger.py
@@ -24,58 +24,63 @@
 import csv
 import gzip
 
+# pylint: disable=import-error
 import ninja_rsp
 
 import file_sections_pb2
 
 BLOATY_EXTENSION = ".bloaty.csv"
 
+
 def parse_csv(path):
-  """Parses a Bloaty-generated CSV file into a protobuf.
+    """Parses a Bloaty-generated CSV file into a protobuf.
 
-  Args:
-    path: The filepath to the CSV file, relative to $ANDROID_TOP.
+    Args:
+      path: The filepath to the CSV file, relative to $ANDROID_TOP.
 
-  Returns:
-    A file_sections_pb2.File if the file was found; None otherwise.
-  """
-  file_proto = None
-  with open(path, newline='') as csv_file:
-    file_proto = file_sections_pb2.File()
-    if path.endswith(BLOATY_EXTENSION):
-      file_proto.path = path[:-len(BLOATY_EXTENSION)]
-    section_reader = csv.DictReader(csv_file)
-    for row in section_reader:
-      section = file_proto.sections.add()
-      section.name = row["sections"]
-      section.vm_size = int(row["vmsize"])
-      section.file_size = int(row["filesize"])
-  return file_proto
+    Returns:
+      A file_sections_pb2.File if the file was found; None otherwise.
+    """
+    file_proto = None
+    with open(path, newline='') as csv_file:
+        file_proto = file_sections_pb2.File()
+        if path.endswith(BLOATY_EXTENSION):
+            file_proto.path = path[: -len(BLOATY_EXTENSION)]
+        section_reader = csv.DictReader(csv_file)
+        for row in section_reader:
+            section = file_proto.sections.add()
+            section.name = row["sections"]
+            section.vm_size = int(row["vmsize"])
+            section.file_size = int(row["filesize"])
+    return file_proto
+
 
 def create_file_size_metrics(input_list, output_proto):
-  """Creates a FileSizeMetrics proto from a list of CSV files.
+    """Creates a FileSizeMetrics proto from a list of CSV files.
 
-  Args:
-    input_list: The path to the file which contains the list of CSV files. Each
-        filepath is separated by a space.
-    output_proto: The path for the output protobuf. It will be compressed using
-        gzip.
-  """
-  metrics = file_sections_pb2.FileSizeMetrics()
-  reader = ninja_rsp.NinjaRspFileReader(input_list)
-  for csv_path in reader:
-    file_proto = parse_csv(csv_path)
-    if file_proto:
-      metrics.files.append(file_proto)
-  with gzip.open(output_proto, "wb") as output:
-    output.write(metrics.SerializeToString())
+    Args:
+      input_list: The path to the file which contains the list of CSV files.
+          Each filepath is separated by a space.
+      output_proto: The path for the output protobuf. It will be compressed
+          using gzip.
+    """
+    metrics = file_sections_pb2.FileSizeMetrics()
+    reader = ninja_rsp.NinjaRspFileReader(input_list)
+    for csv_path in reader:
+        file_proto = parse_csv(csv_path)
+        if file_proto:
+            metrics.files.append(file_proto)
+    with gzip.open(output_proto, "wb") as output:
+        output.write(metrics.SerializeToString())
+
 
 def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument("input_list_file", help="List of bloaty csv files.")
-  parser.add_argument("output_proto", help="Output proto.")
-  args = parser.parse_args()
-  create_file_size_metrics(args.input_list_file, args.output_proto)
+    parser = argparse.ArgumentParser()
+    parser.add_argument("input_list_file", help="List of bloaty csv files.")
+    parser.add_argument("output_proto", help="Output proto.")
+    args = parser.parse_args()
+    create_file_size_metrics(args.input_list_file, args.output_proto)
+
 
 if __name__ == '__main__':
-  main()
+    main()
diff --git a/bloaty/bloaty_merger_test.py b/bloaty/bloaty_merger_test.py
index 9de049a..83680b9 100644
--- a/bloaty/bloaty_merger_test.py
+++ b/bloaty/bloaty_merger_test.py
@@ -14,6 +14,7 @@
 import gzip
 import unittest
 
+# pylint: disable=import-error
 from pyfakefs import fake_filesystem_unittest
 
 import bloaty_merger
@@ -21,46 +22,46 @@
 
 
 class BloatyMergerTestCase(fake_filesystem_unittest.TestCase):
-  def setUp(self):
-    self.setUpPyfakefs()
+    def setUp(self):
+        self.setUpPyfakefs()
 
-  def test_parse_csv(self):
-    csv_content = "sections,vmsize,filesize\nsection1,2,3\n"
-    self.fs.create_file("file1.bloaty.csv", contents=csv_content)
-    pb = bloaty_merger.parse_csv("file1.bloaty.csv")
-    self.assertEqual(pb.path, "file1")
-    self.assertEqual(len(pb.sections), 1)
-    s = pb.sections[0]
-    self.assertEqual(s.name, "section1")
-    self.assertEqual(s.vm_size, 2)
-    self.assertEqual(s.file_size, 3)
+    def test_parse_csv(self):
+        csv_content = "sections,vmsize,filesize\nsection1,2,3\n"
+        self.fs.create_file("file1.bloaty.csv", contents=csv_content)
+        pb = bloaty_merger.parse_csv("file1.bloaty.csv")
+        self.assertEqual(pb.path, "file1")
+        self.assertEqual(len(pb.sections), 1)
+        s = pb.sections[0]
+        self.assertEqual(s.name, "section1")
+        self.assertEqual(s.vm_size, 2)
+        self.assertEqual(s.file_size, 3)
 
-  def test_missing_file(self):
-    with self.assertRaises(FileNotFoundError):
-      bloaty_merger.parse_csv("missing.bloaty.csv")
+    def test_missing_file(self):
+        with self.assertRaises(FileNotFoundError):
+            bloaty_merger.parse_csv("missing.bloaty.csv")
 
-  def test_malformed_csv(self):
-    csv_content = "header1,heaVder2,header3\n4,5,6\n"
-    self.fs.create_file("file1.bloaty.csv", contents=csv_content)
-    with self.assertRaises(KeyError):
-      bloaty_merger.parse_csv("file1.bloaty.csv")
+    def test_malformed_csv(self):
+        csv_content = "header1,heaVder2,header3\n4,5,6\n"
+        self.fs.create_file("file1.bloaty.csv", contents=csv_content)
+        with self.assertRaises(KeyError):
+            bloaty_merger.parse_csv("file1.bloaty.csv")
 
-  def test_create_file_metrics(self):
-    file_list = "file1.bloaty.csv file2.bloaty.csv"
-    file1_content = "sections,vmsize,filesize\nsection1,2,3\nsection2,7,8"
-    file2_content = "sections,vmsize,filesize\nsection1,4,5\n"
+    def test_create_file_metrics(self):
+        file_list = "file1.bloaty.csv file2.bloaty.csv"
+        file1_content = "sections,vmsize,filesize\nsection1,2,3\nsection2,7,8"
+        file2_content = "sections,vmsize,filesize\nsection1,4,5\n"
 
-    self.fs.create_file("files.lst", contents=file_list)
-    self.fs.create_file("file1.bloaty.csv", contents=file1_content)
-    self.fs.create_file("file2.bloaty.csv", contents=file2_content)
+        self.fs.create_file("files.lst", contents=file_list)
+        self.fs.create_file("file1.bloaty.csv", contents=file1_content)
+        self.fs.create_file("file2.bloaty.csv", contents=file2_content)
 
-    bloaty_merger.create_file_size_metrics("files.lst", "output.pb.gz")
+        bloaty_merger.create_file_size_metrics("files.lst", "output.pb.gz")
 
-    metrics = file_sections_pb2.FileSizeMetrics()
-    with gzip.open("output.pb.gz", "rb") as output:
-      metrics.ParseFromString(output.read())
+        metrics = file_sections_pb2.FileSizeMetrics()
+        with gzip.open("output.pb.gz", "rb") as output:
+            metrics.ParseFromString(output.read())
 
 
 if __name__ == '__main__':
-  suite = unittest.TestLoader().loadTestsFromTestCase(BloatyMergerTestCase)
-  unittest.TextTestRunner(verbosity=2).run(suite)
+    suite = unittest.TestLoader().loadTestsFromTestCase(BloatyMergerTestCase)
+    unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 96a8b09..a64d474 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -244,7 +244,7 @@
 		dir := bpCtx.ModuleDir(m)
 		dirs[dir] = true
 
-		var t BazelTarget
+		var targets []BazelTarget
 
 		switch ctx.Mode() {
 		case Bp2Build:
@@ -258,18 +258,23 @@
 				if _, exists := buildFileToAppend[pathToBuildFile]; exists {
 					return
 				}
-				var err error
-				t, err = getHandcraftedBuildContent(ctx, b, pathToBuildFile)
+				t, err := getHandcraftedBuildContent(ctx, b, pathToBuildFile)
 				if err != nil {
 					panic(fmt.Errorf("Error converting %s: %s", bpCtx.ModuleName(m), err))
 				}
+				targets = append(targets, t)
 				// TODO(b/181575318): currently we append the whole BUILD file, let's change that to do
 				// something more targeted based on the rule type and target
 				buildFileToAppend[pathToBuildFile] = true
-			} else if btm, ok := m.(android.BazelTargetModule); ok {
-				t = generateBazelTarget(bpCtx, m, btm)
-				metrics.RuleClassCount[t.ruleClass] += 1
-				compatLayer.AddNameToLabelEntry(m.Name(), t.Label())
+			} else if aModule, ok := m.(android.Module); ok && aModule.IsConvertedByBp2build() {
+				targets = generateBazelTargets(bpCtx, aModule)
+				for _, t := range targets {
+					if t.name == m.Name() {
+						// only add targets that exist in Soong to compatibility layer
+						compatLayer.AddNameToLabelEntry(m.Name(), t.Label())
+					}
+					metrics.RuleClassCount[t.ruleClass] += 1
+				}
 			} else {
 				metrics.TotalModuleCount += 1
 				return
@@ -281,12 +286,13 @@
 				// be mapped cleanly to a bazel label.
 				return
 			}
-			t = generateSoongModuleTarget(bpCtx, m)
+			t := generateSoongModuleTarget(bpCtx, m)
+			targets = append(targets, t)
 		default:
 			panic(fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
 		}
 
-		buildFileToTargets[dir] = append(buildFileToTargets[dir], t)
+		buildFileToTargets[dir] = append(buildFileToTargets[dir], targets...)
 	})
 	if generateFilegroups {
 		// Add a filegroup target that exposes all sources in the subtree of this package
@@ -326,22 +332,38 @@
 	}, nil
 }
 
-func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module, btm android.BazelTargetModule) BazelTarget {
-	ruleClass := btm.RuleClass()
-	bzlLoadLocation := btm.BzlLoadLocation()
+func generateBazelTargets(ctx bpToBuildContext, m android.Module) []BazelTarget {
+	var targets []BazelTarget
+	for _, m := range m.Bp2buildTargets() {
+		targets = append(targets, generateBazelTarget(ctx, m))
+	}
+	return targets
+}
+
+type bp2buildModule interface {
+	TargetName() string
+	TargetPackage() string
+	BazelRuleClass() string
+	BazelRuleLoadLocation() string
+	BazelAttributes() interface{}
+}
+
+func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) BazelTarget {
+	ruleClass := m.BazelRuleClass()
+	bzlLoadLocation := m.BazelRuleLoadLocation()
 
 	// extract the bazel attributes from the module.
-	props := getBuildProperties(ctx, m)
+	props := extractModuleProperties([]interface{}{m.BazelAttributes()})
 
 	delete(props.Attrs, "bp2build_available")
 
 	// Return the Bazel target with rule class and attributes, ready to be
 	// code-generated.
 	attributes := propsToAttributes(props.Attrs)
-	targetName := targetNameForBp2Build(ctx, m)
+	targetName := m.TargetName()
 	return BazelTarget{
 		name:            targetName,
-		packageName:     ctx.ModuleDir(m),
+		packageName:     m.TargetPackage(),
 		ruleClass:       ruleClass,
 		bzlLoadLocation: bzlLoadLocation,
 		content: fmt.Sprintf(
@@ -391,24 +413,21 @@
 }
 
 func getBuildProperties(ctx bpToBuildContext, m blueprint.Module) BazelAttributes {
-	var allProps map[string]string
 	// 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 {
-		allProps = ExtractModuleProperties(aModule)
+		return extractModuleProperties(aModule.GetProperties())
 	}
 
-	return BazelAttributes{
-		Attrs: allProps,
-	}
+	return BazelAttributes{}
 }
 
 // Generically extract module properties and types into a map, keyed by the module property name.
-func ExtractModuleProperties(aModule android.Module) map[string]string {
+func extractModuleProperties(props []interface{}) BazelAttributes {
 	ret := map[string]string{}
 
 	// Iterate over this android.Module's property structs.
-	for _, properties := range aModule.GetProperties() {
+	for _, properties := range props {
 		propertiesValue := reflect.ValueOf(properties)
 		// Check that propertiesValue is a pointer to the Properties struct, like
 		// *cc.BaseLinkerProperties or *java.CompilerProperties.
@@ -427,7 +446,9 @@
 		}
 	}
 
-	return ret
+	return BazelAttributes{
+		Attrs: ret,
+	}
 }
 
 func isStructPtr(t reflect.Type) bool {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index eb3a73f..0d9106c 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -480,12 +480,12 @@
     name = "bar",
 )
 
-my_proto_library(
-    name = "bar_my_proto_library_deps",
-)
-
 proto_library(
     name = "bar_proto_library_deps",
+)
+
+my_proto_library(
+    name = "bar_my_proto_library_deps",
 )`,
 			expectedBazelTargetCount: 3,
 			expectedLoadStatements: `load("//build/bazel/rules:proto.bzl", "my_proto_library", "proto_library")
@@ -1213,22 +1213,24 @@
 
 	dir := "."
 	for _, testCase := range testCases {
-		config := android.TestConfig(buildDir, nil, testCase.bp, nil)
-		ctx := android.NewTestContext(config)
-		ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
-		ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
-		ctx.RegisterForBazelConversion()
+		t.Run(testCase.description, func(t *testing.T) {
+			config := android.TestConfig(buildDir, nil, testCase.bp, nil)
+			ctx := android.NewTestContext(config)
+			ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+			ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
+			ctx.RegisterForBazelConversion()
 
-		_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
-		android.FailIfErrored(t, errs)
-		_, errs = ctx.ResolveDependencies(config)
-		android.FailIfErrored(t, errs)
+			_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
+			android.FailIfErrored(t, errs)
+			_, errs = ctx.ResolveDependencies(config)
+			android.FailIfErrored(t, errs)
 
-		codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
-		bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
-		if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
-			t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
-		}
+			codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+			bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+			if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
+				t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
+			}
+		})
 	}
 }
 
diff --git a/bp2build/testing.go b/bp2build/testing.go
index faf1a44..266b817 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -140,16 +140,6 @@
 	customBazelModuleAttributes
 }
 
-func customBazelModuleFactory() android.Module {
-	module := &customBazelModule{}
-	module.AddProperties(&module.customBazelModuleAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
-func (m *customBazelModule) Name() string                                          { return m.BaseModuleName() }
-func (m *customBazelModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
 func customBp2BuildMutator(ctx android.TopDownMutatorContext) {
 	if m, ok := ctx.Module().(*customModule); ok {
 		if !m.ConvertWithBp2build(ctx) {
@@ -178,7 +168,7 @@
 			Rule_class: "custom",
 		}
 
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, m.Name(), props, attrs)
+		ctx.CreateBazelTargetModule(m.Name(), props, attrs)
 	}
 }
 
@@ -197,19 +187,19 @@
 			Rule_class:        "my_library",
 			Bzl_load_location: "//build/bazel/rules:rules.bzl",
 		}
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName, myLibraryProps, attrs)
+		ctx.CreateBazelTargetModule(baseName, myLibraryProps, attrs)
 
 		protoLibraryProps := bazel.BazelTargetModuleProperties{
 			Rule_class:        "proto_library",
 			Bzl_load_location: "//build/bazel/rules:proto.bzl",
 		}
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName+"_proto_library_deps", protoLibraryProps, attrs)
+		ctx.CreateBazelTargetModule(baseName+"_proto_library_deps", protoLibraryProps, attrs)
 
 		myProtoLibraryProps := bazel.BazelTargetModuleProperties{
 			Rule_class:        "my_proto_library",
 			Bzl_load_location: "//build/bazel/rules:proto.bzl",
 		}
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
+		ctx.CreateBazelTargetModule(baseName+"_my_proto_library_deps", myProtoLibraryProps, attrs)
 	}
 }
 
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 1706d72..537f01c 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -132,27 +132,7 @@
 }
 
 func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
-	var props StaticOrSharedProperties
-	if isStatic {
-		props = lib.StaticProperties.Static
-	} else {
-		props = lib.SharedProperties.Shared
-	}
-
-	system_dynamic_deps := bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.System_shared_libs))
-	system_dynamic_deps.ForceSpecifyEmptyList = true
-	if system_dynamic_deps.IsEmpty() && props.System_shared_libs != nil {
-		system_dynamic_deps.Value.Includes = []bazel.Label{}
-	}
-
-	attrs := staticOrSharedAttributes{
-		Copts:               bazel.StringListAttribute{Value: props.Cflags},
-		Srcs:                bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
-		Static_deps:         bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
-		Dynamic_deps:        bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)),
-		Whole_archive_deps:  bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)),
-		System_dynamic_deps: system_dynamic_deps,
-	}
+	attrs := staticOrSharedAttributes{}
 
 	setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
 		attrs.Copts.SetSelectValue(axis, config, props.Cflags)
@@ -162,6 +142,10 @@
 		attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs))
 		attrs.System_dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.System_shared_libs))
 	}
+	// system_dynamic_deps distinguishes between nil/empty list behavior:
+	//    nil -> use default values
+	//    empty list -> no values specified
+	attrs.System_dynamic_deps.ForceSpecifyEmptyList = true
 
 	if isStatic {
 		for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
@@ -195,18 +179,8 @@
 }
 
 func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
-	prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
-	prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
-
 	var srcLabelAttribute bazel.LabelAttribute
 
-	if len(prebuiltLinker.properties.Srcs) > 1 {
-		ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
-	}
-
-	if len(prebuiltLinker.properties.Srcs) == 1 {
-		srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]))
-	}
 	for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
 		for config, props := range configToProps {
 			if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
@@ -298,36 +272,7 @@
 		return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
 	}
 
-	for _, props := range module.compiler.compilerProps() {
-		if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
-			srcs.SetValue(parseSrcs(baseCompilerProps))
-			copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags)
-			asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
-			conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
-			cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
-			rtti.Value = baseCompilerProps.Rtti
-
-			for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
-				copts.Value = append(copts.Value, includeFlags(dir)...)
-				asFlags.Value = append(asFlags.Value, includeFlags(dir)...)
-			}
-			break
-		}
-	}
-
-	// Handle include_build_directory prop. If the property is true, then the
-	// target has access to all headers recursively in the package, and has
-	// "-I<module-dir>" in its copts.
-	if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
-		copts.Value = append(copts.Value, includeFlags(".")...)
-		asFlags.Value = append(asFlags.Value, includeFlags(".")...)
-	} else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
-		copts.Value = append(copts.Value, includeFlags(".")...)
-		asFlags.Value = append(asFlags.Value, includeFlags(".")...)
-	}
-
 	archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
-
 	for axis, configToProps := range archVariantCompilerProps {
 		for config, props := range configToProps {
 			if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
@@ -345,6 +290,14 @@
 					archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
 				}
 
+				if axis == bazel.NoConfigAxis {
+					if includeBuildDirectory(baseCompilerProps.Include_build_directory) {
+						flags := includeFlags(".")
+						archVariantCopts = append(archVariantCopts, flags...)
+						archVariantAsflags = append(archVariantAsflags, flags...)
+					}
+				}
+
 				copts.SetSelectValue(axis, config, archVariantCopts)
 				asFlags.SetSelectValue(axis, config, archVariantAsflags)
 				conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
@@ -423,7 +376,7 @@
 	var exportedDeps bazel.LabelListAttribute
 	var dynamicDeps bazel.LabelListAttribute
 	var wholeArchiveDeps bazel.LabelListAttribute
-	var systemSharedDeps bazel.LabelListAttribute
+	systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
 	var linkopts bazel.StringListAttribute
 	var versionScript bazel.LabelAttribute
 	var useLibcrt bazel.BoolAttribute
@@ -434,15 +387,6 @@
 	var stripAll bazel.BoolAttribute
 	var stripNone bazel.BoolAttribute
 
-	if libraryDecorator, ok := module.linker.(*libraryDecorator); ok {
-		stripProperties := libraryDecorator.stripper.StripProperties
-		stripKeepSymbols.Value = stripProperties.Strip.Keep_symbols
-		stripKeepSymbolsList.Value = stripProperties.Strip.Keep_symbols_list
-		stripKeepSymbolsAndDebugFrame.Value = stripProperties.Strip.Keep_symbols_and_debug_frame
-		stripAll.Value = stripProperties.Strip.All
-		stripNone.Value = stripProperties.Strip.None
-	}
-
 	for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
 		for config, props := range configToProps {
 			if stripProperties, ok := props.(*StripProperties); ok {
@@ -455,54 +399,22 @@
 		}
 	}
 
-	for _, linkerProps := range module.linker.linkerProps() {
-		if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
-			// Excludes to parallel Soong:
-			// https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
-			staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
-			staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
-			wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
-			wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
-
-			systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
-			systemSharedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
-			systemSharedDeps.ForceSpecifyEmptyList = true
-			if systemSharedDeps.Value.IsNil() && baseLinkerProps.System_shared_libs != nil {
-				systemSharedDeps.Value.Includes = []bazel.Label{}
-			}
-
-			sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
-
-			dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
-
-			headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
-			headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
-			// TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
-			// export_generated_headers
-			exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
-			exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
-
-			linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
-			if baseLinkerProps.Version_script != nil {
-				versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
-			}
-			useLibcrt.Value = baseLinkerProps.libCrt()
-
-			break
-		}
-	}
-
 	for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
 		for config, props := range configToProps {
 			if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
+				// Excludes to parallel Soong:
+				// https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
 				staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
 				staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
 				wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
 				wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
 
-				systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
-				if len(systemSharedLibs) == 0 && baseLinkerProps.System_shared_libs != nil {
-					systemSharedLibs = baseLinkerProps.System_shared_libs
+				systemSharedLibs := baseLinkerProps.System_shared_libs
+				// systemSharedLibs distinguishes between nil/empty list behavior:
+				//    nil -> use default values
+				//    empty list -> no values specified
+				if len(systemSharedLibs) > 0 {
+					systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
 				}
 				systemSharedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
 
@@ -642,22 +554,24 @@
 	// are root-relative.
 	includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
 	includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
-	includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
+	var includeDirsAttribute bazel.StringListAttribute
 
-	getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties) []string {
+	getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties, subtract bool) []string {
 		variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
 		variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
 
-		// To avoid duplicate includes when base includes + arch includes are combined
-		// TODO: This doesn't take conflicts between arch and os includes into account
-		variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
+		if subtract {
+			// To avoid duplicate includes when base includes + arch includes are combined
+			// TODO: Add something similar to ResolveExcludes() in bazel/properties.go
+			variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
+		}
 		return variantIncludeDirs
 	}
 
 	for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
 		for config, props := range configToProps {
 			if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
-				archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
+				archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties, axis != bazel.NoConfigAxis)
 				if len(archVariantIncludeDirs) > 0 {
 					includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
 				}
diff --git a/cc/cc.go b/cc/cc.go
index 2006ecf..243f0a5 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -822,6 +822,16 @@
 }
 
 func (c *Module) AddJSONData(d *map[string]interface{}) {
+	var hasAidl, hasLex, hasProto, hasRenderscript, hasSysprop, hasWinMsg, hasYacc bool
+	if b, ok := c.compiler.(*baseCompiler); ok {
+		hasAidl = b.hasSrcExt(".aidl")
+		hasLex = b.hasSrcExt(".l") || b.hasSrcExt(".ll")
+		hasProto = b.hasSrcExt(".proto")
+		hasRenderscript = b.hasSrcExt(".rscript") || b.hasSrcExt(".fs")
+		hasSysprop = b.hasSrcExt(".sysprop")
+		hasWinMsg = b.hasSrcExt(".mc")
+		hasYacc = b.hasSrcExt(".y") || b.hasSrcExt(".yy")
+	}
 	c.AndroidModuleBase().AddJSONData(d)
 	(*d)["Cc"] = map[string]interface{}{
 		"SdkVersion":             c.SdkVersion(),
@@ -858,6 +868,14 @@
 		"IsVendorPublicLibrary":  c.IsVendorPublicLibrary(),
 		"ApexSdkVersion":         c.apexSdkVersion,
 		"TestFor":                c.TestFor(),
+		"AidlSrcs":               hasAidl,
+		"LexSrcs":                hasLex,
+		"ProtoSrcs":              hasProto,
+		"RenderscriptSrcs":       hasRenderscript,
+		"SyspropSrcs":            hasSysprop,
+		"WinMsgSrcs":             hasWinMsg,
+		"YaccSrsc":               hasYacc,
+		"OnlyCSrcs":              !(hasAidl || hasLex || hasProto || hasRenderscript || hasSysprop || hasWinMsg || hasYacc),
 	}
 }
 
diff --git a/cc/compiler.go b/cc/compiler.go
index 03214c8..34d68a1 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -261,8 +261,12 @@
 	return []interface{}{&compiler.Properties, &compiler.Proto}
 }
 
+func includeBuildDirectory(prop *bool) bool {
+	return proptools.BoolDefault(prop, true)
+}
+
 func (compiler *baseCompiler) includeBuildDirectory() bool {
-	return proptools.BoolDefault(compiler.Properties.Include_build_directory, true)
+	return includeBuildDirectory(compiler.Properties.Include_build_directory)
 }
 
 func (compiler *baseCompiler) compilerInit(ctx BaseModuleContext) {}
diff --git a/cc/library.go b/cc/library.go
index b2360e9..1526f81 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -27,6 +27,7 @@
 	"android/soong/bazel"
 	"android/soong/bazel/cquery"
 	"android/soong/cc/config"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/pathtools"
 )
@@ -256,24 +257,6 @@
 	None                         bazel.BoolAttribute
 }
 
-type bazelCcLibrary struct {
-	android.BazelTargetModuleBase
-	bazelCcLibraryAttributes
-}
-
-func (m *bazelCcLibrary) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelCcLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
-func BazelCcLibraryFactory() android.Module {
-	module := &bazelCcLibrary{}
-	module.AddProperties(&module.bazelCcLibraryAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func CcLibraryBp2Build(ctx android.TopDownMutatorContext) {
 	m, ok := ctx.Module().(*Module)
 	if !ok || !m.ConvertWithBp2build(ctx) {
@@ -346,7 +329,7 @@
 		Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelCcLibraryFactory, m.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(m.Name(), props, attrs)
 }
 
 // cc_library creates both static and/or shared libraries for a device and/or
@@ -1754,7 +1737,7 @@
 					mayUseCoreVariant = false
 				}
 
-				if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
+				if ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) {
 					mayUseCoreVariant = false
 				}
 
@@ -2414,7 +2397,7 @@
 		Bzl_load_location: "//build/bazel/rules:cc_library_static.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelCcLibraryStaticFactory, module.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(module.Name(), props, attrs)
 }
 
 func CcLibraryStaticBp2Build(ctx android.TopDownMutatorContext) {
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 1a276f4..44a7a71 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -111,18 +111,6 @@
 	System_dynamic_deps bazel.LabelListAttribute
 }
 
-type bazelCcLibraryHeaders struct {
-	android.BazelTargetModuleBase
-	bazelCcLibraryHeadersAttributes
-}
-
-func BazelCcLibraryHeadersFactory() android.Module {
-	module := &bazelCcLibraryHeaders{}
-	module.AddProperties(&module.bazelCcLibraryHeadersAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) {
 	module, ok := ctx.Module().(*Module)
 	if !ok {
@@ -155,11 +143,5 @@
 		Bzl_load_location: "//build/bazel/rules:cc_library_headers.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelCcLibraryHeadersFactory, module.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(module.Name(), props, attrs)
 }
-
-func (m *bazelCcLibraryHeaders) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelCcLibraryHeaders) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/cc/object.go b/cc/object.go
index 5952f1e..606e368 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -130,24 +130,6 @@
 	Asflags bazel.StringListAttribute
 }
 
-type bazelObject struct {
-	android.BazelTargetModuleBase
-	bazelObjectAttributes
-}
-
-func (m *bazelObject) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelObject) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
-func BazelObjectFactory() android.Module {
-	module := &bazelObject{}
-	module.AddProperties(&module.bazelObjectAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 // ObjectBp2Build is the bp2build converter from cc_object modules to the
 // Bazel equivalent target, plus any necessary include deps for the cc_object.
 func ObjectBp2Build(ctx android.TopDownMutatorContext) {
@@ -200,7 +182,7 @@
 		Bzl_load_location: "//build/bazel/rules:cc_object.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelObjectFactory, m.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(m.Name(), props, attrs)
 }
 
 func (object *objectLinker) appendLdflags(flags []string) {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index b244394..dd15ae1 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -437,8 +437,8 @@
 		}
 	}
 
-	// Enable CFI for all components in the include paths (for Aarch64 only)
-	if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && ctx.Arch().ArchType == android.Arm64 {
+	// Enable CFI for non-host components in the include paths
+	if s.Cfi == nil && ctx.Config().CFIEnabledForPath(ctx.ModuleDir()) && !ctx.Host() {
 		s.Cfi = proptools.BoolPtr(true)
 		if inList("cfi", ctx.Config().SanitizeDeviceDiag()) {
 			s.Diag.Cfi = proptools.BoolPtr(true)
diff --git a/cc/symbolfile/__init__.py b/cc/symbolfile/__init__.py
index 31c4443..f8d1841 100644
--- a/cc/symbolfile/__init__.py
+++ b/cc/symbolfile/__init__.py
@@ -329,7 +329,7 @@
     def parse(self) -> List[Version]:
         """Parses the symbol file and returns a list of Version objects."""
         versions = []
-        while self.next_line() != '':
+        while self.next_line():
             assert self.current_line is not None
             if '{' in self.current_line:
                 versions.append(self.parse_version())
@@ -376,7 +376,7 @@
         symbols: List[Symbol] = []
         global_scope = True
         cpp_symbols = False
-        while self.next_line() != '':
+        while self.next_line():
             if '}' in self.current_line:
                 # Line is something like '} BASE; # tags'. Both base and tags
                 # are optional here.
@@ -428,11 +428,11 @@
         A return value of '' indicates EOF.
         """
         line = self.input_file.readline()
-        while line.strip() == '' or line.strip().startswith('#'):
+        while not line.strip() or line.strip().startswith('#'):
             line = self.input_file.readline()
 
             # We want to skip empty lines, but '' indicates EOF.
-            if line == '':
+            if not line:
                 break
         self.current_line = line
         return self.current_line
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index af935db..8aea037 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -25,9 +25,9 @@
 
 	"android/soong/bp2build"
 	"android/soong/shared"
-
 	"github.com/google/blueprint/bootstrap"
 	"github.com/google/blueprint/deptools"
+	"github.com/google/blueprint/pathtools"
 
 	"android/soong/android"
 )
@@ -38,6 +38,8 @@
 	availableEnvFile string
 	usedEnvFile      string
 
+	globFile    string
+	globListDir string
 	delveListen string
 	delvePath   string
 
@@ -65,8 +67,8 @@
 	flag.StringVar(&bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
 
 	flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
-	flag.StringVar(&cmdlineArgs.GlobFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output")
-	flag.StringVar(&cmdlineArgs.GlobListDir, "globListDir", "", "the directory containing the glob list files")
+	flag.StringVar(&globFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output")
+	flag.StringVar(&globListDir, "globListDir", "", "the directory containing the glob list files")
 	flag.StringVar(&cmdlineArgs.BuildDir, "b", ".", "the build output directory")
 	flag.StringVar(&cmdlineArgs.NinjaBuildDir, "n", "", "the ninja builddir directory")
 	flag.StringVar(&cmdlineArgs.DepFile, "d", "", "the dependency file to output")
@@ -143,6 +145,10 @@
 	secondArgs = cmdlineArgs
 	ninjaDeps := bootstrap.RunBlueprint(secondArgs, secondCtx.Context, secondConfig)
 	ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
+
+	globListFiles := writeBuildGlobsNinjaFile(secondCtx.SrcDir(), configuration.BuildDir(), secondCtx.Globs, configuration)
+	ninjaDeps = append(ninjaDeps, globListFiles...)
+
 	err = deptools.WriteDepFile(shared.JoinPath(topDir, secondArgs.DepFile), secondArgs.OutFile, ninjaDeps)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "Error writing depfile '%s': %s\n", secondArgs.DepFile, err)
@@ -191,6 +197,17 @@
 	writeFakeNinjaFile(extraNinjaDeps, configuration.BuildDir())
 }
 
+func writeBuildGlobsNinjaFile(srcDir, buildDir string, globs func() pathtools.MultipleGlobResults, config interface{}) []string {
+	globDir := bootstrap.GlobDirectory(buildDir, globListDir)
+	bootstrap.WriteBuildGlobsNinjaFile(&bootstrap.GlobSingleton{
+		GlobLister: globs,
+		GlobFile:   globFile,
+		GlobDir:    globDir,
+		SrcDir:     srcDir,
+	}, config)
+	return bootstrap.GlobFileListFiles(globDir)
+}
+
 // 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.
@@ -215,6 +232,10 @@
 	} else {
 		ninjaDeps := bootstrap.RunBlueprint(blueprintArgs, ctx.Context, configuration)
 		ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
+
+		globListFiles := writeBuildGlobsNinjaFile(ctx.SrcDir(), configuration.BuildDir(), ctx.Globs, configuration)
+		ninjaDeps = append(ninjaDeps, globListFiles...)
+
 		err := deptools.WriteDepFile(shared.JoinPath(topDir, blueprintArgs.DepFile), blueprintArgs.OutFile, ninjaDeps)
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "Error writing depfile '%s': %s\n", blueprintArgs.DepFile, err)
@@ -484,13 +505,8 @@
 	ninjaDeps := bootstrap.RunBlueprint(blueprintArgs, bp2buildCtx.Context, configuration)
 	ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
 
-	// Generate out/soong/.bootstrap/build-globs.ninja with the actions to generate flattened globfiles
-	// containing the globs seen during bp2build conversion
-	if blueprintArgs.GlobFile != "" {
-		bootstrap.WriteBuildGlobsNinjaFile(blueprintArgs.GlobListDir, bp2buildCtx.Context, blueprintArgs, configuration)
-	}
-	// Add the depfile on the expanded globs in out/soong/.primary/globs
-	ninjaDeps = append(ninjaDeps, bootstrap.GlobFileListFiles(configuration, blueprintArgs.GlobListDir)...)
+	globListFiles := writeBuildGlobsNinjaFile(bp2buildCtx.SrcDir(), configuration.BuildDir(), bp2buildCtx.Globs, configuration)
+	ninjaDeps = append(ninjaDeps, globListFiles...)
 
 	// Run the code-generation phase to convert BazelTargetModules to BUILD files
 	// and print conversion metrics to the user.
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 8aeb0dd..3213e5c 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -662,18 +662,6 @@
 	Installable bazel.BoolAttribute
 }
 
-type bazelPrebuiltEtc struct {
-	android.BazelTargetModuleBase
-	bazelPrebuiltEtcAttributes
-}
-
-func BazelPrebuiltEtcFactory() android.Module {
-	module := &bazelPrebuiltEtc{}
-	module.AddProperties(&module.bazelPrebuiltEtcAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func PrebuiltEtcBp2Build(ctx android.TopDownMutatorContext) {
 	module, ok := ctx.Module().(*PrebuiltEtc)
 	if !ok {
@@ -723,11 +711,5 @@
 		Bzl_load_location: "//build/bazel/rules:prebuilt_etc.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelPrebuiltEtcFactory, module.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(module.Name(), props, attrs)
 }
-
-func (m *bazelPrebuiltEtc) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelPrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index fdb3618..bde6e97 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -826,18 +826,6 @@
 	Cmd   string
 }
 
-type bazelGenrule struct {
-	android.BazelTargetModuleBase
-	bazelGenruleAttributes
-}
-
-func BazelGenruleFactory() android.Module {
-	module := &bazelGenrule{}
-	module.AddProperties(&module.bazelGenruleAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func GenruleBp2Build(ctx android.TopDownMutatorContext) {
 	m, ok := ctx.Module().(*Module)
 	if !ok || !m.ConvertWithBp2build(ctx) {
@@ -904,15 +892,9 @@
 	}
 
 	// Create the BazelTargetModule.
-	ctx.CreateBazelTargetModule(BazelGenruleFactory, m.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(m.Name(), props, attrs)
 }
 
-func (m *bazelGenrule) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelGenrule) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
 var Bool = proptools.Bool
 var String = proptools.String
 
diff --git a/java/aar.go b/java/aar.go
index 04727e4..afbaea2 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -502,11 +502,12 @@
 	if sdkDep.hasFrameworkLibs() {
 		a.aapt.deps(ctx, sdkDep)
 	}
+	a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
 }
 
 func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	a.aapt.isLibrary = true
-	a.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
+	a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
 	a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts)
 
 	a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
diff --git a/java/app.go b/java/app.go
index 99e2ab6..e7661df 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1385,18 +1385,6 @@
 	Certificate string
 }
 
-type bazelAndroidAppCertificate struct {
-	android.BazelTargetModuleBase
-	bazelAndroidAppCertificateAttributes
-}
-
-func BazelAndroidAppCertificateFactory() android.Module {
-	module := &bazelAndroidAppCertificate{}
-	module.AddProperties(&module.bazelAndroidAppCertificateAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func AndroidAppCertificateBp2Build(ctx android.TopDownMutatorContext) {
 	module, ok := ctx.Module().(*AndroidAppCertificate)
 	if !ok {
@@ -1428,11 +1416,5 @@
 		Bzl_load_location: "//build/bazel/rules:android_app_certificate.bzl",
 	}
 
-	ctx.CreateBazelTargetModule(BazelAndroidAppCertificateFactory, module.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(module.Name(), props, attrs)
 }
-
-func (m *bazelAndroidAppCertificate) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelAndroidAppCertificate) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
diff --git a/java/app_test.go b/java/app_test.go
index 8de6691..c14c65d 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2285,6 +2285,49 @@
 			sdk_version: "current",
 		}
 
+		java_library {
+			name: "runtime-required-x",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "runtime-optional-x",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		android_library {
+			name: "static-x",
+			uses_libs: ["runtime-required-x"],
+			optional_uses_libs: ["runtime-optional-x"],
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "runtime-required-y",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "runtime-optional-y",
+			srcs: ["a.java"],
+			installable: true,
+			sdk_version: "current",
+		}
+
+		java_library {
+			name: "static-y",
+			srcs: ["a.java"],
+			uses_libs: ["runtime-required-y"],
+			optional_uses_libs: ["runtime-optional-y"],
+			sdk_version: "current",
+		}
+
 		// A library that has to use "provides_uses_lib", because:
 		//    - it is not an SDK library
 		//    - its library name is different from its module name
@@ -2307,6 +2350,8 @@
 				// statically linked component libraries should not pull their SDK libraries,
 				// so "fred" should not be added to class loader context
 				"fred.stubs",
+				"static-x",
+				"static-y",
 			],
 			uses_libs: [
 				"foo",
@@ -2356,7 +2401,11 @@
 		`--uses-library foo ` + // TODO(b/132357300): "foo" should not be passed to manifest_fixer
 		`--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer
 		`--uses-library runtime-library ` +
-		`--optional-uses-library bar` // TODO(b/132357300): "bar" should not be passed to manifest_fixer
+		`--uses-library runtime-required-x ` + // TODO(b/132357300): "runtime-required-x" should not be passed to manifest_fixer
+		`--uses-library runtime-required-y ` + // TODO(b/132357300): "runtime-required-y" should not be passed to manifest_fixer
+		`--optional-uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer
+		`--optional-uses-library runtime-optional-x ` + // TODO(b/132357300): "runtime-optional-x" should not be passed to manifest_fixer
+		`--optional-uses-library runtime-optional-y` // TODO(b/132357300): "runtime-optional-y" should not be passed to manifest_fixer
 	android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs)
 
 	// Test that all libraries are verified (library order matters).
@@ -2366,8 +2415,12 @@
 		`--uses-library qux ` +
 		`--uses-library quuz ` +
 		`--uses-library runtime-library ` +
+		`--uses-library runtime-required-x ` +
+		`--uses-library runtime-required-y ` +
 		`--optional-uses-library bar ` +
-		`--optional-uses-library baz `
+		`--optional-uses-library baz ` +
+		`--optional-uses-library runtime-optional-x ` +
+		`--optional-uses-library runtime-optional-y `
 	android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
 
 	// Test that all libraries are verified for an APK (library order matters).
@@ -2387,7 +2440,11 @@
 		`PCL[/system/framework/foo.jar]#` +
 		`PCL[/system/framework/non-sdk-lib.jar]#` +
 		`PCL[/system/framework/bar.jar]#` +
-		`PCL[/system/framework/runtime-library.jar]`
+		`PCL[/system/framework/runtime-library.jar]#` +
+		`PCL[/system/framework/runtime-required-x.jar]#` +
+		`PCL[/system/framework/runtime-optional-x.jar]#` +
+		`PCL[/system/framework/runtime-required-y.jar]#` +
+		`PCL[/system/framework/runtime-optional-y.jar] `
 	android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w)
 
 	// Test conditional context for target SDK version 28.
diff --git a/java/java.go b/java/java.go
index 5bf3d79..b46324f 100644
--- a/java/java.go
+++ b/java/java.go
@@ -511,7 +511,7 @@
 		j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
 	}
 	j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
-	j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
+	j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
 	j.compile(ctx, nil)
 
 	// Collect the module directory for IDE info in java/jdeps.go.
@@ -530,6 +530,7 @@
 
 func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
 	j.deps(ctx)
+	j.usesLibrary.deps(ctx, false)
 }
 
 const (
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index eeec504..938bb28 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -157,7 +157,7 @@
 	qux := result.ModuleForTests("qux", "android_common")
 	if quxLib, ok := qux.Module().(*Library); ok {
 		requiredSdkLibs, optionalSdkLibs := quxLib.ClassLoaderContexts().UsesLibs()
-		android.AssertDeepEquals(t, "qux exports (required)", []string{"foo", "bar", "fred", "quuz"}, requiredSdkLibs)
+		android.AssertDeepEquals(t, "qux exports (required)", []string{"fred", "quuz", "foo", "bar"}, requiredSdkLibs)
 		android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs)
 	}
 }
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 30888c7..b05d340 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -118,7 +118,7 @@
 	"notdir":                              {baseName + ".notdir", starlarkTypeString, hiddenArgNone},
 	"my-dir":                              {"!my-dir", starlarkTypeString, hiddenArgNone},
 	"patsubst":                            {baseName + ".mkpatsubst", starlarkTypeString, hiddenArgNone},
-	"produce_copy_files":                  {baseName + ".produce_copy_files", starlarkTypeList, hiddenArgNone},
+	"product-copy-files-by-pattern":       {baseName + ".product_copy_files_by_pattern", starlarkTypeList, hiddenArgNone},
 	"require-artifacts-in-path":           {baseName + ".require_artifacts_in_path", starlarkTypeVoid, hiddenArgNone},
 	"require-artifacts-in-path-relaxed":   {baseName + ".require_artifacts_in_path_relaxed", starlarkTypeVoid, hiddenArgNone},
 	// TODO(asmundak): remove it once all calls are removed from configuration makefiles. see b/183161002
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index ebaae28..46212ee 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -669,6 +669,7 @@
 $(call add_soong_config_namespace,snsconfig)
 $(call add_soong_config_var_value,snsconfig,imagetype,odm_image)
 PRODUCT_COPY_FILES := $(call copy-files,$(wildcard foo*.mk),etc)
+PRODUCT_COPY_FILES := $(call product-copy-files-by-pattern,from/%,to/%,a b c)
 `,
 		expected: `load("//build/make/core:product_config.rbc", "rblf")
 
@@ -689,6 +690,7 @@
   rblf.add_soong_config_namespace(g, "snsconfig")
   rblf.add_soong_config_var_value(g, "snsconfig", "imagetype", "odm_image")
   cfg["PRODUCT_COPY_FILES"] = rblf.copy_files(rblf.expand_wildcard("foo*.mk"), "etc")
+  cfg["PRODUCT_COPY_FILES"] = rblf.product_copy_files_by_pattern("from/%", "to/%", "a b c")
 `,
 	},
 	{
diff --git a/python/binary.go b/python/binary.go
index e955492..b106536 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -41,24 +41,6 @@
 	Python_version string
 }
 
-type bazelPythonBinary struct {
-	android.BazelTargetModuleBase
-	bazelPythonBinaryAttributes
-}
-
-func BazelPythonBinaryFactory() android.Module {
-	module := &bazelPythonBinary{}
-	module.AddProperties(&module.bazelPythonBinaryAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
-func (m *bazelPythonBinary) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelPythonBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
 func PythonBinaryBp2Build(ctx android.TopDownMutatorContext) {
 	m, ok := ctx.Module().(*Module)
 	if !ok || !m.ConvertWithBp2build(ctx) {
@@ -112,7 +94,7 @@
 		Rule_class: "py_binary",
 	}
 
-	ctx.CreateBazelTargetModule(BazelPythonBinaryFactory, m.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(m.Name(), props, attrs)
 }
 
 type BinaryProperties struct {
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 1647428..c6e98c7 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -527,18 +527,6 @@
 	// visibility
 }
 
-type bazelShBinary struct {
-	android.BazelTargetModuleBase
-	bazelShBinaryAttributes
-}
-
-func BazelShBinaryFactory() android.Module {
-	module := &bazelShBinary{}
-	module.AddProperties(&module.bazelShBinaryAttributes)
-	android.InitBazelTargetModule(module)
-	return module
-}
-
 func ShBinaryBp2Build(ctx android.TopDownMutatorContext) {
 	m, ok := ctx.Module().(*ShBinary)
 	if !ok || !m.ConvertWithBp2build(ctx) {
@@ -556,13 +544,7 @@
 		Rule_class: "sh_binary",
 	}
 
-	ctx.CreateBazelTargetModule(BazelShBinaryFactory, m.Name(), props, attrs)
+	ctx.CreateBazelTargetModule(m.Name(), props, attrs)
 }
 
-func (m *bazelShBinary) Name() string {
-	return m.BaseModuleName()
-}
-
-func (m *bazelShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
-
 var Bool = proptools.Bool
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index 9342d75..76b2ee9 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -477,7 +477,8 @@
   run_soong
   local mtime1=$(stat -c "%y" out/soong/build.ninja)
 
-  prebuilts/build-tools/linux-x86/bin/ninja -f out/soong/build.ninja soong_docs
+  prebuilts/build-tools/linux-x86/bin/ninja -f out/combined.ninja soong_docs
+
   run_soong
   local mtime2=$(stat -c "%y" out/soong/build.ninja)