Merge "Re-enable the base hidl modules in mixed build."
diff --git a/android/defs.go b/android/defs.go
index 362b382..2a28e98 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -68,7 +68,7 @@
 
 	CpExecutable = pctx.AndroidStaticRule("CpExecutable",
 		blueprint.RuleParams{
-			Command:     "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out && chmod +x $out$extraCmds",
+			Command:     "rm -f $out && cp $cpFlags $in $out && chmod +x $out$extraCmds",
 			Description: "cp $out",
 		},
 		"cpFlags", "extraCmds")
diff --git a/android_sdk/sdk_repo_host.go b/android_sdk/sdk_repo_host.go
index 280dae8..f646742 100644
--- a/android_sdk/sdk_repo_host.go
+++ b/android_sdk/sdk_repo_host.go
@@ -166,9 +166,10 @@
 		}
 	} else {
 		llvmStrip := config.ClangPath(ctx, "bin/llvm-strip")
-		llvmLib := config.ClangPath(ctx, "lib64/libc++.so.1")
+		llvmLib64 := config.ClangPath(ctx, "lib64/libc++.so.1")
+		llvmLib := config.ClangPath(ctx, "lib/libc++.so.1")
 		for _, strip := range s.properties.Strip_files {
-			cmd := builder.Command().Tool(llvmStrip).ImplicitTool(llvmLib)
+			cmd := builder.Command().Tool(llvmStrip).ImplicitTool(llvmLib64).ImplicitTool(llvmLib)
 			if !ctx.Windows() {
 				cmd.Flag("-x")
 			}
diff --git a/bazel/properties.go b/bazel/properties.go
index aba97c6..bffd97b 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -960,6 +960,146 @@
 	return ret
 }
 
+// StringAttribute corresponds to the string Bazel attribute type with
+// support for additional metadata, like configurations.
+type StringAttribute struct {
+	// The base value of the string attribute.
+	Value *string
+
+	// The configured attribute label list Values. Optional
+	// a map of independent configurability axes
+	ConfigurableValues configurableStrings
+}
+
+type configurableStrings map[ConfigurationAxis]stringSelectValues
+
+func (cs configurableStrings) setValueForAxis(axis ConfigurationAxis, config string, str *string) {
+	if cs[axis] == nil {
+		cs[axis] = make(stringSelectValues)
+	}
+	var v = ""
+	if str != nil {
+		v = *str
+	}
+	cs[axis][config] = v
+}
+
+type stringSelectValues map[string]string
+
+// HasConfigurableValues returns true if the attribute contains axis-specific string values.
+func (sa StringAttribute) HasConfigurableValues() bool {
+	for _, selectValues := range sa.ConfigurableValues {
+		if len(selectValues) > 0 {
+			return true
+		}
+	}
+	return false
+}
+
+// SetSelectValue set a value for a bazel select for the given axis, config and value.
+func (sa *StringAttribute) SetSelectValue(axis ConfigurationAxis, config string, str *string) {
+	axis.validateConfig(config)
+	switch axis.configurationType {
+	case noConfig:
+		sa.Value = str
+	case arch, os, osArch, productVariables:
+		if sa.ConfigurableValues == nil {
+			sa.ConfigurableValues = make(configurableStrings)
+		}
+		sa.ConfigurableValues.setValueForAxis(axis, config, str)
+	default:
+		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+	}
+}
+
+// SelectValue gets a value for a bazel select for the given axis and config.
+func (sa *StringAttribute) SelectValue(axis ConfigurationAxis, config string) *string {
+	axis.validateConfig(config)
+	switch axis.configurationType {
+	case noConfig:
+		return sa.Value
+	case arch, os, osArch, productVariables:
+		if v, ok := sa.ConfigurableValues[axis][config]; ok {
+			return &v
+		} else {
+			return nil
+		}
+	default:
+		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
+	}
+}
+
+// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
+func (sa *StringAttribute) SortedConfigurationAxes() []ConfigurationAxis {
+	keys := make([]ConfigurationAxis, 0, len(sa.ConfigurableValues))
+	for k := range sa.ConfigurableValues {
+		keys = append(keys, k)
+	}
+
+	sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
+	return keys
+}
+
+// Collapse reduces the configurable axes of the string attribute to a single axis.
+// This is necessary for final writing to bp2build, as a configurable string
+// attribute can only be comprised by a single select.
+func (sa *StringAttribute) Collapse() error {
+	axisTypes := sa.axisTypes()
+	_, containsOs := axisTypes[os]
+	_, containsArch := axisTypes[arch]
+	_, containsOsArch := axisTypes[osArch]
+	_, containsProductVariables := axisTypes[productVariables]
+	if containsProductVariables {
+		if containsOs || containsArch || containsOsArch {
+			return fmt.Errorf("boolean attribute could not be collapsed as it has two or more unrelated axes")
+		}
+	}
+	if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
+		// If a bool attribute has both os and arch configuration axes, the only
+		// way to successfully union their values is to increase the granularity
+		// of the configuration criteria to os_arch.
+		for osType, supportedArchs := range osToArchMap {
+			for _, supportedArch := range supportedArchs {
+				osArch := osArchString(osType, supportedArch)
+				if archOsVal := sa.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
+					// Do nothing, as the arch_os is explicitly defined already.
+				} else {
+					archVal := sa.SelectValue(ArchConfigurationAxis, supportedArch)
+					osVal := sa.SelectValue(OsConfigurationAxis, osType)
+					if osVal != nil && archVal != nil {
+						// In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
+						// runs after os mutator.
+						sa.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
+					} else if osVal != nil && archVal == nil {
+						sa.SetSelectValue(OsArchConfigurationAxis, osArch, osVal)
+					} else if osVal == nil && archVal != nil {
+						sa.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
+					}
+				}
+			}
+		}
+		// All os_arch values are now set. Clear os and arch axes.
+		delete(sa.ConfigurableValues, ArchConfigurationAxis)
+		delete(sa.ConfigurableValues, OsConfigurationAxis)
+		// Verify post-condition; this should never fail, provided no additional
+		// axes are introduced.
+		if len(sa.ConfigurableValues) > 1 {
+			panic(fmt.Errorf("error in collapsing attribute: %#v", sa))
+		}
+	}
+	return nil
+}
+
+func (sa *StringAttribute) axisTypes() map[configurationType]bool {
+	types := map[configurationType]bool{}
+	for k := range sa.ConfigurableValues {
+		if strs := sa.ConfigurableValues[k]; len(strs) > 0 {
+			types[k.configurationType] = true
+		}
+	}
+	return types
+}
+
 // StringListAttribute corresponds to the string_list Bazel attribute type with
 // support for additional metadata, like configurations.
 type StringListAttribute struct {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index c5644ed..1ac7518 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -231,6 +231,52 @@
 func TestGenerateBazelTargetModules(t *testing.T) {
 	testCases := []Bp2buildTestCase{
 		{
+			Description: "string prop empty",
+			Blueprint: `custom {
+	name: "foo",
+    string_literal_prop: "",
+    bazel_module: { bp2build_available: true },
+}`,
+			ExpectedBazelTargets: []string{
+				makeBazelTarget("custom", "foo", AttrNameToString{
+					"string_literal_prop": `""`,
+				}),
+			},
+		},
+		{
+			Description: `string prop "PROP"`,
+			Blueprint: `custom {
+	name: "foo",
+    string_literal_prop: "PROP",
+    bazel_module: { bp2build_available: true },
+}`,
+			ExpectedBazelTargets: []string{
+				makeBazelTarget("custom", "foo", AttrNameToString{
+					"string_literal_prop": `"PROP"`,
+				}),
+			},
+		},
+		{
+			Description: `string prop arch variant`,
+			Blueprint: `custom {
+    name: "foo",
+    arch: {
+        arm: { string_literal_prop: "ARM" },
+        arm64: { string_literal_prop: "ARM64" },
+    },
+    bazel_module: { bp2build_available: true },
+}`,
+			ExpectedBazelTargets: []string{
+				makeBazelTarget("custom", "foo", AttrNameToString{
+					"string_literal_prop": `select({
+        "//build/bazel/platforms/arch:arm": "ARM",
+        "//build/bazel/platforms/arch:arm64": "ARM64",
+        "//conditions:default": None,
+    })`,
+				}),
+			},
+		},
+		{
 			Description: "string ptr props",
 			Blueprint: `custom {
 	name: "foo",
@@ -244,7 +290,7 @@
 			},
 		},
 		{
-			Description: "string props",
+			Description: "string list props",
 			Blueprint: `custom {
   name: "foo",
     string_list_prop: ["a", "b"],
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 6cb9509..28d2c75 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -15,11 +15,12 @@
 package bp2build
 
 import (
-	"android/soong/android"
 	"io/ioutil"
 	"os"
 	"strings"
 	"testing"
+
+	"android/soong/android"
 )
 
 func setUp() {
@@ -103,6 +104,7 @@
         "one_to_many_prop": attr.bool(),
         "other_embedded_prop": attr.string(),
         "string_list_prop": attr.string_list(),
+        "string_literal_prop": attr.string(),
         "string_prop": attr.string(),
         "string_ptr_prop": attr.string(),
     },
@@ -132,6 +134,7 @@
         "one_to_many_prop": attr.bool(),
         "other_embedded_prop": attr.string(),
         "string_list_prop": attr.string_list(),
+        "string_literal_prop": attr.string(),
         "string_prop": attr.string(),
         "string_ptr_prop": attr.string(),
     },
@@ -161,6 +164,7 @@
         "one_to_many_prop": attr.bool(),
         "other_embedded_prop": attr.string(),
         "string_list_prop": attr.string_list(),
+        "string_literal_prop": attr.string(),
         "string_prop": attr.string(),
         "string_ptr_prop": attr.string(),
         # test_prop start
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index d37a523..9398d12 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -13,6 +13,30 @@
 
 type selects map[string]reflect.Value
 
+func getStringValue(str bazel.StringAttribute) (reflect.Value, []selects) {
+	value := reflect.ValueOf(str.Value)
+
+	if !str.HasConfigurableValues() {
+		return value, []selects{}
+	}
+
+	ret := selects{}
+	for _, axis := range str.SortedConfigurationAxes() {
+		configToStrs := str.ConfigurableValues[axis]
+		for config, strs := range configToStrs {
+			selectKey := axis.SelectKey(config)
+			ret[selectKey] = reflect.ValueOf(strs)
+		}
+	}
+	// if there is a select, use the base value as the conditions default value
+	if len(ret) > 0 {
+		ret[bazel.ConditionsDefaultSelectKey] = value
+		value = reflect.Zero(value.Type())
+	}
+
+	return value, []selects{ret}
+}
+
 func getStringListValues(list bazel.StringListAttribute) (reflect.Value, []selects) {
 	value := reflect.ValueOf(list.Value)
 	if !list.HasConfigurableValues() {
@@ -137,6 +161,12 @@
 	// If true, print the default attribute value, even if the attribute is zero.
 	shouldPrintDefault := false
 	switch list := v.(type) {
+	case bazel.StringAttribute:
+		if err := list.Collapse(); err != nil {
+			return "", err
+		}
+		value, configurableAttrs = getStringValue(list)
+		defaultSelectValue = &bazelNone
 	case bazel.StringListAttribute:
 		value, configurableAttrs = getStringListValues(list)
 		defaultSelectValue = &emptyBazelList
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 3ee5096..0f321de 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -173,11 +173,12 @@
 	Bool_prop     bool
 	Bool_ptr_prop *bool
 	// Ensure that properties tagged `blueprint:mutated` are omitted
-	Int_prop         int `blueprint:"mutated"`
-	Int64_ptr_prop   *int64
-	String_prop      string
-	String_ptr_prop  *string
-	String_list_prop []string
+	Int_prop            int `blueprint:"mutated"`
+	Int64_ptr_prop      *int64
+	String_prop         string
+	String_literal_prop *string `android:"arch_variant"`
+	String_ptr_prop     *string
+	String_list_prop    []string
 
 	Nested_props     nestedProps
 	Nested_props_ptr *nestedProps
@@ -305,23 +306,29 @@
 type customBazelModuleAttributes struct {
 	EmbeddedAttr
 	*OtherEmbeddedAttr
-	String_ptr_prop  *string
-	String_list_prop []string
-	Arch_paths       bazel.LabelListAttribute
+	String_literal_prop bazel.StringAttribute
+	String_ptr_prop     *string
+	String_list_prop    []string
+	Arch_paths          bazel.LabelListAttribute
 }
 
 func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
-	paths := bazel.LabelListAttribute{}
-
 	if p := m.props.One_to_many_prop; p != nil && *p {
 		customBp2buildOneToMany(ctx, m)
 		return
 	}
 
+	paths := bazel.LabelListAttribute{}
+	strAttr := bazel.StringAttribute{}
 	for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
 		for config, props := range configToProps {
-			if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil {
-				paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, archProps.Arch_paths, archProps.Arch_paths_exclude))
+			if custProps, ok := props.(*customProps); ok {
+				if custProps.Arch_paths != nil {
+					paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, custProps.Arch_paths, custProps.Arch_paths_exclude))
+				}
+				if custProps.String_literal_prop != nil {
+					strAttr.SetSelectValue(axis, config, custProps.String_literal_prop)
+				}
 			}
 		}
 	}
@@ -329,10 +336,12 @@
 	paths.ResolveExcludes()
 
 	attrs := &customBazelModuleAttributes{
-		String_ptr_prop:  m.props.String_ptr_prop,
-		String_list_prop: m.props.String_list_prop,
-		Arch_paths:       paths,
+		String_literal_prop: strAttr,
+		String_ptr_prop:     m.props.String_ptr_prop,
+		String_list_prop:    m.props.String_list_prop,
+		Arch_paths:          paths,
 	}
+
 	attrs.Embedded_attr = m.props.Embedded_prop
 	if m.props.OtherEmbeddedProps != nil {
 		attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index ff5ba45..47fb919 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -226,17 +226,27 @@
 	}
 }
 
-func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) {
-	if library.sAbiDiff.Valid() && !library.static() {
-		entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", library.sAbiDiff.String())
+func (library *libraryDecorator) getAbiDiffsForAndroidMkDeps() []string {
+	if library.static() {
+		return nil
 	}
+	var abiDiffs []string
+	if library.sAbiDiff.Valid() {
+		abiDiffs = append(abiDiffs, library.sAbiDiff.String())
+	}
+	if library.prevSAbiDiff.Valid() {
+		abiDiffs = append(abiDiffs, library.prevSAbiDiff.String())
+	}
+	return abiDiffs
+}
+
+func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) {
+	entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", library.getAbiDiffsForAndroidMkDeps()...)
 }
 
 // TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries
 func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
-	if library.sAbiDiff.Valid() && !library.static() {
-		fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", library.sAbiDiff.String())
-	}
+	fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.getAbiDiffsForAndroidMkDeps(), " "))
 }
 
 func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
