diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/platform_bootclasspath.go | 93 | ||||
-rw-r--r-- | java/platform_bootclasspath_test.go | 101 | ||||
-rw-r--r-- | java/testing.go | 31 |
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")) |