Use the correct bootjars for hiddneapi when multiple prebuilts exist am: 64c9e0ce6e

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2889086

Change-Id: I3a8f5751962ddd8a8036099c42071b13e8223a72
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Spandan Das
2024-01-02 19:27:04 +00:00
committed by Automerger Merge Worker
5 changed files with 80 additions and 16 deletions

View File

@@ -11436,6 +11436,20 @@ func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) {
}
}
// Check that the boot jars of the selected apex are run through boot_jars_package_check
// This validates that the jars on the bootclasspath do not contain packages outside an allowlist
checkBootJarsPackageCheck := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) {
platformBcp := ctx.ModuleForTests("platform-bootclasspath", "android_common")
bootJarsCheckRule := platformBcp.Rule("boot_jars_package_check")
android.AssertStringMatches(t, "Could not find the correct boot dex jar in package check rule", bootJarsCheckRule.RuleParams.Command, "build/soong/scripts/check_boot_jars/package_allowed_list.txt.*"+expectedBootJar)
}
// Check that the boot jars used to generate the monolithic hiddenapi flags come from the selected apex
checkBootJarsForMonolithicHiddenapi := func(t *testing.T, ctx *android.TestContext, expectedBootJar string) {
monolithicHiddenapiFlagsCmd := ctx.ModuleForTests("platform-bootclasspath", "android_common").Output("out/soong/hiddenapi/hiddenapi-stub-flags.txt").RuleParams.Command
android.AssertStringMatches(t, "Could not find the correct boot dex jar in monolithic hiddenapi flags generation command", monolithicHiddenapiFlagsCmd, "--boot-dex="+expectedBootJar)
}
bp := `
// Source APEX.
@@ -11575,5 +11589,7 @@ func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) {
)
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
checkBootDexJarPath(t, ctx, "framework-foo", tc.expectedBootJar)
checkBootJarsPackageCheck(t, ctx, tc.expectedBootJar)
checkBootJarsForMonolithicHiddenapi(t, ctx, tc.expectedBootJar)
}
}

View File

@@ -382,6 +382,9 @@ func TestPlatformBootclasspathDependencies(t *testing.T) {
// Make sure that the myplatform-bootclasspath has the correct dependencies.
CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
// source vs prebuilt selection metadata module
`platform:all_apex_contributions`,
// The following are stubs.
`platform:android_stubs_current`,
`platform:android_system_stubs_current`,
@@ -534,6 +537,9 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
// Make sure that the myplatform-bootclasspath has the correct dependencies.
CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
// source vs prebuilt selection metadata module
`platform:all_apex_contributions`,
// The following are stubs.
"platform:prebuilt_sdk_public_current_android",
"platform:prebuilt_sdk_system_current_android",

View File

@@ -699,28 +699,40 @@ func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig)
// extractEncodedDexJarsFromModulesOrBootclasspathFragments gets the hidden API encoded dex jars for
// the given modules.
func extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx android.ModuleContext, apexJarModulePairs []apexJarModulePair) bootDexJarByModule {
apexNameToBcpInfoMap := getApexNameToBcpInfoMap(ctx)
apexNameToApexExportInfoMap := getApexNameToApexExportsInfoMap(ctx)
encodedDexJarsByModuleName := bootDexJarByModule{}
for _, pair := range apexJarModulePairs {
dexJarPath := getDexJarForApex(ctx, pair, apexNameToBcpInfoMap)
dexJarPath := getDexJarForApex(ctx, pair, apexNameToApexExportInfoMap)
encodedDexJarsByModuleName.addPath(pair.jarModule, dexJarPath)
}
return encodedDexJarsByModuleName
}
type apexNameToApexExportsInfoMap map[string]android.ApexExportsInfo
// javaLibraryPathOnHost returns the path to the java library which is exported by the apex for hiddenapi and dexpreopt and a boolean indicating whether the java library exists
// For prebuilt apexes, this is created by deapexing the prebuilt apex
func (m *apexNameToApexExportsInfoMap) javaLibraryDexPathOnHost(ctx android.ModuleContext, apex string, javalib string) (android.Path, bool) {
if info, exists := (*m)[apex]; exists {
if dex, exists := info.LibraryNameToDexJarPathOnHost[javalib]; exists {
return dex, true
} else {
ctx.ModuleErrorf("Apex %s does not provide a dex boot jar for library %s\n", apex, javalib)
}
}
// An apex entry could not be found. Return false.
// TODO: b/308174306 - When all the mainline modules have been flagged, make this a hard error
return nil, false
}
// Returns the java libraries exported by the apex for hiddenapi and dexpreopt
// This information can come from two mechanisms
// 1. New: Direct deps to _selected_ apexes. The apexes return a ApexExportsInfo
// 2. Legacy: An edge to java_library or java_import (java_sdk_library) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToBcpInfoMap map[string]android.ApexExportsInfo) android.Path {
if info, exists := apexNameToBcpInfoMap[pair.apex]; exists {
libraryName := android.RemoveOptionalPrebuiltPrefix(pair.jarModule.Name())
if dex, exists := info.LibraryNameToDexJarPathOnHost[libraryName]; exists {
func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToApexExportsInfoMap apexNameToApexExportsInfoMap) android.Path {
if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, android.RemoveOptionalPrebuiltPrefix(pair.jarModule.Name())); found {
return dex
} else {
ctx.ModuleErrorf("Apex %s does not provide a dex boot jar for library %s\n", pair.apex, libraryName)
}
}
// TODO: b/308174306 - Remove the legacy mechanism
if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) {
@@ -900,14 +912,14 @@ func getProfilePathForApex(ctx android.ModuleContext, apexName string, apexNameT
return fragment.(commonBootclasspathFragment).getProfilePath()
}
func getApexNameToBcpInfoMap(ctx android.ModuleContext) map[string]android.ApexExportsInfo {
apexNameToBcpInfoMap := map[string]android.ApexExportsInfo{}
func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap {
apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{}
ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(am android.Module) {
if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists {
apexNameToBcpInfoMap[info.ApexName] = info
apexNameToApexExportsInfoMap[info.ApexName] = info
}
})
return apexNameToBcpInfoMap
return apexNameToApexExportsInfoMap
}
// Generate boot image build rules for a specific target.
@@ -952,7 +964,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
apexNameToBcpInfoMap := getApexNameToBcpInfoMap(ctx)
apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx)
cmd.Tool(globalSoong.Dex2oat).
Flag("--avoid-storing-invocation").
@@ -966,7 +978,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
}
for _, apex := range image.profileImports {
importedProfile := getProfilePathForApex(ctx, apex, apexNameToBcpInfoMap)
importedProfile := getProfilePathForApex(ctx, apex, apexNameToApexExportsInfoMap)
if importedProfile == nil {
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
"doesn't provide a profile",

View File

@@ -19,6 +19,7 @@ import (
"strings"
"android/soong/android"
"android/soong/dexpreopt"
"github.com/google/blueprint"
)
@@ -1250,9 +1251,27 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix s
}
// extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules.
// This information can come from two mechanisms
// 1. New: Direct deps to _selected_ apexes. The apexes contain a ApexExportsInfo
// 2. Legacy: An edge to java_sdk_library(_import) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes
// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2)
func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
bootDexJars := bootDexJarByModule{}
apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx)
// For ART and mainline module jars, query apexNameToApexExportsInfoMap to get the dex file
apexJars := dexpreopt.GetGlobalConfig(ctx).ArtApexJars.AppendList(&dexpreopt.GetGlobalConfig(ctx).ApexBootJars)
for i := 0; i < apexJars.Len(); i++ {
if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, apexJars.Apex(i), apexJars.Jar(i)); found {
bootDexJars[apexJars.Jar(i)] = dex
}
}
// TODO - b/308174306: Drop the legacy mechanism
for _, module := range contents {
if _, exists := bootDexJars[android.RemoveOptionalPrebuiltPrefix(module.Name())]; exists {
continue
}
hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module)
if hiddenAPIModule == nil {
continue

View File

@@ -106,6 +106,9 @@ func (b *platformBootclasspathModule) OutputFiles(tag string) (android.Paths, er
}
func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
// Create a dependency on all_apex_contributions to determine the selected mainline module
ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions")
b.hiddenAPIDepsMutator(ctx)
if !dexpreopt.IsDex2oatNeeded(ctx) {
@@ -130,6 +133,8 @@ func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpM
func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies on all the ART jars.
global := dexpreopt.GetGlobalConfig(ctx)
addDependenciesOntoSelectedBootImageApexes(ctx, "com.android.art")
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag)
// Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable
@@ -138,6 +143,12 @@ func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.Botto
// Add dependencies on all the updatable jars, except the ART jars.
apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
apexes := []string{}
for i := 0; i < apexJars.Len(); i++ {
apexes = append(apexes, apexJars.Apex(i))
}
addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...)
// TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly
addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
// Add dependencies on all the fragments.