diff --git a/cc/builder.go b/cc/builder.go
index ab2b80a..f3faca8 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -920,10 +920,15 @@
 
 // sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
 func sourceAbiDiff(ctx android.ModuleContext, inputDump android.Path, referenceDump android.Path,
-	baseName, exportedHeaderFlags string, diffFlags []string,
-	checkAllApis, isLlndk, isNdk, isVndkExt bool) android.OptionalPath {
+	baseName, prevVersion, exportedHeaderFlags string, diffFlags []string,
+	checkAllApis, isLlndk, isNdk, isVndkExt, previousVersionDiff bool) android.OptionalPath {
 
-	outputFile := android.PathForModuleOut(ctx, baseName+".abidiff")
+	var outputFile android.ModuleOutPath
+	if prevVersion == "" {
+		outputFile = android.PathForModuleOut(ctx, baseName+".abidiff")
+	} else {
+		outputFile = android.PathForModuleOut(ctx, baseName+"."+prevVersion+".abidiff")
+	}
 	libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
 
 	var extraFlags []string
@@ -935,10 +940,15 @@
 			"-allow-unreferenced-elf-symbol-changes")
 	}
 
+	// TODO(b/241496591): Remove -advice-only after b/239792343 and b/239790286 are reolved.
+	if previousVersionDiff {
+		extraFlags = append(extraFlags, "-advice-only")
+	}
+
 	if isLlndk || isNdk {
 		extraFlags = append(extraFlags, "-consider-opaque-types-different")
 	}
