From 972917d794e1f9a225fa3737cf648f4a8d044d31 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 27 Feb 2024 09:31:51 +0000 Subject: [PATCH] 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 --- android/prebuilt.go | 15 ++++++++++-- cc/prebuilt_test.go | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/android/prebuilt.go b/android/prebuilt.go index 734c1101f..5a94a0f23 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -654,6 +654,17 @@ type createdByJavaSdkLibraryName interface { 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 { @@ -668,7 +679,7 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M 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 } @@ -676,7 +687,7 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M // 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/cc/prebuilt_test.go b/cc/prebuilt_test.go index 7dfe6422f..71b7e4369 100644 --- a/cc/prebuilt_test.go +++ b/cc/prebuilt_test.go @@ -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)) } } + +// 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)) +}