Merge "android:path attribute is respected for fields in a slice of struct"
diff --git a/android/filegroup.go b/android/filegroup.go
index 674a196..c3bf6f8 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -57,9 +57,9 @@
 		Srcs: BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs),
 	}
 
-	props := bazel.NewBazelTargetModuleProperties(fg.Name(), "filegroup", "")
+	props := bazel.BazelTargetModuleProperties{Rule_class: "filegroup"}
 
-	ctx.CreateBazelTargetModule(BazelFileGroupFactory, props, attrs)
+	ctx.CreateBazelTargetModule(BazelFileGroupFactory, fg.Name(), props, attrs)
 }
 
 type fileGroupProperties struct {
diff --git a/android/module.go b/android/module.go
index bf74cad..58675d4 100644
--- a/android/module.go
+++ b/android/module.go
@@ -507,13 +507,17 @@
 type BazelTargetModule interface {
 	Module
 
-	BazelTargetModuleProperties() *bazel.BazelTargetModuleProperties
+	bazelTargetModuleProperties() *bazel.BazelTargetModuleProperties
+	SetBazelTargetModuleProperties(props bazel.BazelTargetModuleProperties)
+
+	RuleClass() string
+	BzlLoadLocation() string
 }
 
 // InitBazelTargetModule is a wrapper function that decorates BazelTargetModule
 // with property structs containing metadata for bp2build conversion.
 func InitBazelTargetModule(module BazelTargetModule) {
-	module.AddProperties(module.BazelTargetModuleProperties())
+	module.AddProperties(module.bazelTargetModuleProperties())
 	InitAndroidModule(module)
 }
 
@@ -524,11 +528,26 @@
 	Properties bazel.BazelTargetModuleProperties
 }
 
-// BazelTargetModuleProperties getter.
-func (btmb *BazelTargetModuleBase) BazelTargetModuleProperties() *bazel.BazelTargetModuleProperties {
+// bazelTargetModuleProperties getter.
+func (btmb *BazelTargetModuleBase) bazelTargetModuleProperties() *bazel.BazelTargetModuleProperties {
 	return &btmb.Properties
 }
 
+// SetBazelTargetModuleProperties setter for BazelTargetModuleProperties
+func (btmb *BazelTargetModuleBase) SetBazelTargetModuleProperties(props bazel.BazelTargetModuleProperties) {
+	btmb.Properties = props
+}
+
+// RuleClass returns the rule class for this Bazel target
+func (b *BazelTargetModuleBase) RuleClass() string {
+	return b.bazelTargetModuleProperties().Rule_class
+}
+
+// BzlLoadLocation returns the rule class for this Bazel target
+func (b *BazelTargetModuleBase) BzlLoadLocation() string {
+	return b.bazelTargetModuleProperties().Bzl_load_location
+}
+
 // Qualified id for a module
 type qualifiedModuleName struct {
 	// The package (i.e. directory) in which the module is defined, without trailing /
diff --git a/android/mutator.go b/android/mutator.go
index c387193..b023001 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -283,7 +283,7 @@
 	// factory method, just like in CreateModule, but also requires
 	// BazelTargetModuleProperties containing additional metadata for the
 	// bp2build codegenerator.
-	CreateBazelTargetModule(ModuleFactory, bazel.BazelTargetModuleProperties, interface{}) BazelTargetModule
+	CreateBazelTargetModule(ModuleFactory, string, bazel.BazelTargetModuleProperties, interface{}) BazelTargetModule
 }
 
 type topDownMutatorContext struct {
@@ -513,17 +513,25 @@
 
 func (t *topDownMutatorContext) CreateBazelTargetModule(
 	factory ModuleFactory,
+	name string,
 	bazelProps bazel.BazelTargetModuleProperties,
 	attrs interface{}) BazelTargetModule {
-	if !strings.HasPrefix(*bazelProps.Name, bazel.BazelTargetModuleNamePrefix) {
+	if strings.HasPrefix(name, bazel.BazelTargetModuleNamePrefix) {
 		panic(fmt.Errorf(
-			"bp2build error: the bazel target module name must start with '%s': %s",
+			"The %s name prefix is added automatically, do not set it manually: %s",
 			bazel.BazelTargetModuleNamePrefix,
-			*bazelProps.Name,
-		))
+			name))
+	}
+	name = bazel.BazelTargetModuleNamePrefix + name
+	nameProp := struct {
+		Name *string
+	}{
+		Name: &name,
 	}
 
-	return t.CreateModule(factory, &bazelProps, attrs).(BazelTargetModule)
+	b := t.CreateModule(factory, &nameProp, attrs).(BazelTargetModule)
+	b.SetBazelTargetModuleProperties(bazelProps)
+	return b
 }
 
 func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
diff --git a/bazel/properties.go b/bazel/properties.go
index 8055306..a4df4bc 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -14,11 +14,6 @@
 
 package bazel
 
-import (
-	"fmt"
-	"strings"
-)
-
 type bazelModuleProperties struct {
 	// The label of the Bazel target replacing this Soong module.
 	Label string
@@ -37,32 +32,15 @@
 // BazelTargetModuleProperties contain properties and metadata used for
 // Blueprint to BUILD file conversion.
 type BazelTargetModuleProperties struct {
-	Name *string
-
 	// The Bazel rule class for this target.
-	Rule_class string
+	Rule_class string `blueprint:"mutated"`
 
 	// The target label for the bzl file containing the definition of the rule class.
-	Bzl_load_location string
+	Bzl_load_location string `blueprint:"mutated"`
 }
 
 const BazelTargetModuleNamePrefix = "__bp2build__"
 
-func NewBazelTargetModuleProperties(name string, ruleClass string, bzlLoadLocation string) BazelTargetModuleProperties {
-	if strings.HasPrefix(name, BazelTargetModuleNamePrefix) {
-		panic(fmt.Errorf(
-			"The %s name prefix is added automatically, do not set it manually: %s",
-			BazelTargetModuleNamePrefix,
-			name))
-	}
-	name = BazelTargetModuleNamePrefix + name
-	return BazelTargetModuleProperties{
-		Name:              &name,
-		Rule_class:        ruleClass,
-		Bzl_load_location: bzlLoadLocation,
-	}
-}
-
 // Label is used to represent a Bazel compatible Label. Also stores the original bp text to support
 // string replacement.
 type Label struct {
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 41ad409..a4c4a0d 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -19,7 +19,6 @@
 	"android/soong/bazel"
 	"fmt"
 	"reflect"
-	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -178,13 +177,14 @@
 
 		switch ctx.Mode() {
 		case Bp2Build:
-			if _, ok := m.(android.BazelTargetModule); !ok {
+			if b, ok := m.(android.BazelTargetModule); !ok {
 				// Only include regular Soong modules (non-BazelTargetModules) into the total count.
 				totalModuleCount += 1
 				return
+			} else {
+				t = generateBazelTarget(bpCtx, m, b)
+				ruleClassCount[t.ruleClass] += 1
 			}
-			t = generateBazelTarget(bpCtx, m)
-			ruleClassCount[t.ruleClass] += 1
 		case QueryView:
 			// Blocklist certain module types from being generated.
 			if canonicalizeModuleType(bpCtx.ModuleType(m)) == "package" {
@@ -208,36 +208,13 @@
 	return buildFileToTargets, metrics
 }
 
-// Helper method to trim quotes around strings.
-func trimQuotes(s string) string {
-	if s == "" {
-		// strconv.Unquote would error out on empty strings, but this method
-		// allows them, so return the empty string directly.
-		return ""
-	}
-	ret, err := strconv.Unquote(s)
-	if err != nil {
-		// Panic the error immediately.
-		panic(fmt.Errorf("Trying to unquote '%s', but got error: %s", s, err))
-	}
-	return ret
-}
+func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module, b android.BazelTargetModule) BazelTarget {
+	ruleClass := b.RuleClass()
+	bzlLoadLocation := b.BzlLoadLocation()
 
-func generateBazelTarget(ctx bpToBuildContext, m blueprint.Module) BazelTarget {
 	// extract the bazel attributes from the module.
 	props := getBuildProperties(ctx, m)
 
-	// extract the rule class name from the attributes. Since the string value
-	// will be string-quoted, remove the quotes here.
-	ruleClass := trimQuotes(props.Attrs["rule_class"])
-	// Delete it from being generated in the BUILD file.
-	delete(props.Attrs, "rule_class")
-
-	// extract the bzl_load_location, and also remove the quotes around it here.
-	bzlLoadLocation := trimQuotes(props.Attrs["bzl_load_location"])
-	// Delete it from being generated in the BUILD file.
-	delete(props.Attrs, "bzl_load_location")
-
 	delete(props.Attrs, "bp2build_available")
 
 	// Return the Bazel target with rule class and attributes, ready to be
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 9774915..cb50fc8 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -136,9 +136,11 @@
 			String_list_prop: m.props.String_list_prop,
 		}
 
-		props := bazel.NewBazelTargetModuleProperties(m.Name(), "custom", "")
+		props := bazel.BazelTargetModuleProperties{
+			Rule_class: "custom",
+		}
 
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, props, attrs)
+		ctx.CreateBazelTargetModule(customBazelModuleFactory, m.Name(), props, attrs)
 	}
 }
 
@@ -153,26 +155,23 @@
 		baseName := m.Name()
 		attrs := &customBazelModuleAttributes{}
 
-		myLibraryProps := bazel.NewBazelTargetModuleProperties(
-			baseName,
-			"my_library",
-			"//build/bazel/rules:rules.bzl",
-		)
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, myLibraryProps, attrs)
+		myLibraryProps := bazel.BazelTargetModuleProperties{
+			Rule_class:        "my_library",
+			Bzl_load_location: "//build/bazel/rules:rules.bzl",
+		}
+		ctx.CreateBazelTargetModule(customBazelModuleFactory, baseName, myLibraryProps, attrs)
 
-		protoLibraryProps := bazel.NewBazelTargetModuleProperties(
-			baseName+"_proto_library_deps",
-			"proto_library",
-			"//build/bazel/rules:proto.bzl",
-		)
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, protoLibraryProps, 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)
 
