From 2b6dfb554d3332b26ef293b7c9618bbe4e47f20d Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 19 Jan 2024 00:22:22 +0000 Subject: [PATCH] Support mechanism to select a specific version of module sdk prebuilt This CL is scoped to cc_* module types. With trunk stable, we will have multiple prebuilts of the cc modules in prebuilts/module_sdk/art//host-exports/, and this CL introduces a mechanism to use apex_contributions to select a specific versioned prebuilt when building. If a soong module is selected using apex_contributions, all rdeps will get that soong module, which includes - rdep soong modules which might be depending on it via Android.bp - Soong's rule builder HostToolPath API Implementation details: Create a new source_module_name property to identify the root module. rdeps referring to the root module will get redirected if necessary. This property also becomes the stem, if `stem` is not set explicitly. Bug: 322175508 Test: Added a unit test Change-Id: Ic8725602c81999621fcb33ce2a57fe4b9751baa8 --- cc/androidmk.go | 5 ++- cc/cc.go | 14 ++++++- cc/prebuilt.go | 22 +++++++++- cc/prebuilt_test.go | 98 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 4 deletions(-) diff --git a/cc/androidmk.go b/cc/androidmk.go index fe542b05e..c39668c73 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -83,8 +83,9 @@ func (c *Module) AndroidMkEntries() []android.AndroidMkEntries { // causing multiple ART APEXes (com.android.art and com.android.art.debug) // to be installed. And this is breaking some older devices (like marlin) // where system.img is small. - Required: c.Properties.AndroidMkRuntimeLibs, - Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", + Required: c.Properties.AndroidMkRuntimeLibs, + OverrideName: c.BaseModuleName(), + Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { diff --git a/cc/cc.go b/cc/cc.go index c07e35850..36f04624e 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1744,7 +1744,7 @@ func (ctx *moduleContextImpl) useClangLld(actx ModuleContext) bool { } func (ctx *moduleContextImpl) baseModuleName() string { - return ctx.mod.ModuleBase.BaseModuleName() + return ctx.mod.BaseModuleName() } func (ctx *moduleContextImpl) getVndkExtendsModuleName() string { @@ -4173,6 +4173,18 @@ func (c *Module) Partition() string { return "" } +type sourceModuleName interface { + sourceModuleName() string +} + +func (c *Module) BaseModuleName() string { + if smn, ok := c.linker.(sourceModuleName); ok && smn.sourceModuleName() != "" { + // if the prebuilt module sets a source_module_name in Android.bp, use that + return smn.sourceModuleName() + } + return c.ModuleBase.BaseModuleName() +} + var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var BoolPtr = proptools.BoolPtr diff --git a/cc/prebuilt.go b/cc/prebuilt.go index e721c5388..8f4b7df42 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -17,6 +17,8 @@ package cc import ( "path/filepath" + "github.com/google/blueprint/proptools" + "android/soong/android" ) @@ -36,9 +38,15 @@ func RegisterPrebuiltBuildComponents(ctx android.RegistrationContext) { type prebuiltLinkerInterface interface { Name(string) string prebuilt() *android.Prebuilt + sourceModuleName() string } type prebuiltLinkerProperties struct { + // Name of the source soong module that gets shadowed by this prebuilt + // If unspecified, follows the naming convention that the source module of + // the prebuilt is Name() without "prebuilt_" prefix + Source_module_name *string + // a prebuilt library or binary. Can reference a genrule module that generates an executable file. Srcs []string `android:"path,arch_variant"` @@ -337,7 +345,11 @@ func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libr } type prebuiltObjectProperties struct { - Srcs []string `android:"path,arch_variant"` + // Name of the source soong module that gets shadowed by this prebuilt + // If unspecified, follows the naming convention that the source module of + // the prebuilt is Name() without "prebuilt_" prefix + Source_module_name *string + Srcs []string `android:"path,arch_variant"` } type prebuiltObjectLinker struct { @@ -351,6 +363,10 @@ func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt { return &p.Prebuilt } +func (p *prebuiltObjectLinker) sourceModuleName() string { + return proptools.String(p.properties.Source_module_name) +} + var _ prebuiltLinkerInterface = (*prebuiltObjectLinker)(nil) func (p *prebuiltObjectLinker) link(ctx ModuleContext, @@ -520,3 +536,7 @@ func srcsForSanitizer(sanitize *sanitize, sanitized Sanitized) []string { } return sanitized.None.Srcs } + +func (p *prebuiltLinker) sourceModuleName() string { + return proptools.String(p.properties.Source_module_name) +} diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go index 8b4174b52..95fb7edfb 100644 --- a/cc/prebuilt_test.go +++ b/cc/prebuilt_test.go @@ -15,6 +15,7 @@ package cc import ( + "fmt" "runtime" "testing" @@ -509,3 +510,100 @@ cc_prebuilt_binary { }` testCcError(t, `Android.bp:4:6: module "bintest" variant "android_arm64_armv8-a": srcs: multiple prebuilt source files`, bp) } + +func TestMultiplePrebuilts(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"], + } + // prebuilt "v2" + cc_prebuilt_library_shared { + name: "libbar.v2", + stem: "libbar", + source_module_name: "libbar", + srcs: ["libbar.so"], + } + + // 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 + }{ + { + desc: "Source library is selected using apex_contributions", + selectedDependencyName: "libbar", + expectedDependencyName: "libbar", + }, + { + desc: "Prebuilt library v1 is selected using apex_contributions", + selectedDependencyName: "prebuilt_libbar", + expectedDependencyName: "prebuilt_libbar", + }, + { + desc: "Prebuilt library v2 is selected using apex_contributions", + selectedDependencyName: "prebuilt_libbar.v2", + expectedDependencyName: "prebuilt_libbar.v2", + }, + } + + 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", + } + }), + ) + ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{ + "libbar.so": nil, + "crtx.o": nil, + }, preparer) + 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)) + + // check installation rules + // the selected soong module should be exported to make + libbar := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module() + android.AssertBoolEquals(t, fmt.Sprintf("dependency %s should be exported to make\n", expectedDependency), true, !libbar.IsHideFromMake()) + + // check LOCAL_MODULE of the selected module name + // the prebuilt should have the same LOCAL_MODULE when exported to make + entries := android.AndroidMkEntriesForTest(t, ctx, libbar)[0] + android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "libbar", entries.EntryMap["LOCAL_MODULE"][0]) + } +}