Support partial module variants with apex_contributions

Some libraries like `libnativehelper_compat_libc++` only exist as shared
library in module sdk. When prebuilt of this library is selected using
apex_contritbutions, only shared linkages should be redirected to the
prebuilt version. The static linkage should come from source.

Test: Added a unit test
Bug: 322175508

Change-Id: Ic65d376b2354b4a42c7b9ea3ed1cd80c37e2840f
This commit is contained in:
Spandan Das 2024-02-27 09:31:51 +00:00
parent f2c1057586
commit 972917d794
2 changed files with 71 additions and 2 deletions

View file

@ -654,6 +654,17 @@ type createdByJavaSdkLibraryName interface {
CreatedByJavaSdkLibraryName() *string 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 // 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. // 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 { func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt Module) bool {
@ -668,7 +679,7 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M
return false return false
} }
// If the prebuilt module is explicitly listed in the metadata module, use that // 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 return true
} }
@ -676,7 +687,7 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M
// fall back to the existing source vs prebuilt selection. // fall back to the existing source vs prebuilt selection.
// TODO: Drop the fallback mechanisms // TODO: Drop the fallback mechanisms
if p.srcsSupplier != nil && len(p.srcsSupplier(ctx, prebuilt)) == 0 { if p.variantIsDisabled(ctx, prebuilt) {
return false return false
} }

View file

@ -702,3 +702,61 @@ func TestMultiplePrebuiltsPreferredUsingLegacyFlags(t *testing.T) {
android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency)) 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))
}