Support mechanism to select a specific version of module sdk prebuilt

This CL is the java_(test_)_import equivalent of aosp/2928483.

With trunk stable, we will have
multiple prebuilts of the prebuilt java .jars in
prebuilts/module_sdk/art/<v>/test-exports/, and this CL introduces a
mechanism to use apex_contributions to select a specific versioned
prebuilt when building.

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: I2dff38acdf2002355586dbb2be8c1f98af4741f7
This commit is contained in:
Spandan Das
2024-01-19 00:22:22 +00:00
parent 2b6dfb554d
commit 3cf0463a47
3 changed files with 117 additions and 4 deletions

View File

@@ -209,9 +209,10 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{} return []android.AndroidMkEntries{}
} }
return []android.AndroidMkEntries{android.AndroidMkEntries{ return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES", Class: "JAVA_LIBRARIES",
OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile), OverrideName: prebuilt.BaseModuleName(),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable)) entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable))

View File

@@ -2089,6 +2089,11 @@ type ImportProperties struct {
// that depend on this module, as well as to aidl for this module. // that depend on this module, as well as to aidl for this module.
Export_include_dirs []string Export_include_dirs []string
} }
// 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
} }
type Import struct { type Import struct {
@@ -2162,12 +2167,16 @@ func (j *Import) PrebuiltSrcs() []string {
return j.properties.Jars return j.properties.Jars
} }
func (j *Import) BaseModuleName() string {
return proptools.StringDefault(j.properties.Source_module_name, j.ModuleBase.Name())
}
func (j *Import) Name() string { func (j *Import) Name() string {
return j.prebuilt.Name(j.ModuleBase.Name()) return j.prebuilt.Name(j.ModuleBase.Name())
} }
func (j *Import) Stem() string { func (j *Import) Stem() string {
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) return proptools.StringDefault(j.properties.Stem, j.BaseModuleName())
} }
func (a *Import) JacocoReportClassesFile() android.Path { func (a *Import) JacocoReportClassesFile() android.Path {

View File

@@ -24,6 +24,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
"android/soong/aconfig" "android/soong/aconfig"
@@ -2521,3 +2522,105 @@ func TestDisableFromTextStubForCoverageBuild(t *testing.T) {
apiScopePublic.stubsLibraryModuleName("foo"), "android_common", apiScopePublic.stubsLibraryModuleName("foo"), "android_common",
apiScopePublic.apiLibraryModuleName("foo"))) apiScopePublic.apiLibraryModuleName("foo")))
} }
func TestMultiplePrebuilts(t *testing.T) {
bp := `
// an rdep
java_library {
name: "foo",
libs: ["bar"],
}
// multiple variations of dep
// source
java_library {
name: "bar",
srcs: ["bar.java"],
}
// prebuilt "v1"
java_import {
name: "bar",
jars: ["bar.jar"],
}
// prebuilt "v2"
java_import {
name: "bar.v2",
source_module_name: "bar",
jars: ["bar.v1.jar"],
}
// selectors
apex_contributions {
name: "myapex_contributions",
contents: ["%v"],
}
`
hasDep := func(ctx *android.TestResult, 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
}
hasFileWithStem := func(m android.TestingModule, stem string) bool {
t.Helper()
for _, o := range m.AllOutputs() {
_, file := filepath.Split(o)
if file == stem+".jar" {
return true
}
}
return false
}
testCases := []struct {
desc string
selectedDependencyName string
expectedDependencyName string
}{
{
desc: "Source library is selected using apex_contributions",
selectedDependencyName: "bar",
expectedDependencyName: "bar",
},
{
desc: "Prebuilt library v1 is selected using apex_contributions",
selectedDependencyName: "prebuilt_bar",
expectedDependencyName: "prebuilt_bar",
},
{
desc: "Prebuilt library v2 is selected using apex_contributions",
selectedDependencyName: "prebuilt_bar.v2",
expectedDependencyName: "prebuilt_bar.v2",
},
}
for _, tc := range testCases {
ctx := android.GroupFixturePreparers(
prepareForJavaTest,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.BuildFlags = map[string]string{
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions",
}
}),
).RunTestWithBp(t, fmt.Sprintf(bp, tc.selectedDependencyName))
// check that rdep gets the correct variation of dep
foo := ctx.ModuleForTests("foo", "android_common")
expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_common")
android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", foo.Module().Name(), tc.expectedDependencyName), true, hasDep(ctx, foo.Module(), expectedDependency.Module()))
// check that output file of dep is always bar.jar
// The filename should be agnostic to source/prebuilt/prebuilt_version
android.AssertBoolEquals(t, fmt.Sprintf("could not find bar.jar in outputs of %s. All Outputs %v\n", tc.expectedDependencyName, expectedDependency.AllOutputs()), true, hasFileWithStem(expectedDependency, "bar"))
// 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.TestContext, expectedDependency.Module())[0]
android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "bar", entries.EntryMap["LOCAL_MODULE"][0])
}
}