-		myProtoLibraryProps := bazel.NewBazelTargetModuleProperties(
-			baseName+"_my_proto_library_deps",
-			"my_proto_library",
-			"//build/bazel/rules:proto.bzl",
-		)
-		ctx.CreateBazelTargetModule(customBazelModuleFactory, myProtoLibraryProps, 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)
 	}
 }
 
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 86ec6e9..e640f12 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -4092,7 +4092,6 @@
 		)
 	})
 
-	// TODO: fix this test as it exports all generated headers.
 	t.Run("ensure only aidl headers are exported", func(t *testing.T) {
 		ctx := testCc(t, genRuleModules+`
 		cc_library_shared {
@@ -4117,18 +4116,15 @@
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
 			`),
 			expectedOrderOnlyDeps(`
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
 			`),
 		)
 	})
 
-	// TODO: fix this test as it exports all generated headers.
 	t.Run("ensure only proto headers are exported", func(t *testing.T) {
 		ctx := testCc(t, genRuleModules+`
 		cc_library_shared {
@@ -4150,22 +4146,15 @@
 			`),
 			expectedSystemIncludeDirs(``),
 			expectedGeneratedHeaders(`
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
 			`),
 			expectedOrderOnlyDeps(`
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
 				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
 			`),
 		)
 	})
 
-	// TODO: fix this test as it exports all generated headers including public and non-public.
-	t.Run("ensure only non-public sysprop headers are exported", func(t *testing.T) {
+	t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
 		ctx := testCc(t, genRuleModules+`
 		cc_library_shared {
 			name: "libfoo",
@@ -4185,19 +4174,10 @@
 			expectedSystemIncludeDirs(``),
 			expectedGeneratedHeaders(`
 				.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/aidl/b.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.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/aidl/b.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
-				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
 			`),
 		)
 	})
diff --git a/cc/compiler.go b/cc/compiler.go
index 5f30d3d..e96295c 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -230,6 +230,8 @@
 	// other modules and filegroups. May include source files that have not yet been translated to
 	// C/C++ (.aidl, .proto, etc.)
 	srcsBeforeGen android.Paths
+
+	generatedSourceInfo
 }
 
 var _ compiler = (*baseCompiler)(nil)
@@ -634,10 +636,11 @@
 
 	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
 
-	srcs, genDeps := genSources(ctx, srcs, buildFlags)
+	srcs, genDeps, info := genSources(ctx, srcs, buildFlags)
 	pathDeps = append(pathDeps, genDeps...)
 
 	compiler.pathDeps = pathDeps
+	compiler.generatedSourceInfo = info
 	compiler.cFlagsDeps = flags.CFlagsDeps
 
 	// Save src, buildFlags and context
diff --git a/cc/gen.go b/cc/gen.go
index 75b9e49..83c019c 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -220,8 +220,35 @@
 	return rcFile, headerFile
 }
 
+// Used to communicate information from the genSources method back to the library code that uses
+// it.
+type generatedSourceInfo struct {
+	// The headers created from .proto files
+	protoHeaders android.Paths
+
+	// The files that can be used as order only dependencies in order to ensure that the proto header
+	// files are up to date.
+	protoOrderOnlyDeps android.Paths
+
+	// The headers created from .aidl files
+	aidlHeaders android.Paths
+
+	// The files that can be used as order only dependencies in order to ensure that the aidl header
+	// files are up to date.
+	aidlOrderOnlyDeps android.Paths
+
+	// The headers created from .sysprop files
+	syspropHeaders android.Paths
+
+	// The files that can be used as order only dependencies in order to ensure that the sysprop
+	// header files are up to date.
+	syspropOrderOnlyDeps android.Paths
+}
+
 func genSources(ctx android.ModuleContext, srcFiles android.Paths,
-	buildFlags builderFlags) (android.Paths, android.Paths) {
+	buildFlags builderFlags) (android.Paths, android.Paths, generatedSourceInfo) {
+
+	var info generatedSourceInfo
 
 	var deps android.Paths
 	var rsFiles android.Paths
@@ -258,7 +285,9 @@
 		case ".proto":
 			ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
 			srcFiles[i] = ccFile
-			deps = append(deps, headerFile)
+			info.protoHeaders = append(info.protoHeaders, headerFile)
+			// Use the generated header as an order only dep to ensure that it is up to date when needed.
+			info.protoOrderOnlyDeps = append(info.protoOrderOnlyDeps, headerFile)
 		case ".aidl":
 			if aidlRule == nil {
 				aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"),
@@ -267,7 +296,12 @@
 			cppFile := android.GenPathWithExt(ctx, "aidl", srcFile, "cpp")
 			depFile := android.GenPathWithExt(ctx, "aidl", srcFile, "cpp.d")
 			srcFiles[i] = cppFile
-			deps = append(deps, genAidl(ctx, aidlRule, srcFile, cppFile, depFile, buildFlags.aidlFlags)...)
+			aidlHeaders := genAidl(ctx, aidlRule, srcFile, cppFile, depFile, buildFlags.aidlFlags)
+			info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...)
+			// Use the generated headers as order only deps to ensure that they are up to date when
+			// needed.
+			// TODO: Reduce the size of the ninja file by using one order only dep for the whole rule
+			info.aidlOrderOnlyDeps = append(info.aidlOrderOnlyDeps, aidlHeaders...)
 		case ".rscript", ".fs":
 			cppFile := rsGeneratedCppFile(ctx, srcFile)
 			rsFiles = append(rsFiles, srcFiles[i])
@@ -279,7 +313,10 @@
 		case ".sysprop":
 			cppFile, headerFiles := genSysprop(ctx, srcFile)
 			srcFiles[i] = cppFile
-			deps = append(deps, headerFiles...)
+			info.syspropHeaders = append(info.syspropHeaders, headerFiles...)
+			// Use the generated headers as order only deps to ensure that they are up to date when
+			// needed.
+			info.syspropOrderOnlyDeps = append(info.syspropOrderOnlyDeps, headerFiles...)
 		}
 	}
 
@@ -291,9 +328,13 @@
 		yaccRule_.Build("yacc", "gen yacc")
 	}
 
+	deps = append(deps, info.protoOrderOnlyDeps...)
+	deps = append(deps, info.aidlOrderOnlyDeps...)
+	deps = append(deps, info.syspropOrderOnlyDeps...)
+
 	if len(rsFiles) > 0 {
 		deps = append(deps, rsGenerateCpp(ctx, rsFiles, buildFlags.rsFlags)...)
 	}
 
-	return srcFiles, deps
+	return srcFiles, deps, info
 }
diff --git a/cc/library.go b/cc/library.go
index 65533bc..0e6e107 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1313,9 +1313,8 @@
 			dir := android.PathForModuleGen(ctx, "aidl")
 			library.reexportDirs(dir)
 
-			// TODO: restrict to aidl deps
-			library.reexportDeps(library.baseCompiler.pathDeps...)
-			library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...)
+			library.reexportDeps(library.baseCompiler.aidlOrderOnlyDeps...)
+			library.addExportedGeneratedHeaders(library.baseCompiler.aidlHeaders...)
 		}
 	}
 
@@ -1329,9 +1328,8 @@
 			includes = append(includes, flags.proto.Dir)
 			library.reexportDirs(includes...)
 
-			// TODO: restrict to proto deps
-			library.reexportDeps(library.baseCompiler.pathDeps...)
-			library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...)
+			library.reexportDeps(library.baseCompiler.protoOrderOnlyDeps...)
+			library.addExportedGeneratedHeaders(library.baseCompiler.protoHeaders...)
 		}
 	}
 
@@ -1350,10 +1348,16 @@
 			}
 		}
 
+		// Make sure to only export headers which are within the include directory.
+		_, headers := android.FilterPathListPredicate(library.baseCompiler.syspropHeaders, func(path android.Path) bool {
+			_, isRel := android.MaybeRel(ctx, dir.String(), path.String())
+			return isRel
+		})
+
 		// Add sysprop-related directories to the exported directories of this library.
 		library.reexportDirs(dir)
-		library.reexportDeps(library.baseCompiler.pathDeps...)
-		library.addExportedGeneratedHeaders(library.baseCompiler.pathDeps...)
+		library.reexportDeps(library.baseCompiler.syspropOrderOnlyDeps...)
+		library.addExportedGeneratedHeaders(headers...)
 	}
 
 	// Add stub-related flags if this library is a stub library.
diff --git a/cc/library_headers.go b/cc/library_headers.go
index e5a5557..03450c6 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -129,13 +129,12 @@
 		Deps:     headerLibLabels,
 	}
 
-	props := bazel.NewBazelTargetModuleProperties(
-		module.Name(),
-		"cc_library_headers",
-		"//build/bazel/rules:cc_library_headers.bzl",
-	)
+	props := bazel.BazelTargetModuleProperties{
+		Rule_class:        "cc_library_headers",
+		Bzl_load_location: "//build/bazel/rules:cc_library_headers.bzl",
+	}
 
-	ctx.CreateBazelTargetModule(BazelCcLibraryHeadersFactory, props, attrs)
+	ctx.CreateBazelTargetModule(BazelCcLibraryHeadersFactory, module.Name(), props, attrs)
 }
 
 func (m *bazelCcLibraryHeaders) Name() string {
diff --git a/cc/object.go b/cc/object.go
index d92e110..3a7af97 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -150,13 +150,12 @@
 		Local_include_dirs: localIncludeDirs,
 	}
 
-	props := bazel.NewBazelTargetModuleProperties(
-		m.Name(),
-		"cc_object",
-		"//build/bazel/rules:cc_object.bzl",
-	)
+	props := bazel.BazelTargetModuleProperties{
+		Rule_class:        "cc_object",
+		Bzl_load_location: "//build/bazel/rules:cc_object.bzl",
+	}
 
-	ctx.CreateBazelTargetModule(BazelObjectFactory, props, attrs)
+	ctx.CreateBazelTargetModule(BazelObjectFactory, m.Name(), props, attrs)
 }
 
 func (object *objectLinker) appendLdflags(flags []string) {
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index d55204b..36a5e2a 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -84,6 +84,15 @@
 	BootFlags         string        // extra flags to pass to dex2oat for the boot image
 	Dex2oatImageXmx   string        // max heap size for dex2oat for the boot image
 	Dex2oatImageXms   string        // initial heap size for dex2oat for the boot image
+
+	// If true, downgrade the compiler filter of dexpreopt to "extract" when verify_uses_libraries
+	// check fails, instead of failing the build. This will disable any AOT-compilation.
+	//
+	// The intended use case for this flag is to have a smoother migration path for the Java
+	// modules that need to add <uses-library> information in their build files. The flag allows to
+	// quickly silence build errors. This flag should be used with caution and only as a temporary
+	// measure, as it masks real errors and affects performance.
+	RelaxUsesLibraryCheck bool
 }
 
 // GlobalSoongConfig contains the global config that is generated from Soong,
@@ -113,9 +122,10 @@
 	ProfileIsTextListing bool
 	ProfileBootListing   android.OptionalPath
 
-	EnforceUsesLibraries bool
-	ProvidesUsesLibrary  string // the name of the <uses-library> (usually the same as its module)
-	ClassLoaderContexts  ClassLoaderContextMap
+	EnforceUsesLibraries           bool         // turn on build-time verify_uses_libraries check
+	EnforceUsesLibrariesStatusFile android.Path // a file with verify_uses_libraries errors (if any)
+	ProvidesUsesLibrary            string       // library name (usually the same as module name)
+	ClassLoaderContexts            ClassLoaderContextMap
 
 	Archs                   []android.ArchType
 	DexPreoptImages         []android.Path
@@ -258,14 +268,15 @@
 
 		// Copies of entries in ModuleConfig that are not constructable without extra parameters.  They will be
 		// used to construct the real value manually below.
-		BuildPath                   string
-		DexPath                     string
-		ManifestPath                string
-		ProfileClassListing         string
-		ClassLoaderContexts         jsonClassLoaderContextMap
-		DexPreoptImages             []string
-		DexPreoptImageLocations     []string
-		PreoptBootClassPathDexFiles []string
+		BuildPath                      string
+		DexPath                        string
+		ManifestPath                   string
+		ProfileClassListing            string
+		EnforceUsesLibrariesStatusFile string
+		ClassLoaderContexts            jsonClassLoaderContextMap
+		DexPreoptImages                []string
+		DexPreoptImageLocations        []string
+		PreoptBootClassPathDexFiles    []string
 	}
 
 	config := ModuleJSONConfig{}
@@ -280,6 +291,7 @@
 	config.ModuleConfig.DexPath = constructPath(ctx, config.DexPath)
 	config.ModuleConfig.ManifestPath = constructPath(ctx, config.ManifestPath)
 	config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing))
+	config.ModuleConfig.EnforceUsesLibrariesStatusFile = constructPath(ctx, config.EnforceUsesLibrariesStatusFile)
 	config.ModuleConfig.ClassLoaderContexts = fromJsonClassLoaderContext(ctx, config.ClassLoaderContexts)
 	config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
 	config.ModuleConfig.DexPreoptImageLocations = config.DexPreoptImageLocations
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index b0a684e..6e0fe01 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -279,11 +279,12 @@
 
 		// Generate command that saves host and target class loader context in shell variables.
 		clc, paths := ComputeClassLoaderContext(module.ClassLoaderContexts)
-		cmd := rule.Command().
-			Text(`eval "$(`).Tool(globalSoong.ConstructContext).
+		rule.Command().
+			Text("if ! test -s ").Input(module.EnforceUsesLibrariesStatusFile).
+			Text(` ; then eval "$(`).Tool(globalSoong.ConstructContext).
 			Text(` --target-sdk-version ${target_sdk_version}`).
-			Text(clc).Implicits(paths)
-		cmd.Text(`)"`)
+			Text(clc).Implicits(paths).
+			Text(`)" ; fi`)
 
 	} else {
 		// Other libraries or APKs for which the exact <uses-library> list is unknown.
@@ -366,7 +367,16 @@
 		} else {
 			compilerFilter = "quicken"
 		}
-		cmd.FlagWithArg("--compiler-filter=", compilerFilter)
+		if module.EnforceUsesLibraries {
+			// If the verify_uses_libraries check failed (in this case status file contains a
+			// non-empty error message), then use "extract" compiler filter to avoid compiling any
+			// code (it would be rejected on device because of a class loader context mismatch).
+			cmd.Text("--compiler-filter=$(if test -s ").
+				Input(module.EnforceUsesLibrariesStatusFile).
+				Text(" ; then echo extract ; else echo " + compilerFilter + " ; fi)")
+		} else {
+			cmd.FlagWithArg("--compiler-filter=", compilerFilter)
+		}
 	}
 
 	if generateDM {
@@ -542,6 +552,12 @@
 	}
 }
 