-	if isVndkExt {
+	if isVndkExt || previousVersionDiff {
 		extraFlags = append(extraFlags, "-allow-extensions")
 	}
 	// TODO(b/232891473): Simplify the above logic with diffFlags.
diff --git a/cc/config/global.go b/cc/config/global.go
index 4fcef9d..357ea44 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -290,11 +290,7 @@
 		"-Wno-deprecated-non-prototype",
 	}
 
-	llvmNextExtraCommonGlobalCflags = []string{
-		"-Wno-error=array-parameter",     // http://b/241941550
-		"-Wno-error=deprecated-builtins", // http://b/241601211
-		"-Wno-error=deprecated",          // in external/googletest/googletest
-	}
+	llvmNextExtraCommonGlobalCflags = []string{}
 
 	IllegalFlags = []string{
 		"-w",
diff --git a/cc/library.go b/cc/library.go
index 546982b..897b572 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -613,6 +613,9 @@
 	// Source Abi Diff
 	sAbiDiff android.OptionalPath
 
+	// Source Abi Diff against previous SDK version
+	prevSAbiDiff android.OptionalPath
+
 	// Location of the static library in the sysroot. Empty if the library is
 	// not included in the NDK.
 	ndkSysrootPath android.Path
@@ -771,6 +774,12 @@
 		if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
 			continue
 		}
