Merge "Add dependencies from platform_bootclasspath to contents"
This commit is contained in:
commit
d32118c5c4
5 changed files with 381 additions and 3 deletions
|
@ -31,6 +31,7 @@ bootstrap_go_package {
|
|||
testSrcs: [
|
||||
"apex_test.go",
|
||||
"boot_image_test.go",
|
||||
"platform_bootclasspath_test.go",
|
||||
"vndk_test.go",
|
||||
],
|
||||
pluginFor: ["soong_build"],
|
||||
|
|
158
apex/platform_bootclasspath_test.go
Normal file
158
apex/platform_bootclasspath_test.go
Normal file
|
@ -0,0 +1,158 @@
|
|||
// Copyright (C) 2021 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package apex
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/dexpreopt"
|
||||
"android/soong/java"
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
// Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires
|
||||
// apexes.
|
||||
|
||||
var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
|
||||
java.PrepareForTestWithDexpreopt,
|
||||
PrepareForTestWithApexBuildComponents,
|
||||
)
|
||||
|
||||
func TestPlatformBootclasspathDependencies(t *testing.T) {
|
||||
result := android.GroupFixturePreparers(
|
||||
prepareForTestWithPlatformBootclasspath,
|
||||
prepareForTestWithArtApex,
|
||||
prepareForTestWithMyapex,
|
||||
// Configure some libraries in the art and framework boot images.
|
||||
dexpreopt.FixtureSetArtBootJars("com.android.art:baz", "com.android.art:quuz"),
|
||||
dexpreopt.FixtureSetBootJars("platform:foo"),
|
||||
dexpreopt.FixtureSetUpdatableBootJars("myapex:bar"),
|
||||
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||
java.FixtureWithLastReleaseApis("foo"),
|
||||
).RunTestWithBp(t, `
|
||||
apex {
|
||||
name: "com.android.art",
|
||||
key: "com.android.art.key",
|
||||
bootclasspath_fragments: [
|
||||
"art-bootclasspath-fragment",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
|
||||
apex_key {
|
||||
name: "com.android.art.key",
|
||||
public_key: "com.android.art.avbpubkey",
|
||||
private_key: "com.android.art.pem",
|
||||
}
|
||||
|
||||
bootclasspath_fragment {
|
||||
name: "art-bootclasspath-fragment",
|
||||
apex_available: [
|
||||
"com.android.art",
|
||||
],
|
||||
contents: [
|
||||
"baz",
|
||||
"quuz",
|
||||
],
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "baz",
|
||||
apex_available: [
|
||||
"com.android.art",
|
||||
],
|
||||
srcs: ["b.java"],
|
||||
installable: true,
|
||||
}
|
||||
|
||||
// Add a java_import that is not preferred and so won't have an appropriate apex variant created
|
||||
// for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it.
|
||||
java_import {
|
||||
name: "baz",
|
||||
apex_available: [
|
||||
"com.android.art",
|
||||
],
|
||||
jars: ["b.jar"],
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "quuz",
|
||||
apex_available: [
|
||||
"com.android.art",
|
||||
],
|
||||
srcs: ["b.java"],
|
||||
installable: true,
|
||||
}
|
||||
|
||||
apex {
|
||||
name: "myapex",
|
||||
key: "myapex.key",
|
||||
java_libs: [
|
||||
"bar",
|
||||
],
|
||||
updatable: false,
|
||||
}
|
||||
|
||||
apex_key {
|
||||
name: "myapex.key",
|
||||
public_key: "testkey.avbpubkey",
|
||||
private_key: "testkey.pem",
|
||||
}
|
||||
|
||||
java_sdk_library {
|
||||
name: "foo",
|
||||
srcs: ["b.java"],
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "bar",
|
||||
srcs: ["b.java"],
|
||||
installable: true,
|
||||
apex_available: ["myapex"],
|
||||
permitted_packages: ["bar"],
|
||||
}
|
||||
|
||||
platform_bootclasspath {
|
||||
name: "myplatform-bootclasspath",
|
||||
}
|
||||
`,
|
||||
)
|
||||
|
||||
// Make sure that the myplatform-bootclasspath has the correct dependencies.
|
||||
CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
|
||||
`platform:dex2oatd`,
|
||||
`com.android.art:baz`,
|
||||
`com.android.art:quuz`,
|
||||
`platform:foo`,
|
||||
`myapex:bar`,
|
||||
})
|
||||
}
|
||||
|
||||
// CheckModuleDependencies checks the dependencies of the selected module against the expected list.
|
||||
//
|
||||
// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
|
||||
// name of the apex, or platform is it is not part of an apex and <module> is the module name.
|
||||
func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
|
||||
t.Helper()
|
||||
module := ctx.ModuleForTests(name, variant).Module()
|
||||
modules := []android.Module{}
|
||||
ctx.VisitDirectDeps(module, func(m blueprint.Module) {
|
||||
modules = append(modules, m.(android.Module))
|
||||
})
|
||||
|
||||
pairs := java.ApexNamePairsFromModules(ctx, modules)
|
||||
android.AssertDeepEquals(t, "module dependencies", expected, pairs)
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
|
|
Loading…
Reference in a new issue