+// Returns path to a file containing the reult of verify_uses_libraries check (empty if the check
+// has succeeded, or an error message if it failed).
+func UsesLibrariesStatusFile(ctx android.ModuleContext) android.WritablePath {
+	return android.PathForModuleOut(ctx, "enforce_uses_libraries.status")
+}
+
 func contains(l []string, s string) bool {
 	for _, e := range l {
 		if e == s {
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index af73d0c..12df36b 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -43,6 +43,7 @@
 		PreoptFlags:                     nil,
 		ProfileClassListing:             android.OptionalPath{},
 		ProfileIsTextListing:            false,
+		EnforceUsesLibrariesStatusFile:  android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)),
 		EnforceUsesLibraries:            false,
 		ClassLoaderContexts:             nil,
 		Archs:                           []android.ArchType{android.Arm},
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 9fa6c48..c743fc3 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -853,10 +853,12 @@
 		Tools: tools,
 	}
 
-	props := bazel.NewBazelTargetModuleProperties(m.Name(), "genrule", "")
+	props := bazel.BazelTargetModuleProperties{
+		Rule_class: "genrule",
+	}
 
 	// Create the BazelTargetModule.
-	ctx.CreateBazelTargetModule(BazelGenruleFactory, props, attrs)
+	ctx.CreateBazelTargetModule(BazelGenruleFactory, m.Name(), props, attrs)
 }
 
 func (m *bazelGenrule) Name() string {
diff --git a/java/androidmk.go b/java/androidmk.go
index e7261f8..9bdb70c 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -287,9 +287,16 @@
 			},
 		}}
 	} else {
+		outputFile := binary.wrapperFile
+		// Have Make installation trigger Soong installation by using Soong's install path as
+		// the output file.
+		if binary.Host() {
+			outputFile = binary.binaryFile
+		}
+
 		return []android.AndroidMkEntries{android.AndroidMkEntries{
 			Class:      "EXECUTABLES",
-			OutputFile: android.OptionalPathForPath(binary.wrapperFile),
+			OutputFile: android.OptionalPathForPath(outputFile),
 			ExtraEntries: []android.AndroidMkExtraEntriesFunc{
 				func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
 					entries.SetBool("LOCAL_STRIP_MODULE", false)
diff --git a/java/app.go b/java/app.go
index ce89e9b..5181207 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1260,13 +1260,19 @@
 // in the uses_libs and optional_uses_libs properties.  It returns the path to a copy of the manifest.
 func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
 	outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
+	statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
 
 	rule := android.NewRuleBuilder(pctx, ctx)
 	cmd := rule.Command().BuiltTool("manifest_check").
 		Flag("--enforce-uses-libraries").
 		Input(manifest).
+		FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
 		FlagWithOutput("-o ", outputFile)
 
+	if dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck {
+		cmd.Flag("--enforce-uses-libraries-relax")
+	}
+
 	for _, lib := range u.usesLibraryProperties.Uses_libs {
 		cmd.FlagWithArg("--uses-library ", lib)
 	}
@@ -1284,6 +1290,7 @@
 // in the uses_libs and optional_uses_libs properties.  It returns the path to a copy of the APK.
 func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
 	outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
+	statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
 
 	rule := android.NewRuleBuilder(pctx, ctx)
 	aapt := ctx.Config().HostToolPath(ctx, "aapt")
@@ -1291,7 +1298,8 @@
 		Textf("aapt_binary=%s", aapt.String()).Implicit(aapt).
 		Textf(`uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Uses_libs, " ")).
 		Textf(`optional_uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Optional_uses_libs, " ")).
-		Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk)
+		Textf(`relax_check="%b"`, dexpreopt.GetGlobalConfig(ctx).RelaxUsesLibraryCheck).
+		Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk).Output(statusFile)
 	rule.Command().Text("cp -f").Input(apk).Output(outputFile)
 
 	rule.Build("verify_uses_libraries", "verify <uses-library>")
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 29c73c1..a2961c2 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -35,6 +35,7 @@
 	isPresignedPrebuilt bool
 
 	manifestFile        android.Path
+	statusFile          android.WritablePath
 	enforceUsesLibs     bool
 	classLoaderContexts dexpreopt.ClassLoaderContextMap
 
@@ -226,9 +227,10 @@
 		ProfileIsTextListing: profileIsTextListing,
 		ProfileBootListing:   profileBootListing,
 
-		EnforceUsesLibraries: d.enforceUsesLibs,
-		ProvidesUsesLibrary:  providesUsesLib,
-		ClassLoaderContexts:  d.classLoaderContexts,
+		EnforceUsesLibrariesStatusFile: dexpreopt.UsesLibrariesStatusFile(ctx),
+		EnforceUsesLibraries:           d.enforceUsesLibs,
+		ProvidesUsesLibrary:            providesUsesLib,
+		ClassLoaderContexts:            d.classLoaderContexts,
 
 		Archs:                   archs,
 		DexPreoptImages:         images,
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index f8e41c4..da2c48f 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -15,8 +15,6 @@
 package java
 
 import (
-	"strings"
-
 	"github.com/google/blueprint"
 
 	"android/soong/android"
@@ -29,8 +27,8 @@
 
 type hiddenAPI struct {
 	// The name of the module as it would be used in the boot jars configuration, e.g. without any
-	// prebuilt_ prefix (if it is a prebuilt), without any "-hiddenapi" suffix if it just provides
-	// annotations and without any ".impl" suffix if it is a java_sdk_library implementation library.
+	// prebuilt_ prefix (if it is a prebuilt) and without any ".impl" suffix if it is a
+	// java_sdk_library implementation library.
 	configurationName string
 
 	// True if the module containing this structure contributes to the hiddenapi information or has
@@ -49,11 +47,6 @@
 	// annotation information.
 	primary bool
 
-	// True if the module only contains additional annotations and so does not require hiddenapi
-	// information to be encoded in its dex file and should not be used to generate the
-	// hiddenAPISingletonPathsStruct.stubFlags file.
-	annotationsOnly bool
-
 	// The path to the dex jar that is in the boot class path. If this is nil then the associated
 	// module is not a boot jar, but could be one of the <x>-hiddenapi modules that provide additional
 	// annotations for the <x> boot dex jar but which do not actually provide a boot dex jar
@@ -119,48 +112,40 @@
 var _ hiddenAPIIntf = (*hiddenAPI)(nil)
 
 // Initialize the hiddenapi structure
-func (h *hiddenAPI) initHiddenAPI(ctx android.BaseModuleContext, name string) {
+func (h *hiddenAPI) initHiddenAPI(ctx android.BaseModuleContext, configurationName string) {
 	// If hiddenapi processing is disabled treat this as inactive.
 	if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
 		return
 	}
 
-	// Modules whose names are of the format <x>-hiddenapi provide hiddenapi information for the boot
-	// jar module <x>. Otherwise, the module provides information for itself. Either way extract the
-	// configurationName of the boot jar module.
-	configurationName := strings.TrimSuffix(name, "-hiddenapi")
 	h.configurationName = configurationName
 
 	// It is important that hiddenapi information is only gathered for/from modules that are actually
 	// on the boot jars list because the runtime only enforces access to the hidden API for the
 	// bootclassloader. If information is gathered for modules not on the list then that will cause
 	// failures in the CtsHiddenApiBlocklist... tests.
-	h.active = inList(configurationName, ctx.Config().BootJars())
+	module := ctx.Module()
+	h.active = isModuleInBootClassPath(ctx, module)
 	if !h.active {
 		// The rest of the properties will be ignored if active is false.
 		return
 	}
 
-	// If this module has a suffix of -hiddenapi then it only provides additional annotation
-	// information for a module on the boot jars list.
-	h.annotationsOnly = strings.HasSuffix(name, "-hiddenapi")
-
 	// Determine whether this module is the primary module or not.
 	primary := true
 
 	// A prebuilt module is only primary if it is preferred and conversely a source module is only
 	// primary if it has not been replaced by a prebuilt module.
-	module := ctx.Module()
 	if pi, ok := module.(android.PrebuiltInterface); ok {
 		if p := pi.Prebuilt(); p != nil {
 			primary = p.UsePrebuilt()
 		}
 	} else {
-		// The only module that will pass a different name to its module name to this method is the
-		// implementation library of a java_sdk_library. It has a configuration name of <x> the same
-		// as its parent java_sdk_library but a module name of <x>.impl. It is not the primary module,
-		// the java_sdk_library with the name of <x> is.
-		primary = name == ctx.ModuleName()
+		// The only module that will pass a different configurationName to its module name to this
+		// method is the implementation library of a java_sdk_library. It has a configuration name of
+		// <x> the same as its parent java_sdk_library but a module name of <x>.impl. It is not the
+		// primary module, the java_sdk_library with the name of <x> is.
+		primary = configurationName == ctx.ModuleName()
 
 		// A source module that has been replaced by a prebuilt can never be the primary module.
 		primary = primary && !module.IsReplacedByPrebuilt()
@@ -168,6 +153,15 @@
 	h.primary = primary
 }
 
+func isModuleInBootClassPath(ctx android.BaseModuleContext, module android.Module) bool {
+	// Get the configured non-updatable and updatable boot jars.
+	nonUpdatableBootJars := ctx.Config().NonUpdatableBootJars()
+	updatableBootJars := ctx.Config().UpdatableBootJars()
+	active := isModuleInConfiguredList(ctx, module, nonUpdatableBootJars) ||
+		isModuleInConfiguredList(ctx, module, updatableBootJars)
+	return active
+}
+
 // hiddenAPIExtractAndEncode is called by any module that could contribute to the hiddenapi
 // processing.
 //
@@ -191,15 +185,13 @@
 
 	h.hiddenAPIExtractInformation(ctx, dexJar, implementationJar)
 
-	if !h.annotationsOnly {
-		hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", h.configurationName+".jar").OutputPath
+	hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", h.configurationName+".jar").OutputPath
 
-		// Create a copy of the dex jar which has been encoded with hiddenapi flags.
-		hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
+	// Create a copy of the dex jar which has been encoded with hiddenapi flags.
+	hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
 
-		// Use the encoded dex jar from here onwards.
-		dexJar = hiddenAPIJar
-	}
+	// Use the encoded dex jar from here onwards.
+	dexJar = hiddenAPIJar
 
 	return dexJar
 }
@@ -262,6 +254,7 @@
 	rule.Command().
 		BuiltTool("merge_csv").
 		Flag("--zip_input").
+		Flag("--key_field signature").
 		FlagWithOutput("--output=", indexCSV).
 		Inputs(classesJars)
 	rule.Build("merged-hiddenapi-index", "Merged Hidden API index")
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 6341a34..82e8b3f 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -217,10 +217,6 @@
 
 	var bootDexJars android.Paths
 
-	// Get the configured non-updatable and updatable boot jars.
-	nonUpdatableBootJars := ctx.Config().NonUpdatableBootJars()
-	updatableBootJars := ctx.Config().UpdatableBootJars()
-
 	ctx.VisitAllModules(func(module android.Module) {
 		// Collect dex jar paths for the modules listed above.
 		if j, ok := module.(UsesLibraryDependency); ok {
@@ -235,11 +231,6 @@
 		// Collect dex jar paths for modules that had hiddenapi encode called on them.
 		if h, ok := module.(hiddenAPIIntf); ok {
 			if jar := h.bootDexJar(); jar != nil {
-				if !isModuleInConfiguredList(ctx, module, nonUpdatableBootJars) &&
-					!isModuleInConfiguredList(ctx, module, updatableBootJars) {
-					return
-				}
-
 				bootDexJars = append(bootDexJars, jar)
 			}
 		}
@@ -291,8 +282,8 @@
 // there too.
 //
 // TODO(b/179354495): Avoid having to perform this type of check or if necessary dedup it.
-func isModuleInConfiguredList(ctx android.SingletonContext, module android.Module, configuredBootJars android.ConfiguredJarList) bool {
-	name := ctx.ModuleName(module)
+func isModuleInConfiguredList(ctx android.BaseModuleContext, module android.Module, configuredBootJars android.ConfiguredJarList) bool {
+	name := ctx.OtherModuleName(module)
 
 	// Strip a prebuilt_ prefix so that this can match a prebuilt module that has not been renamed.
 	name = android.RemoveOptionalPrebuiltPrefix(name)
@@ -305,11 +296,11 @@
 
 	// It is an error if the module is not an ApexModule.
 	if _, ok := module.(android.ApexModule); !ok {
-		ctx.Errorf("module %q configured in boot jars does not support being added to an apex", module)
+		ctx.ModuleErrorf("is configured in boot jars but does not support being added to an apex")
 		return false
 	}
 
-	apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+	apexInfo := ctx.OtherModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
 
 	// Now match the apex part of the boot image configuration.
 	requiredApex := configuredBootJars.Apex(index)
@@ -433,6 +424,7 @@
 
 	rule.Command().
 		BuiltTool("merge_csv").
+		Flag("--key_field signature").
 		FlagWithOutput("--output=", outputPath).
 		Inputs(metadataCSV)
 
@@ -544,6 +536,7 @@
 	rule := android.NewRuleBuilder(pctx, ctx)
 	rule.Command().
 		BuiltTool("merge_csv").
+		Flag("--key_field signature").
 		FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
 		FlagWithOutput("--output=", hiddenAPISingletonPaths(ctx).index).
 		Inputs(indexes)
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 4670d03..c0f0e38 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -89,12 +89,6 @@
 		}
 
 		java_library {
-			name: "foo-hiddenapi",
-			srcs: ["a.java"],
-			compile_dex: true,
-		}
-
-		java_library {
 			name: "foo-hiddenapi-annotations",
 			srcs: ["a.java"],
 			compile_dex: true,
@@ -118,7 +112,6 @@
 	indexRule := hiddenAPIIndex.Rule("singleton-merged-hiddenapi-index")
 	CheckHiddenAPIRuleInputs(t, `
 .intermediates/bar/android_common/hiddenapi/index.csv
-.intermediates/foo-hiddenapi/android_common/hiddenapi/index.csv
 .intermediates/foo/android_common/hiddenapi/index.csv
 `,
 		indexRule)
diff --git a/java/java.go b/java/java.go
index dbfad02..78cd362 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1038,7 +1038,7 @@
 	case javaPlatform:
 		return "private API"
 	default:
-		panic(fmt.Errorf("unrecognized linktype: %v", lt))
+		panic(fmt.Errorf("unrecognized linktype: %d", lt))
 	}
 }
 
diff --git a/rust/builder.go b/rust/builder.go
index 547d705..6326124 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -230,6 +230,8 @@
 		envVars = append(envVars, "OUT_DIR="+filepath.Join(outDirPrefix, moduleGenDir.String()))
 	}
 
+	envVars = append(envVars, "ANDROID_RUST_VERSION="+config.RustDefaultVersion)
+
 	if flags.Clippy {
 		clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
 		ctx.Build(pctx, android.BuildParams{
diff --git a/scripts/hiddenapi/merge_csv.py b/scripts/hiddenapi/merge_csv.py
index 5ad61b2..b047aab 100755
--- a/scripts/hiddenapi/merge_csv.py
+++ b/scripts/hiddenapi/merge_csv.py
@@ -20,6 +20,9 @@
 import argparse
 import csv
 import io
+import heapq
+import itertools
+import operator
 
 from zipfile import ZipFile
 
@@ -28,6 +31,10 @@
                                           'if missing determines the header from input files.')
 args_parser.add_argument('--zip_input', help='Treat files as ZIP archives containing CSV files to merge.',
                          action="store_true")
+args_parser.add_argument('--key_field', help='The name of the field by which the rows should be sorted. '
+                                             'Must be in the field names. '
+                                             'Will be the first field in the output. '
+                                             'All input files must be sorted by that field.')
 args_parser.add_argument('--output', help='Output file for merged CSV.',
                          default='-', type=argparse.FileType('w'))
 args_parser.add_argument('files', nargs=argparse.REMAINDER)
@@ -57,10 +64,29 @@
         headers = headers.union(reader.fieldnames)
     fieldnames = sorted(headers)
 
-# Concatenate all files to output:
+# By default chain the csv readers together so that the resulting output is
+# the concatenation of the rows from each of them:
+all_rows = itertools.chain.from_iterable(csv_readers)
+
+if len(csv_readers) > 0:
+    keyField = args.key_field
+    if keyField:
+        assert keyField in fieldnames, (
+            "--key_field {} not found, must be one of {}\n").format(
+            keyField, ",".join(fieldnames))
+        # Make the key field the first field in the output
+        keyFieldIndex = fieldnames.index(args.key_field)
+        fieldnames.insert(0, fieldnames.pop(keyFieldIndex))
+        # Create an iterable that performs a lazy merge sort on the csv readers
+        # sorting the rows by the key field.
+        all_rows = heapq.merge(*csv_readers, key=operator.itemgetter(keyField))
+
+# Write all rows from the input files to the output:
 writer = csv.DictWriter(args.output, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL,
                         dialect='unix', fieldnames=fieldnames)
 writer.writeheader()
-for reader in csv_readers:
-    for row in reader:
-        writer.writerow(row)
+
+# Read all the rows from the input and write them to the output in the correct
+# order:
+for row in all_rows:
+  writer.writerow(row)
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index 9122da1..0eb1b76 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -48,6 +48,13 @@
                       dest='enforce_uses_libraries',
                       action='store_true',
                       help='check the uses-library entries known to the build system against the manifest')
+  parser.add_argument('--enforce-uses-libraries-relax',
+                      dest='enforce_uses_libraries_relax',
+                      action='store_true',
+                      help='do not fail immediately, just save the error message to file')
+  parser.add_argument('--enforce-uses-libraries-status',
+                      dest='enforce_uses_libraries_status',
+                      help='output file to store check status (error message)')
   parser.add_argument('--extract-target-sdk-version',
                       dest='extract_target_sdk_version',
                       action='store_true',
@@ -57,7 +64,7 @@
   return parser.parse_args()
 
 
-def enforce_uses_libraries(doc, uses_libraries, optional_uses_libraries):
+def enforce_uses_libraries(doc, uses_libraries, optional_uses_libraries, relax):
   """Verify that the <uses-library> tags in the manifest match those provided by the build system.
 
   Args:
@@ -80,10 +87,10 @@
       raise ManifestMismatchError('no <application> tag found')
     return
 
-  verify_uses_library(application, uses_libraries, optional_uses_libraries)
+  return verify_uses_library(application, uses_libraries, optional_uses_libraries, relax)
 
 
-def verify_uses_library(application, uses_libraries, optional_uses_libraries):
+def verify_uses_library(application, uses_libraries, optional_uses_libraries, relax):
   """Verify that the uses-library values known to the build system match the manifest.
 
   Args:
@@ -112,8 +119,12 @@
                (', '.join(optional_uses_libraries), ', '.join(manifest_optional_uses_libraries)))
 
   if err:
-    raise ManifestMismatchError('\n'.join(err))
+    errmsg = '\n'.join(err)
+    if not relax:
+      raise ManifestMismatchError(errmsg)
+    return errmsg
 
+  return None
 
 def parse_uses_library(application):
   """Extract uses-library tags from the manifest.
@@ -195,9 +206,19 @@
     doc = minidom.parse(args.input)
 
     if args.enforce_uses_libraries:
-      enforce_uses_libraries(doc,
-                             args.uses_libraries,
-                             args.optional_uses_libraries)
+      # Check if the <uses-library> lists in the build system agree with those
+      # in the manifest. Raise an exception on mismatch, unless the script was
+      # passed a special parameter to suppress exceptions.
+      errmsg = enforce_uses_libraries(doc, args.uses_libraries,
+        args.optional_uses_libraries, args.enforce_uses_libraries_relax)
+
+      # Create a status file that is empty on success, or contains an error
+      # message on failure. When exceptions are suppressed, dexpreopt command
+      # command will check file size to determine if the check has failed.
+      if args.enforce_uses_libraries_status:
+        with open(args.enforce_uses_libraries_status, 'w') as f:
+          if not errmsg == None:
+            f.write("%s\n" % errmsg)
 
     if args.extract_target_sdk_version:
       print(extract_target_sdk_version(doc))
diff --git a/scripts/manifest_check_test.py b/scripts/manifest_check_test.py
index 7baad5d..56c2d9e 100755
--- a/scripts/manifest_check_test.py
+++ b/scripts/manifest_check_test.py
@@ -39,7 +39,9 @@
   def run_test(self, input_manifest, uses_libraries=None, optional_uses_libraries=None):
     doc = minidom.parseString(input_manifest)
     try:
-      manifest_check.enforce_uses_libraries(doc, uses_libraries, optional_uses_libraries)
+      relax = False
+      manifest_check.enforce_uses_libraries(doc, uses_libraries,
+        optional_uses_libraries, relax)
       return True
     except manifest_check.ManifestMismatchError:
       return False
diff --git a/scripts/strip.sh b/scripts/strip.sh
index 40f0184..5b7a6da 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -89,7 +89,7 @@
         "${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo"
         "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo"
         "${CROSS_COMPILE}objcopy" --rename-section saved_debug_frame=.debug_frame "${outfile}.mini_debuginfo"
-        "${XZ}" "${outfile}.mini_debuginfo"
+        "${XZ}" --block-size=64k --threads=0 "${outfile}.mini_debuginfo"
 
         "${CLANG_BIN}/llvm-objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
         rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index b1eebe9..6fd6b09 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -22,14 +22,14 @@
 )
 
 var ccTestFs = map[string][]byte{
-	"Test.cpp":                      nil,
-	"include/Test.h":                nil,
-	"include-android/AndroidTest.h": nil,
-	"include-host/HostTest.h":       nil,
-	"arm64/include/Arm64Test.h":     nil,
-	"libfoo.so":                     nil,
-	"aidl/foo/bar/Test.aidl":        nil,
-	"some/where/stubslib.map.txt":   nil,
+	"Test.cpp":                        nil,
+	"myinclude/Test.h":                nil,
+	"myinclude-android/AndroidTest.h": nil,
+	"myinclude-host/HostTest.h":       nil,
+	"arm64/include/Arm64Test.h":       nil,
+	"libfoo.so":                       nil,
+	"aidl/foo/bar/Test.aidl":          nil,
+	"some/where/stubslib.map.txt":     nil,
 }
 
 func testSdkWithCc(t *testing.T, bp string) *testSdkResult {
@@ -102,16 +102,15 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_sdkmember@current",
-    sdk_member_name: "sdkmember",
+    name: "sdkmember",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
-    installable: false,
     stl: "none",
     compile_multilib: "64",
     target: {
@@ -127,13 +126,17 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "sdkmember",
-    prefer: false,
+    name: "mysdk_sdkmember@current",
+    sdk_member_name: "sdkmember",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
+    installable: false,
     stl: "none",
     compile_multilib: "64",
     target: {
@@ -348,12 +351,12 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_object {
-    name: "mysdk_crtobj@current",
-    sdk_member_name: "crtobj",
+    name: "crtobj",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     stl: "none",
@@ -370,10 +373,14 @@
         },
     },
 }
+`),
+		// Make sure that the generated sdk_snapshot uses the native_objects property.
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_object {
-    name: "crtobj",
-    prefer: false,
+    name: "mysdk_crtobj@current",
+    sdk_member_name: "crtobj",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     stl: "none",
@@ -416,7 +423,7 @@
 			srcs: [
 				"Test.cpp",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			stl: "none",
 		}
 
@@ -425,14 +432,14 @@
 			srcs: [
 				"Test.cpp",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			stl: "none",
 		}
 	`)
 
 	result.CheckSnapshot("mysdk", "",
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib1/android_arm64_armv8-a_shared/mynativelib1.so -> arm64/lib/mynativelib1.so
 .intermediates/mynativelib1/android_arm_armv7-a-neon_shared/mynativelib1.so -> arm/lib/mynativelib1.so
 .intermediates/mynativelib2/android_arm64_armv8-a_shared/mynativelib2.so -> arm64/lib/mynativelib2.so
@@ -441,6 +448,81 @@
 	)
 }
 
+func TestSnapshotWithCcExportGeneratedHeaders(t *testing.T) {
+	result := testSdkWithCc(t, `
+		sdk {
+			name: "mysdk",
+			native_shared_libs: ["mynativelib"],
+		}
+
+		cc_library_shared {
+			name: "mynativelib",
+			srcs: [
+				"Test.cpp",
+			],
+			generated_headers: [
+				"generated_foo",
+			],
+			export_generated_headers: [
+				"generated_foo",
+			],
+			export_include_dirs: ["myinclude"],
+			stl: "none",
+		}
+
+		genrule {
+			name: "generated_foo",
+			cmd: "generate-foo",
+			out: [
+				"generated_foo/protos/foo/bar.h",
+			],
+			export_include_dirs: [
+				".",
+				"protos",
+			],
+		}
+	`)
+
+	result.CheckSnapshot("mysdk", "",
+		checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+    name: "mynativelib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    stl: "none",
+    compile_multilib: "both",
+    export_include_dirs: ["include/myinclude"],
+    arch: {
+        arm64: {
+            srcs: ["arm64/lib/mynativelib.so"],
+            export_include_dirs: [
+                "arm64/include_gen/mynativelib",
+                "arm64/include_gen/mynativelib",
+            ],
+        },
+        arm: {
+            srcs: ["arm/lib/mynativelib.so"],
+            export_include_dirs: [
+                "arm/include_gen/mynativelib",
+                "arm/include_gen/mynativelib",
+            ],
+        },
+    },
+}
+`),
+		checkAllCopyRules(`
+myinclude/Test.h -> include/myinclude/Test.h
+.intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so
+.intermediates/generated_foo/gen/generated_foo/protos/foo/bar.h -> arm64/include_gen/mynativelib/generated_foo/protos/foo/bar.h
+.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so
+.intermediates/generated_foo/gen/generated_foo/protos/foo/bar.h -> arm/include_gen/mynativelib/generated_foo/protos/foo/bar.h
+`),
+	)
+}
+
 // Verify that when the shared library has some common and some arch specific
 // properties that the generated snapshot is optimized properly. Substruct
 // handling is tested with the sanitize clauses (but note there's a lot of
@@ -458,7 +540,7 @@
 				"Test.cpp",
 				"aidl/foo/bar/Test.aidl",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			sanitize: {
 				fuzzer: false,
 				integer_overflow: true,
@@ -477,49 +559,17 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mynativelib@current",
-    sdk_member_name: "mynativelib",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    stl: "none",
-    compile_multilib: "both",
-    export_include_dirs: ["include/include"],
-    sanitize: {
-        fuzzer: false,
-        diag: {
-            undefined: false,
-        },
-    },
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/mynativelib.so"],
-            export_system_include_dirs: ["arm64/include/arm64/include"],
-            sanitize: {
-                integer_overflow: false,
-            },
-        },
-        arm: {
-            srcs: ["arm/lib/mynativelib.so"],
-            sanitize: {
-                integer_overflow: true,
-            },
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     sanitize: {
         fuzzer: false,
         diag: {
@@ -542,15 +592,9 @@
         },
     },
 }
-
-sdk_snapshot {
-    name: "mysdk@current",
-    visibility: ["//visibility:public"],
-    native_shared_libs: ["mysdk_mynativelib@current"],
-}
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so
 arm64/include/Arm64Test.h -> arm64/include/arm64/include/Arm64Test.h
 .intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so`),
@@ -574,15 +618,14 @@
 	`)
 
 	result.CheckSnapshot("mymodule_exports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_binary {
-    name: "mymodule_exports_mynativebinary@current",
-    sdk_member_name: "mynativebinary",
+    name: "mynativebinary",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
-    installable: false,
     compile_multilib: "both",
     arch: {
         arm64: {
@@ -593,12 +636,17 @@
         },
     },
 }
+`),
+		// Make sure that the generated sdk_snapshot uses the native_binaries property.
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_binary {
-    name: "mynativebinary",
-    prefer: false,
+    name: "mymodule_exports_mynativebinary@current",
+    sdk_member_name: "mynativebinary",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
+    installable: false,
     compile_multilib: "both",
     arch: {
         arm64: {
@@ -655,17 +703,16 @@
 	`)
 
 	result.CheckSnapshot("myexports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_binary {
-    name: "myexports_mynativebinary@current",
-    sdk_member_name: "mynativebinary",
+    name: "mynativebinary",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
-    installable: false,
     stl: "none",
     target: {
         host: {
@@ -691,14 +738,18 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_binary {
-    name: "mynativebinary",
-    prefer: false,
+    name: "myexports_mynativebinary@current",
+    sdk_member_name: "mynativebinary",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
+    installable: false,
     stl: "none",
     target: {
         host: {
@@ -805,7 +856,50 @@
 	result := runTests(t, ctx, config)
 
 	result.CheckSnapshot("myexports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_binary {
+    name: "mynativebinary",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    device_supported: false,
+    host_supported: true,
+    stl: "none",
+    compile_multilib: "64",
+    target: {
+        host: {
+            enabled: false,
+        },
+        linux_bionic_x86_64: {
+            enabled: true,
+            srcs: ["x86_64/bin/mynativebinary"],
+        },
+    },
+}
+
+cc_prebuilt_library_shared {
+    name: "mynativelib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    device_supported: false,
+    host_supported: true,
+    stl: "none",
+    compile_multilib: "64",
+    target: {
+        host: {
+            enabled: false,
+        },
+        linux_bionic_x86_64: {
+            enabled: true,
+            srcs: ["x86_64/lib/mynativelib.so"],
+        },
+    },
+}
+`),
+		checkVersionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_binary {
@@ -829,26 +923,6 @@
     },
 }
 
-cc_prebuilt_binary {
-    name: "mynativebinary",
-    prefer: false,
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    device_supported: false,
-    host_supported: true,
-    stl: "none",
-    compile_multilib: "64",
-    target: {
-        host: {
-            enabled: false,
-        },
-        linux_bionic_x86_64: {
-            enabled: true,
-            srcs: ["x86_64/bin/mynativebinary"],
-        },
-    },
-}
-
 cc_prebuilt_library_shared {
     name: "myexports_mynativelib@current",
     sdk_member_name: "mynativelib",
@@ -870,26 +944,6 @@
     },
 }
 
-cc_prebuilt_library_shared {
-    name: "mynativelib",
-    prefer: false,
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    device_supported: false,
-    host_supported: true,
-    stl: "none",
-    compile_multilib: "64",
-    target: {
-        host: {
-            enabled: false,
-        },
-        linux_bionic_x86_64: {
-            enabled: true,
-            srcs: ["x86_64/lib/mynativelib.so"],
-        },
-    },
-}
-
 module_exports_snapshot {
     name: "myexports@current",
     visibility: ["//visibility:public"],
@@ -940,17 +994,16 @@
 	`)
 
 	result.CheckSnapshot("mymodule_exports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_binary {
-    name: "mymodule_exports_linker@current",
-    sdk_member_name: "linker",
+    name: "linker",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
-    installable: false,
     stl: "none",
     compile_multilib: "both",
     static_executable: true,
@@ -969,14 +1022,18 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_binary {
-    name: "linker",
-    prefer: false,
+    name: "mymodule_exports_linker@current",
+    sdk_member_name: "linker",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
+    installable: false,
     stl: "none",
     compile_multilib: "both",
     static_executable: true,
@@ -1036,7 +1093,7 @@
 				"aidl/foo/bar/Test.aidl",
 			],
 			apex_available: ["apex1", "apex2"],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			aidl: {
 				export_aidl_headers: true,
 			},
@@ -1045,34 +1102,10 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mynativelib@current",
-    sdk_member_name: "mynativelib",
-    visibility: ["//visibility:public"],
-    apex_available: [
-        "apex1",
-        "apex2",
-    ],
-    installable: false,
-    stl: "none",
-    compile_multilib: "both",
-    export_include_dirs: ["include/include"],
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/mynativelib.so"],
-            export_include_dirs: ["arm64/include_gen/mynativelib"],
-        },
-        arm: {
-            srcs: ["arm/lib/mynativelib.so"],
-            export_include_dirs: ["arm/include_gen/mynativelib"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -1082,7 +1115,7 @@
     ],
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     arch: {
         arm64: {
             srcs: ["arm64/lib/mynativelib.so"],
@@ -1094,15 +1127,9 @@
         },
     },
 }
-
-sdk_snapshot {
-    name: "mysdk@current",
-    visibility: ["//visibility:public"],
-    native_shared_libs: ["mysdk_mynativelib@current"],
-}
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so
 .intermediates/mynativelib/android_arm64_armv8-a_shared/gen/aidl/aidl/foo/bar/Test.h -> arm64/include_gen/mynativelib/aidl/foo/bar/Test.h
 .intermediates/mynativelib/android_arm64_armv8-a_shared/gen/aidl/aidl/foo/bar/BnTest.h -> arm64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
@@ -1176,32 +1203,10 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mynativelib@current",
-    sdk_member_name: "mynativelib",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    stl: "none",
-    compile_multilib: "both",
-    shared_libs: [
-        "mysdk_myothernativelib@current",
-        "libc",
-    ],
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/mynativelib.so"],
-        },
-        arm: {
-            srcs: ["arm/lib/mynativelib.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -1223,25 +1228,6 @@
 }
 
 cc_prebuilt_library_shared {
-    name: "mysdk_myothernativelib@current",
-    sdk_member_name: "myothernativelib",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    stl: "none",
-    compile_multilib: "both",
-    system_shared_libs: ["libm"],
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/myothernativelib.so"],
-        },
-        arm: {
-            srcs: ["arm/lib/myothernativelib.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "myothernativelib",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -1260,24 +1246,6 @@
 }
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mysystemnativelib@current",
-    sdk_member_name: "mysystemnativelib",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    stl: "none",
-    compile_multilib: "both",
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/mysystemnativelib.so"],
-        },
-        arm: {
-            srcs: ["arm/lib/mysystemnativelib.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "mysystemnativelib",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -1293,16 +1261,6 @@
         },
     },
 }
-
-sdk_snapshot {
-    name: "mysdk@current",
-    visibility: ["//visibility:public"],
-    native_shared_libs: [
-        "mysdk_mynativelib@current",
-        "mysdk_myothernativelib@current",
-        "mysdk_mysystemnativelib@current",
-    ],
-}
 `),
 		checkAllCopyRules(`
 .intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so
@@ -1332,7 +1290,7 @@
 				"Test.cpp",
 				"aidl/foo/bar/Test.aidl",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			aidl: {
 				export_aidl_headers: true,
 			},
@@ -1342,21 +1300,20 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mynativelib@current",
-    sdk_member_name: "mynativelib",
+    name: "mynativelib",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
-    installable: false,
     sdk_version: "minimum",
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     target: {
         host: {
             enabled: false,
@@ -1373,18 +1330,22 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mynativelib",
-    prefer: false,
+    name: "mysdk_mynativelib@current",
+    sdk_member_name: "mynativelib",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
+    installable: false,
     sdk_version: "minimum",
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     target: {
         host: {
             enabled: false,
@@ -1422,7 +1383,7 @@
 }
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib/linux_glibc_x86_64_shared/mynativelib.so -> x86_64/lib/mynativelib.so
 .intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/Test.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h
 .intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/BnTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
@@ -1466,17 +1427,16 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mynativelib@current",
-    sdk_member_name: "mynativelib",
+    name: "mynativelib",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
-    installable: false,
     stl: "none",
     target: {
         host: {
@@ -1502,14 +1462,18 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mynativelib",
-    prefer: false,
+    name: "mysdk_mynativelib@current",
+    sdk_member_name: "mynativelib",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
+    installable: false,
     stl: "none",
     target: {
         host: {
@@ -1582,7 +1546,7 @@
 				"Test.cpp",
 				"aidl/foo/bar/Test.aidl",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			aidl: {
 				export_aidl_headers: true,
 			},
@@ -1591,38 +1555,17 @@
 	`)
 
 	result.CheckSnapshot("myexports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_static {
-    name: "myexports_mynativelib@current",
-    sdk_member_name: "mynativelib",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    stl: "none",
-    compile_multilib: "both",
-    export_include_dirs: ["include/include"],
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/mynativelib.a"],
-            export_include_dirs: ["arm64/include_gen/mynativelib"],
-        },
-        arm: {
-            srcs: ["arm/lib/mynativelib.a"],
-            export_include_dirs: ["arm/include_gen/mynativelib"],
-        },
-    },
-}
-
-cc_prebuilt_library_static {
     name: "mynativelib",
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     arch: {
         arm64: {
             srcs: ["arm64/lib/mynativelib.a"],
@@ -1634,15 +1577,9 @@
         },
     },
 }
-
-module_exports_snapshot {
-    name: "myexports@current",
-    visibility: ["//visibility:public"],
-    native_static_libs: ["myexports_mynativelib@current"],
-}
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib/android_arm64_armv8-a_static/mynativelib.a -> arm64/lib/mynativelib.a
 .intermediates/mynativelib/android_arm64_armv8-a_static/gen/aidl/aidl/foo/bar/Test.h -> arm64/include_gen/mynativelib/aidl/foo/bar/Test.h
 .intermediates/mynativelib/android_arm64_armv8-a_static/gen/aidl/aidl/foo/bar/BnTest.h -> arm64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
@@ -1672,7 +1609,7 @@
 				"Test.cpp",
 				"aidl/foo/bar/Test.aidl",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			aidl: {
 				export_aidl_headers: true,
 			},
@@ -1681,20 +1618,19 @@
 	`)
 
 	result.CheckSnapshot("myexports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_static {
-    name: "myexports_mynativelib@current",
-    sdk_member_name: "mynativelib",
+    name: "mynativelib",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
-    installable: false,
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     target: {
         host: {
             enabled: false,
@@ -1711,17 +1647,21 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_static {
-    name: "mynativelib",
-    prefer: false,
+    name: "myexports_mynativelib@current",
+    sdk_member_name: "mynativelib",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
+    installable: false,
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     target: {
         host: {
             enabled: false,
@@ -1759,7 +1699,7 @@
 }
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib/linux_glibc_x86_64_static/mynativelib.a -> x86_64/lib/mynativelib.a
 .intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/Test.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h
 .intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/BnTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
@@ -1784,7 +1724,7 @@
 			srcs: [
 				"Test.cpp",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			stl: "none",
 			recovery_available: true,
 			vendor_available: true,
@@ -1792,20 +1732,19 @@
 	`)
 
 	result.CheckSnapshot("myexports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library {
-    name: "myexports_mynativelib@current",
-    sdk_member_name: "mynativelib",
+    name: "mynativelib",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
-    installable: false,
     recovery_available: true,
     vendor_available: true,
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     arch: {
         arm64: {
             static: {
@@ -1825,17 +1764,22 @@
         },
     },
 }
+`),
+		// Make sure that the generated sdk_snapshot uses the native_libs property.
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library {
-    name: "mynativelib",
-    prefer: false,
+    name: "myexports_mynativelib@current",
+    sdk_member_name: "mynativelib",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
+    installable: false,
     recovery_available: true,
     vendor_available: true,
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     arch: {
         arm64: {
             static: {
@@ -1863,7 +1807,7 @@
 }
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib/android_arm64_armv8-a_static/mynativelib.a -> arm64/lib/mynativelib.a
 .intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so
 .intermediates/mynativelib/android_arm_armv7-a-neon_static/mynativelib.a -> arm/lib/mynativelib.a
@@ -1893,7 +1837,7 @@
 				"Test.cpp",
 				"aidl/foo/bar/Test.aidl",
 			],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			aidl: {
 				export_aidl_headers: true,
 			},
@@ -1902,7 +1846,32 @@
 	`)
 
 	result.CheckSnapshot("myexports", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_static {
+    name: "mynativelib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    device_supported: false,
+    host_supported: true,
+    stl: "none",
+    compile_multilib: "64",
+    export_include_dirs: ["include/myinclude"],
+    target: {
+        host: {
+            enabled: false,
+        },
+        linux_glibc_x86_64: {
+            enabled: true,
+            srcs: ["x86_64/lib/mynativelib.a"],
+            export_include_dirs: ["x86_64/include_gen/mynativelib"],
+        },
+    },
+}
+`),
+		checkVersionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_static {
@@ -1915,29 +1884,7 @@
     installable: false,
     stl: "none",
     compile_multilib: "64",
-    export_include_dirs: ["include/include"],
-    target: {
-        host: {
-            enabled: false,
-        },
-        linux_glibc_x86_64: {
-            enabled: true,
-            srcs: ["x86_64/lib/mynativelib.a"],
-            export_include_dirs: ["x86_64/include_gen/mynativelib"],
-        },
-    },
-}
-
-cc_prebuilt_library_static {
-    name: "mynativelib",
-    prefer: false,
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    device_supported: false,
-    host_supported: true,
-    stl: "none",
-    compile_multilib: "64",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     target: {
         host: {
             enabled: false,
@@ -1965,9 +1912,10 @@
             enabled: true,
         },
     },
-}`),
+}
+`),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 .intermediates/mynativelib/linux_glibc_x86_64_static/mynativelib.a -> x86_64/lib/mynativelib.a
 .intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/Test.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h
 .intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/BnTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
@@ -1985,43 +1933,27 @@
 
 		cc_library_headers {
 			name: "mynativeheaders",
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			stl: "none",
 		}
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_headers {
-    name: "mysdk_mynativeheaders@current",
-    sdk_member_name: "mynativeheaders",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    stl: "none",
-    compile_multilib: "both",
-    export_include_dirs: ["include/include"],
-}
-
-cc_prebuilt_library_headers {
     name: "mynativeheaders",
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
-}
-
-sdk_snapshot {
-    name: "mysdk@current",
-    visibility: ["//visibility:public"],
-    native_header_libs: ["mysdk_mynativeheaders@current"],
+    export_include_dirs: ["include/myinclude"],
 }
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 `),
 	)
 }
@@ -2039,25 +1971,25 @@
 			name: "mynativeheaders",
 			device_supported: false,
 			host_supported: true,
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			stl: "none",
 		}
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_headers {
-    name: "mysdk_mynativeheaders@current",
-    sdk_member_name: "mynativeheaders",
+    name: "mynativeheaders",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     target: {
         host: {
             enabled: false,
@@ -2070,17 +2002,20 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_headers {
-    name: "mynativeheaders",
-    prefer: false,
+    name: "mysdk_mynativeheaders@current",
+    sdk_member_name: "mynativeheaders",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     device_supported: false,
     host_supported: true,
     stl: "none",
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     target: {
         host: {
             enabled: false,
@@ -2114,7 +2049,7 @@
 }
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 `),
 	)
 }
@@ -2131,20 +2066,52 @@
 			name: "mynativeheaders",
 			host_supported: true,
 			stl: "none",
-			export_system_include_dirs: ["include"],
+			export_system_include_dirs: ["myinclude"],
 			target: {
 				android: {
-					export_include_dirs: ["include-android"],
+					export_include_dirs: ["myinclude-android"],
 				},
 				host: {
-					export_include_dirs: ["include-host"],
+					export_include_dirs: ["myinclude-host"],
 				},
 			},
 		}
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_headers {
+    name: "mynativeheaders",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    host_supported: true,
+    stl: "none",
+    compile_multilib: "both",
+    export_system_include_dirs: ["common_os/include/myinclude"],
+    target: {
+        host: {
+            enabled: false,
+        },
+        android: {
+            export_include_dirs: ["android/include/myinclude-android"],
+        },
+        linux_glibc: {
+            export_include_dirs: ["linux_glibc/include/myinclude-host"],
+        },
+        linux_glibc_x86_64: {
+            enabled: true,
+        },
+        linux_glibc_x86: {
+            enabled: true,
+        },
+    },
+}
+`),
+		// Verifi
+		checkVersionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_headers {
@@ -2155,44 +2122,16 @@
     host_supported: true,
     stl: "none",
     compile_multilib: "both",
-    export_system_include_dirs: ["common_os/include/include"],
+    export_system_include_dirs: ["common_os/include/myinclude"],
     target: {
         host: {
             enabled: false,
         },
         android: {
-            export_include_dirs: ["android/include/include-android"],
+            export_include_dirs: ["android/include/myinclude-android"],
         },
         linux_glibc: {
-            export_include_dirs: ["linux_glibc/include/include-host"],
-        },
-        linux_glibc_x86_64: {
-            enabled: true,
-        },
-        linux_glibc_x86: {
-            enabled: true,
-        },
-    },
-}
-
-cc_prebuilt_library_headers {
-    name: "mynativeheaders",
-    prefer: false,
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    host_supported: true,
-    stl: "none",
-    compile_multilib: "both",
-    export_system_include_dirs: ["common_os/include/include"],
-    target: {
-        host: {
-            enabled: false,
-        },
-        android: {
-            export_include_dirs: ["android/include/include-android"],
-        },
-        linux_glibc: {
-            export_include_dirs: ["linux_glibc/include/include-host"],
+            export_include_dirs: ["linux_glibc/include/myinclude-host"],
         },
         linux_glibc_x86_64: {
             enabled: true,
@@ -2222,9 +2161,9 @@
 }
 `),
 		checkAllCopyRules(`
-include/Test.h -> common_os/include/include/Test.h
-include-android/AndroidTest.h -> android/include/include-android/AndroidTest.h
-include-host/HostTest.h -> linux_glibc/include/include-host/HostTest.h
+myinclude/Test.h -> common_os/include/myinclude/Test.h
+myinclude-android/AndroidTest.h -> android/include/myinclude-android/AndroidTest.h
+myinclude-host/HostTest.h -> linux_glibc/include/myinclude-host/HostTest.h
 `),
 	)
 }
@@ -2253,27 +2192,10 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_sslnil@current",
-    sdk_member_name: "sslnil",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    compile_multilib: "both",
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/sslnil.so"],
-        },
-        arm: {
-            srcs: ["arm/lib/sslnil.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "sslnil",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -2290,24 +2212,6 @@
 }
 
 cc_prebuilt_library_shared {
-    name: "mysdk_sslempty@current",
-    sdk_member_name: "sslempty",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    compile_multilib: "both",
-    system_shared_libs: [],
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/sslempty.so"],
-        },
-        arm: {
-            srcs: ["arm/lib/sslempty.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "sslempty",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -2325,24 +2229,6 @@
 }
 
 cc_prebuilt_library_shared {
-    name: "mysdk_sslnonempty@current",
-    sdk_member_name: "sslnonempty",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    compile_multilib: "both",
-    system_shared_libs: ["mysdk_sslnil@current"],
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/sslnonempty.so"],
-        },
-        arm: {
-            srcs: ["arm/lib/sslnonempty.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "sslnonempty",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -2358,16 +2244,6 @@
         },
     },
 }
-
-sdk_snapshot {
-    name: "mysdk@current",
-    visibility: ["//visibility:public"],
-    native_shared_libs: [
-        "mysdk_sslnil@current",
-        "mysdk_sslempty@current",
-        "mysdk_sslnonempty@current",
-    ],
-}
 `))
 
 	result = testSdkWithCc(t, `
@@ -2389,16 +2265,15 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_sslvariants@current",
-    sdk_member_name: "sslvariants",
+    name: "sslvariants",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
-    installable: false,
     compile_multilib: "both",
     target: {
         host: {
@@ -2423,13 +2298,17 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "sslvariants",
-    prefer: false,
+    name: "mysdk_sslvariants@current",
+    sdk_member_name: "sslvariants",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
+    installable: false,
     compile_multilib: "both",
     target: {
         host: {
@@ -2497,34 +2376,10 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_stubslib@current",
-    sdk_member_name: "stubslib",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    compile_multilib: "both",
-    stubs: {
-        versions: [
-            "1",
-            "2",
-            "3",
-        ],
-    },
-    arch: {
-        arm64: {
-            srcs: ["arm64/lib/stubslib.so"],
-        },
-        arm: {
-            srcs: ["arm/lib/stubslib.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "stubslib",
     prefer: false,
     visibility: ["//visibility:public"],
@@ -2546,12 +2401,6 @@
         },
     },
 }
-
-sdk_snapshot {
-    name: "mysdk@current",
-    visibility: ["//visibility:public"],
-    native_shared_libs: ["mysdk_stubslib@current"],
-}
 `))
 }
 
@@ -2580,16 +2429,15 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_stubslib@current",
-    sdk_member_name: "stubslib",
+    name: "stubslib",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
-    installable: false,
     compile_multilib: "both",
     stubs: {
         versions: [
@@ -2618,13 +2466,17 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "stubslib",
-    prefer: false,
+    name: "mysdk_stubslib@current",
+    sdk_member_name: "stubslib",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
+    installable: false,
     compile_multilib: "both",
     stubs: {
         versions: [
@@ -2690,16 +2542,15 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mylib@current",
-    sdk_member_name: "mylib",
+    name: "mylib",
+    prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
-    installable: false,
     unique_host_soname: true,
     compile_multilib: "both",
     target: {
@@ -2722,13 +2573,17 @@
         },
     },
 }
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mylib",
-    prefer: false,
+    name: "mysdk_mylib@current",
+    sdk_member_name: "mylib",
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     host_supported: true,
+    installable: false,
     unique_host_soname: true,
     compile_multilib: "both",
     target: {
@@ -2789,7 +2644,7 @@
 		cc_library_shared {
 			name: "mynativelib",
 			srcs: ["Test.cpp"],
-			export_include_dirs: ["include"],
+			export_include_dirs: ["myinclude"],
 			arch: {
 				arm64: {
 					export_system_include_dirs: ["arm64/include"],
@@ -2802,34 +2657,16 @@
 	`)
 
 	result.CheckSnapshot("mysdk", "",
-		checkAndroidBpContents(`
+		checkUnversionedAndroidBpContents(`
 // This is auto-generated. DO NOT EDIT.
 
 cc_prebuilt_library_shared {
-    name: "mysdk_mynativelib@current",
-    sdk_member_name: "mynativelib",
-    visibility: ["//visibility:public"],
-    apex_available: ["//apex_available:platform"],
-    installable: false,
-    compile_multilib: "both",
-    export_include_dirs: ["include/include"],
-    arch: {
-        arm64: {
-            export_system_include_dirs: ["arm64/include/arm64/include"],
-        },
-        arm: {
-            srcs: ["arm/lib/mynativelib.so"],
-        },
-    },
-}
-
-cc_prebuilt_library_shared {
     name: "mynativelib",
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
     compile_multilib: "both",
-    export_include_dirs: ["include/include"],
+    export_include_dirs: ["include/myinclude"],
     arch: {
         arm64: {
             export_system_include_dirs: ["arm64/include/arm64/include"],
@@ -2839,15 +2676,9 @@
         },
     },
 }
-
-sdk_snapshot {
-    name: "mysdk@current",
-    visibility: ["//visibility:public"],
-    native_shared_libs: ["mysdk_mynativelib@current"],
-}
 `),
 		checkAllCopyRules(`
-include/Test.h -> include/include/Test.h
+myinclude/Test.h -> include/myinclude/Test.h
 arm64/include/Arm64Test.h -> arm64/include/arm64/include/Arm64Test.h
 .intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so`),
 	)
diff --git a/sdk/testing.go b/sdk/testing.go
index 1ac873b..3910e6a 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -243,11 +243,11 @@
 // e.g. find the src/dest pairs from each cp command, the various zip files
 // generated, etc.
 func (r *testSdkResult) getSdkSnapshotBuildInfo(sdk *sdk) *snapshotBuildInfo {
-	androidBpContents := sdk.GetAndroidBpContentsForTests()
-
 	info := &snapshotBuildInfo{
-		r:                 r,
-		androidBpContents: androidBpContents,
+		r:                            r,
+		androidBpContents:            sdk.GetAndroidBpContentsForTests(),
+		androidUnversionedBpContents: sdk.GetUnversionedAndroidBpContentsForTests(),
+		androidVersionedBpContents:   sdk.GetVersionedAndroidBpContentsForTests(),
 	}
 
 	buildParams := sdk.BuildParamsForTests()
@@ -365,6 +365,33 @@
 	}
 }
 
+// Check that the snapshot's unversioned generated Android.bp is correct.
+//
+// This func should be used to check the general snapshot generation code.
+//
+// Both the expected and actual string are both trimmed before comparing.
+func checkUnversionedAndroidBpContents(expected string) snapshotBuildInfoChecker {
+	return func(info *snapshotBuildInfo) {
+		info.r.t.Helper()
+		info.r.AssertTrimmedStringEquals("unversioned Android.bp contents do not match", expected, info.androidUnversionedBpContents)
+	}
+}
+
+// Check that the snapshot's versioned generated Android.bp is correct.
+//
+// This func should only be used to check the version specific snapshot generation code,
+// i.e. the encoding of version into module names and the generation of the _snapshot module. The
+// general snapshot generation code should be checked using the checkUnversionedAndroidBpContents()
+// func.
+//
+// Both the expected and actual string are both trimmed before comparing.
+func checkVersionedAndroidBpContents(expected string) snapshotBuildInfoChecker {
+	return func(info *snapshotBuildInfo) {
+		info.r.t.Helper()
+		info.r.AssertTrimmedStringEquals("versioned Android.bp contents do not match", expected, info.androidVersionedBpContents)
+	}
+}
+
 // Check that the snapshot's copy rules are correct.
 //
 // The copy rules are formatted as <src> -> <dest>, one per line and then compared
@@ -407,6 +434,12 @@
 	// The contents of the generated Android.bp file
 	androidBpContents string
 
+	// The contents of the unversioned Android.bp file
+	androidUnversionedBpContents string
+
+	// The contents of the versioned Android.bp file
+	androidVersionedBpContents string
+
 	// The paths, relative to the snapshot root, of all files and directories copied into the
 	// snapshot.
 	snapshotContents []string
diff --git a/sdk/update.go b/sdk/update.go
index 377aaae..828c7b6 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -572,12 +572,20 @@
 }
 
 func generateBpContents(contents *generatedContents, bpFile *bpFile) {
+	generateFilteredBpContents(contents, bpFile, func(*bpModule) bool {
+		return true
+	})
+}
+
+func generateFilteredBpContents(contents *generatedContents, bpFile *bpFile, moduleFilter func(module *bpModule) bool) {
 	contents.Printfln("// This is auto-generated. DO NOT EDIT.")
 	for _, bpModule := range bpFile.order {
-		contents.Printfln("")
-		contents.Printfln("%s {", bpModule.moduleType)
-		outputPropertySet(contents, bpModule.bpPropertySet)
-		contents.Printfln("}")
+		if moduleFilter(bpModule) {
+			contents.Printfln("")
+			contents.Printfln("%s {", bpModule.moduleType)
+			outputPropertySet(contents, bpModule.bpPropertySet)
+			contents.Printfln("}")
+		}
 	}
 }
 
@@ -639,6 +647,22 @@
 	return contents.content.String()
 }
 
+func (s *sdk) GetUnversionedAndroidBpContentsForTests() string {
+	contents := &generatedContents{}
+	generateFilteredBpContents(contents, s.builderForTests.bpFile, func(module *bpModule) bool {
+		return !strings.Contains(module.properties["name"].(string), "@")
+	})
+	return contents.content.String()
+}
+
+func (s *sdk) GetVersionedAndroidBpContentsForTests() string {
+	contents := &generatedContents{}
+	generateFilteredBpContents(contents, s.builderForTests.bpFile, func(module *bpModule) bool {
+		return strings.Contains(module.properties["name"].(string), "@")
+	})
+	return contents.content.String()
+}
+
 type snapshotBuilder struct {
 	ctx         android.ModuleContext
 	sdk         *sdk
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 58f8cf6..3a5c7de 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -514,9 +514,11 @@
 		Srcs: srcs,
 	}
 
-	props := bazel.NewBazelTargetModuleProperties(m.Name(), "sh_binary", "")
+	props := bazel.BazelTargetModuleProperties{
+		Rule_class: "sh_binary",
+	}
 
-	ctx.CreateBazelTargetModule(BazelShBinaryFactory, props, attrs)
+	ctx.CreateBazelTargetModule(BazelShBinaryFactory, m.Name(), props, attrs)
 }
 
 func (m *bazelShBinary) Name() string {