summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/platform_bootclasspath.go93
-rw-r--r--java/platform_bootclasspath_test.go101
-rw-r--r--java/testing.go31
3 files changed, 222 insertions, 3 deletions
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 550707754..5272eaf77 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -17,6 +17,7 @@ package java
import (
"android/soong/android"
"android/soong/dexpreopt"
+ "github.com/google/blueprint"
)
func init() {
@@ -25,10 +26,38 @@ func init() {
func registerPlatformBootclasspathBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("platform_bootclasspath", platformBootclasspathFactory)
+
+ ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("platform_bootclasspath_deps", platformBootclasspathDepsMutator)
+ })
+}
+
+type platformBootclasspathDependencyTag struct {
+ blueprint.BaseDependencyTag
+
+ name string
}
+// Avoid having to make platform bootclasspath content visible to the platform bootclasspath.
+//
+// This is a temporary workaround to make it easier to migrate to platform bootclasspath with proper
+// dependencies.
+// TODO(b/177892522): Remove this and add needed visibility.
+func (t platformBootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
+}
+
+// The tag used for the dependency between the platform bootclasspath and any configured boot jars.
+var platformBootclasspathModuleDepTag = platformBootclasspathDependencyTag{name: "module"}
+
+var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathDependencyTag{}
+
type platformBootclasspathModule struct {
android.ModuleBase
+
+ // The apex:module pairs obtained from the configured modules.
+ //
+ // Currently only for testing.
+ configuredModules []android.Module
}
func platformBootclasspathFactory() android.Module {
@@ -47,7 +76,71 @@ func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorCon
dexpreopt.RegisterToolDeps(ctx)
}
+func platformBootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
+ m := ctx.Module()
+ if p, ok := m.(*platformBootclasspathModule); ok {
+ // Add dependencies on all the modules configured in the "art" boot image.
+ artImageConfig := genBootImageConfigs(ctx)[artBootImageName]
+ addDependenciesOntoBootImageModules(ctx, artImageConfig.modules)
+
+ // Add dependencies on all the modules configured in the "boot" boot image. That does not
+ // include modules configured in the "art" boot image.
+ bootImageConfig := p.getImageConfig(ctx)
+ addDependenciesOntoBootImageModules(ctx, bootImageConfig.modules)
+
+ // Add dependencies on all the updatable modules.
+ updatableModules := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
+ addDependenciesOntoBootImageModules(ctx, updatableModules)
+ }
+}
+
+func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
+ var variations []blueprint.Variation
+ if apex != "platform" {
+ // Pick the correct apex variant.
+ variations = []blueprint.Variation{
+ {Mutator: "apex", Variation: apex},
+ }
+ }
+
+ addedDep := false
+ if ctx.OtherModuleDependencyVariantExists(variations, name) {
+ ctx.AddFarVariationDependencies(variations, tag, name)
+ addedDep = true
+ }
+
+ // Add a dependency on the prebuilt module if it exists.
+ prebuiltName := android.PrebuiltNameFromSource(name)
+ if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
+ ctx.AddVariationDependencies(variations, tag, prebuiltName)
+ addedDep = true
+ }
+
+ // If no appropriate variant existing for this, so no dependency could be added, then it is an
+ // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
+ // dependency that will not be satisfied and the default behavior will handle it.
+ if !addedDep {
+ ctx.AddFarVariationDependencies(variations, tag, name)
+ }
+}
+
+func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList) {
+ for i := 0; i < modules.Len(); i++ {
+ apex := modules.Apex(i)
+ name := modules.Jar(i)
+
+ addDependencyOntoApexModulePair(ctx, apex, name, platformBootclasspathModuleDepTag)
+ }
+}
+
func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
+ if tag == platformBootclasspathModuleDepTag {
+ b.configuredModules = append(b.configuredModules, module)
+ }
+ })
+
// Nothing to do if skipping the dexpreopt of boot image jars.
if SkipDexpreoptBootJars(ctx) {
return
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index 1c81cfdc2..ebbe3a5ee 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -29,10 +29,105 @@ var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
)
func TestPlatformBootclasspath(t *testing.T) {
- prepareForTestWithPlatformBootclasspath.
- RunTestWithBp(t, `
+ preparer := android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ dexpreopt.FixtureSetBootJars("platform:foo", "platform:bar"),
+ android.FixtureWithRootAndroidBp(`
platform_bootclasspath {
name: "platform-bootclasspath",
}
- `)
+
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ }
+ `),
+ )
+
+ var addSourceBootclassPathModule = android.FixtureAddTextFile("source/Android.bp", `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ }
+ `)
+
+ var addPrebuiltBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", `
+ java_import {
+ name: "foo",
+ jars: ["a.jar"],
+ compile_dex: true,
+ prefer: false,
+ }
+ `)
+
+ var addPrebuiltPreferredBootclassPathModule = android.FixtureAddTextFile("prebuilt/Android.bp", `
+ java_import {
+ name: "foo",
+ jars: ["a.jar"],
+ compile_dex: true,
+ prefer: true,
+ }
+ `)
+
+ t.Run("missing", func(t *testing.T) {
+ preparer.
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"platform-bootclasspath" depends on undefined module "foo"`)).
+ RunTest(t)
+ })
+
+ t.Run("source", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ preparer,
+ addSourceBootclassPathModule,
+ ).RunTest(t)
+
+ CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
+ "platform:foo",
+ "platform:bar",
+ })
+ })
+
+ t.Run("prebuilt", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ preparer,
+ addPrebuiltBootclassPathModule,
+ ).RunTest(t)
+
+ CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
+ "platform:prebuilt_foo",
+ "platform:bar",
+ })
+ })
+
+ t.Run("source+prebuilt - source preferred", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ preparer,
+ addSourceBootclassPathModule,
+ addPrebuiltBootclassPathModule,
+ ).RunTest(t)
+
+ CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
+ "platform:foo",
+ "platform:bar",
+ })
+ })
+
+ t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ preparer,
+ addSourceBootclassPathModule,
+ addPrebuiltPreferredBootclassPathModule,
+ ).RunTest(t)
+
+ CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
+ "platform:prebuilt_foo",
+ "platform:bar",
+ })
+ })
}
diff --git a/java/testing.go b/java/testing.go
index 80c107d12..455cca9dd 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -300,6 +300,37 @@ func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, varia
}
}
+// CheckPlatformBootclasspathModules returns the apex:module pair for the modules depended upon by
+// the platform-bootclasspath module.
+func CheckPlatformBootclasspathModules(t *testing.T, result *android.TestResult, name string, expected []string) {
+ t.Helper()
+ platformBootclasspath := result.Module(name, "android_common").(*platformBootclasspathModule)
+ pairs := ApexNamePairsFromModules(result.TestContext, platformBootclasspath.configuredModules)
+ android.AssertDeepEquals(t, fmt.Sprintf("%s modules", "platform-bootclasspath"), expected, pairs)
+}
+
+// ApexNamePairsFromModules returns the apex:module pair for the supplied modules.
+func ApexNamePairsFromModules(ctx *android.TestContext, modules []android.Module) []string {
+ pairs := []string{}
+ for _, module := range modules {
+ pairs = append(pairs, apexNamePairFromModule(ctx, module))
+ }
+ return pairs
+}
+
+func apexNamePairFromModule(ctx *android.TestContext, module android.Module) string {
+ name := module.Name()
+ var apex string
+ apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+ if apexInfo.IsForPlatform() {
+ apex = "platform"
+ } else {
+ apex = apexInfo.InApexes[0]
+ }
+
+ return fmt.Sprintf("%s:%s", apex, name)
+}
+
func CheckHiddenAPIRuleInputs(t *testing.T, expected string, hiddenAPIRule android.TestingBuildParams) {
t.Helper()
actual := strings.TrimSpace(strings.Join(android.NormalizePathsForTesting(hiddenAPIRule.Implicits), "\n"))