+
+		// Filter out the generated headers from bazel.
+		if strings.HasPrefix(dir, android.PathForBazelOut(ctx, "bazel-out").String()) {
+			continue
+		}
+
 		// libeigen wrongly exports the root directory "external/eigen". But only two
 		// subdirectories "Eigen" and "unsupported" contain exported header files. Even worse
 		// some of them have no extension. So we need special treatment for libeigen in order
@@ -1614,9 +1623,39 @@
 	return nil
 }
 
+func prevDumpRefVersion(ctx ModuleContext) string {
+	sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt()
+	sdkVersionStr := ctx.Config().PlatformSdkVersion().String()
+
+	if ctx.Config().PlatformSdkFinal() {
+		return strconv.Itoa(sdkVersionInt - 1)
+	} else {
+		var dirName string
+
+		isNdk := ctx.isNdk(ctx.Config())
+		if isNdk {
+			dirName = "ndk"
+		} else {
+			dirName = "platform"
+		}
+
+		// The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't
+		// been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version.
+		// This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory.
+		refDumpDir := android.ExistentPathForSource(ctx, "prebuilts", "abi-dumps", dirName, sdkVersionStr)
+		if refDumpDir.Valid() {
+			return sdkVersionStr
+		} else {
+			return strconv.Itoa(sdkVersionInt - 1)
+		}
+	}
+}
+
 func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
 	if library.sabi.shouldCreateSourceAbiDump() {
 		var version string
+		var prevVersion string
+
 		if ctx.useVndk() {
 			// For modules linking against vndk, follow its vndk version
 			version = ctx.Module().(*Module).VndkVersion()
@@ -1628,6 +1667,7 @@
 			} else {
 				version = "current"
 			}
+			prevVersion = prevDumpRefVersion(ctx)
 		}
 
 		exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
