Snap for 11526283 from 558c8dc2193040f29b3d031cb0b9711f2d605fd2 to 24Q2-release
Change-Id: I8bb7a133bd91fdbc5e01e6d191e597612dd3b535
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 13cda9d..5a94a0f 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -534,6 +534,35 @@
for _, moduleInFamily := range allModulesInFamily {
if moduleInFamily.Name() != selectedModuleInFamily.Name() {
moduleInFamily.HideFromMake()
+ // If this is a prebuilt module, unset properties.UsePrebuilt
+ // properties.UsePrebuilt might evaluate to true via soong config var fallback mechanism
+ // Set it to false explicitly so that the following mutator does not replace rdeps to this unselected prebuilt
+ if p := GetEmbeddedPrebuilt(moduleInFamily); p != nil {
+ p.properties.UsePrebuilt = false
+ }
+ }
+ }
+ }
+ // Do a validation pass to make sure that multiple prebuilts of a specific module are not selected.
+ // This might happen if the prebuilts share the same soong config var namespace.
+ // This should be an error, unless one of the prebuilts has been explicitly declared in apex_contributions
+ var selectedPrebuilt Module
+ for _, moduleInFamily := range allModulesInFamily {
+ // Skip if this module is in a different namespace
+ if !moduleInFamily.ExportedToMake() {
+ continue
+ }
+ // Skip for the top-level java_sdk_library_(_import). This has some special cases that need to be addressed first.
+ // This does not run into non-determinism because PrebuiltPostDepsMutator also has the special case
+ if sdkLibrary, ok := moduleInFamily.(interface{ SdkLibraryName() *string }); ok && sdkLibrary.SdkLibraryName() != nil {
+ continue
+ }
+ if p := GetEmbeddedPrebuilt(moduleInFamily); p != nil && p.properties.UsePrebuilt {
+ if selectedPrebuilt == nil {
+ selectedPrebuilt = moduleInFamily
+ } else {
+ ctx.ModuleErrorf("Multiple prebuilt modules %v and %v have been marked as preferred for this source module. "+
+ "Please add the appropriate prebuilt module to apex_contributions for this release config.", selectedPrebuilt.Name(), moduleInFamily.Name())
}
}
}
@@ -562,7 +591,7 @@
// If we do not special-case this here, rdeps referring to a java_sdk_library in next builds via libs
// will get prebuilt stubs
// TODO (b/308187268): Remove this after the apexes have been added to apex_contributions
- if psi.IsSelected(*sdkLibrary.SdkLibraryName()) {
+ if psi.IsSelected(name) {
return false
}
}
@@ -625,6 +654,17 @@
CreatedByJavaSdkLibraryName() *string
}
+// Returns true if the prebuilt variant is disabled
+// e.g. for a cc_prebuilt_library_shared, this will return
+// - true for the static variant of the module
+// - false for the shared variant of the module
+//
+// Even though this is a cc_prebuilt_library_shared, we create both the variants today
+// https://source.corp.google.com/h/googleplex-android/platform/build/soong/+/e08e32b45a18a77bc3c3e751f730539b1b374f1b:cc/library.go;l=2113-2116;drc=2c4a9779cd1921d0397a12b3d3521f4c9b30d747;bpv=1;bpt=0
+func (p *Prebuilt) variantIsDisabled(ctx BaseMutatorContext, prebuilt Module) bool {
+ return p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0
+}
+
// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
// will be used if it is marked "prefer" or if the source module is disabled.
func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool {
@@ -639,7 +679,7 @@
return false
}
// If the prebuilt module is explicitly listed in the metadata module, use that
- if isSelected(psi, prebuilt) {
+ if isSelected(psi, prebuilt) && !p.variantIsDisabled(ctx, prebuilt) {
return true
}
@@ -647,7 +687,7 @@
// fall back to the existing source vs prebuilt selection.
// TODO: Drop the fallback mechanisms
- if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 {
+ if p.variantIsDisabled(ctx, prebuilt) {
return false
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 74d6de8..9dc77c2 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -6199,7 +6199,7 @@
`)
})
- t.Run("Co-existing unflagged apexes should create a duplicate deapexer error in hiddenapi processing", func(t *testing.T) {
+ t.Run("Co-existing unflagged apexes should create a duplicate module error", func(t *testing.T) {
bp := `
// Source
apex {
@@ -6273,7 +6273,7 @@
}
`
- testDexpreoptWithApexes(t, bp, "Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_myapex.v1 and prebuilt_myapex.v2", preparer, fragment)
+ testDexpreoptWithApexes(t, bp, "Multiple prebuilt modules prebuilt_myapex.v1 and prebuilt_myapex.v2 have been marked as preferred for this source module", preparer, fragment)
})
}
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index f6b5ed5..71b7e43 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -610,3 +610,153 @@
android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "libbar", entries.EntryMap["LOCAL_MODULE"][0])
}
}
+
+// Setting prefer on multiple prebuilts is an error, unless one of them is also listed in apex_contributions
+func TestMultiplePrebuiltsPreferredUsingLegacyFlags(t *testing.T) {
+ bp := `
+ // an rdep
+ cc_library {
+ name: "libfoo",
+ shared_libs: ["libbar"],
+ }
+
+ // multiple variations of dep
+ // source
+ cc_library {
+ name: "libbar",
+ }
+ // prebuilt "v1"
+ cc_prebuilt_library_shared {
+ name: "libbar",
+ srcs: ["libbar.so"],
+ prefer: true,
+ }
+ // prebuilt "v2"
+ cc_prebuilt_library_shared {
+ name: "libbar.v2",
+ stem: "libbar",
+ source_module_name: "libbar",
+ srcs: ["libbar.so"],
+ prefer: true,
+ }
+
+ // selectors
+ apex_contributions {
+ name: "myapex_contributions",
+ contents: [%v],
+ }
+ all_apex_contributions {name: "all_apex_contributions"}
+ `
+ hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool {
+ t.Helper()
+ var found bool
+ ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
+ if dep == wantDep {
+ found = true
+ }
+ })
+ return found
+ }
+
+ testCases := []struct {
+ desc string
+ selectedDependencyName string
+ expectedDependencyName string
+ expectedErr string
+ }{
+ {
+ desc: "Multiple prebuilts have prefer: true",
+ expectedErr: "Multiple prebuilt modules prebuilt_libbar and prebuilt_libbar.v2 have been marked as preferred for this source module",
+ },
+ {
+ desc: "Multiple prebuilts have prefer: true. The prebuilt listed in apex_contributions wins.",
+ selectedDependencyName: `"prebuilt_libbar"`,
+ expectedDependencyName: "prebuilt_libbar",
+ },
+ }
+
+ for _, tc := range testCases {
+ preparer := android.GroupFixturePreparers(
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ android.RegisterApexContributionsBuildComponents(ctx)
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
+ }
+ }),
+ )
+ if tc.expectedErr != "" {
+ preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedErr))
+ }
+
+ ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{
+ "libbar.so": nil,
+ "crtx.o": nil,
+ }, preparer)
+ if tc.expectedErr != "" {
+ return // the fixture will assert that the excepted err has been raised
+ }
+ libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+ expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module()
+ android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency))
+ }
+}
+
+// If module sdk cannot provide a cc module variant (e.g. static), then the module variant from source should be used
+func TestMissingVariantInModuleSdk(t *testing.T) {
+ bp := `
+ // an rdep
+ cc_library {
+ name: "libfoo",
+ static_libs: ["libbar"],
+ }
+
+ // source
+ cc_library {
+ name: "libbar",
+ }
+ // prebuilt
+ // libbar only exists as a shared library
+ cc_prebuilt_library_shared {
+ name: "libbar",
+ srcs: ["libbar.so"],
+ }
+ // selectors
+ apex_contributions {
+ name: "myapex_contributions",
+ contents: ["prebuilt_libbar"],
+ }
+ all_apex_contributions {name: "all_apex_contributions"}
+ `
+ hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool {
+ t.Helper()
+ var found bool
+ ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
+ if dep == wantDep {
+ found = true
+ }
+ })
+ return found
+ }
+
+ preparer := android.GroupFixturePreparers(
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ android.RegisterApexContributionsBuildComponents(ctx)
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BuildFlags = map[string]string{
+ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
+ }
+ }),
+ )
+ ctx := testPrebuilt(t, bp, map[string][]byte{
+ "libbar.so": nil,
+ "crtx.o": nil,
+ }, preparer)
+ libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+ sourceLibBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_static").Module()
+ // Even though the prebuilt is listed in apex_contributions, the prebuilt does not have a static variant.
+ // Therefore source of libbar should be used.
+ android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from libfoo to source libbar"), true, hasDep(ctx, libfoo, sourceLibBar))
+}
diff --git a/java/androidmk.go b/java/androidmk.go
index b7df9bf..498962f 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -691,9 +691,10 @@
return nil
}
return []android.AndroidMkEntries{android.AndroidMkEntries{
- Class: "APPS",
- OutputFile: android.OptionalPathForPath(a.outputFile),
- Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
+ Class: "APPS",
+ OutputFile: android.OptionalPathForPath(a.outputFile),
+ OverrideName: a.BaseModuleName(), // TODO (spandandas): Add a test
+ Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", a.Privileged())
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 1cfa642..38ed856 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -187,6 +187,33 @@
return apexInfo.ForPrebuiltApex
}
+// For apex variant of modules, this returns true on the source variant if the prebuilt apex
+// has been selected using apex_contributions.
+// The prebuilt apex will be responsible for generating the dexpreopt rules of the deapexed java lib.
+func disableSourceApexVariant(ctx android.BaseModuleContext) bool {
+ if !isApexVariant(ctx) {
+ return false // platform variant
+ }
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
+ psi := android.PrebuiltSelectionInfoMap{}
+ ctx.VisitDirectDepsWithTag(android.PrebuiltDepTag, func(am android.Module) {
+ psi, _ = android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider)
+ })
+ // Find the apex variant for this module
+ _, apexVariantsWithoutTestApexes, _ := android.ListSetDifference(apexInfo.InApexVariants, apexInfo.TestApexes)
+ disableSource := false
+ // find the selected apexes
+ for _, apexVariant := range apexVariantsWithoutTestApexes {
+ for _, selected := range psi.GetSelectedModulesForApiDomain(apexVariant) {
+ // If the apex_contribution for this api domain contains a prebuilt apex, disable the source variant
+ if strings.HasPrefix(selected, "prebuilt_com.google.android") {
+ disableSource = true
+ }
+ }
+ }
+ return disableSource
+}
+
// Returns whether dexpreopt is applicable to the module.
// When it returns true, neither profile nor dexpreopt artifacts will be generated.
func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext, libName string) bool {
@@ -216,6 +243,10 @@
return true
}
+ if disableSourceApexVariant(ctx) {
+ return true
+ }
+
if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex {
// dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes
return false