diff --git a/java/androidmk.go b/java/androidmk.go index c86dcf4be..b5235940e 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -209,9 +209,10 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{} } return []android.AndroidMkEntries{android.AndroidMkEntries{ - Class: "JAVA_LIBRARIES", - OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile), - Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", + Class: "JAVA_LIBRARIES", + OverrideName: prebuilt.BaseModuleName(), + OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile), + Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", !Bool(prebuilt.properties.Installable)) diff --git a/java/java.go b/java/java.go index 8c56bd771..f806298bf 100644 --- a/java/java.go +++ b/java/java.go @@ -2090,6 +2090,11 @@ type ImportProperties struct { // that depend on this module, as well as to aidl for this module. 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 { @@ -2163,12 +2168,16 @@ func (j *Import) PrebuiltSrcs() []string { 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 { return j.prebuilt.Name(j.ModuleBase.Name()) } 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 { diff --git a/java/java_test.go b/java/java_test.go index 0891ab634..42301d866 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -24,6 +24,7 @@ import ( "strings" "testing" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" "android/soong/aconfig" @@ -2521,3 +2522,105 @@ func TestDisableFromTextStubForCoverageBuild(t *testing.T) { apiScopePublic.stubsLibraryModuleName("foo"), "android_common", 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]) + } +}