@@ -1646,13 +1686,24 @@
 
 		addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String())
 
+		if prevVersion != "" {
+			prevRefAbiDumpFile := getRefAbiDumpFile(ctx, prevVersion, fileName)
+			if prevRefAbiDumpFile != nil {
+				library.prevSAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
+					prevRefAbiDumpFile, fileName, prevVersion, exportedHeaderFlags,
+					library.Properties.Header_abi_checker.Diff_flags,
+					Bool(library.Properties.Header_abi_checker.Check_all_apis),
+					ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt(), true)
+			}
+		}
+
 		refAbiDumpFile := getRefAbiDumpFile(ctx, version, fileName)
 		if refAbiDumpFile != nil {
 			library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
-				refAbiDumpFile, fileName, exportedHeaderFlags,
+				refAbiDumpFile, fileName, "", exportedHeaderFlags,
 				library.Properties.Header_abi_checker.Diff_flags,
 				Bool(library.Properties.Header_abi_checker.Check_all_apis),
-				ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt())
+				ctx.IsLlndk(), ctx.isNdk(ctx.Config()), ctx.IsVndkExt(), false)
 		}
 	}
 }
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index f8844fc..d4a57bf 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -824,6 +824,7 @@
 
 	var regen string
 	var pom2build bool
+	var prepend string
 
 	flag.Var(&excludes, "exclude", "Exclude module")
 	flag.Var(&extraStaticLibs, "extra-static-libs", "Extra static dependencies needed when depending on a module")
@@ -839,6 +840,7 @@
 	flag.BoolVar(&jetifier, "jetifier", false, "Sets jetifier: true on all modules")
 	flag.StringVar(&regen, "regen", "", "Rewrite specified file")
 	flag.BoolVar(&pom2build, "pom2build", false, "If true, will generate a Bazel BUILD file *instead* of a .bp file")
+	flag.StringVar(&prepend, "prepend", "", "Path to a file containing text to insert at the beginning of the generated build file")
 	flag.Parse()
 
 	if regen != "" {
@@ -965,6 +967,15 @@
 	fmt.Fprintln(buf, commentString, "Automatically generated with:")
 	fmt.Fprintln(buf, commentString, "pom2bp", strings.Join(proptools.ShellEscapeList(os.Args[1:]), " "))
 
+	if prepend != "" {
+		contents, err := ioutil.ReadFile(prepend)
+		if err != nil {
+			fmt.Fprintln(os.Stderr, "Error reading", prepend, err)
+			os.Exit(1)
+		}
+		fmt.Fprintln(buf, string(contents))
+	}
+
 	depsTemplate := bpDepsTemplate
 	template := bpTemplate
 	if pom2build {
diff --git a/tests/lib.sh b/tests/lib.sh
index 69ad201..6210e77 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -111,7 +111,7 @@
 
 # shellcheck disable=SC2120
 function run_soong {
-  build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
+  USE_RBE=false build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
 }
 
 function create_mock_bazel {