Split functions for compiling boot jars to allow future code reuse.

This CL adds no functional changes, it only splits a few functions into
parts that will be reused in a follow-up CL.

Bug: 178467404
Test: lunch aosp_cf_x86_64_phone-userdebug && m
Change-Id: I2bcb3c03d51175130da29fdfaf6dd747e3aea964
This commit is contained in:
Ulya Trafimovich 2021-03-22 12:37:10 +00:00
parent 3d5f6a1034
commit fa2b1cf1d8
1 changed files with 55 additions and 28 deletions

View File

@ -15,6 +15,7 @@
package java package java
import ( import (
"fmt"
"path/filepath" "path/filepath"
"sort" "sort"
"strings" "strings"
@ -449,46 +450,61 @@ func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonC
// be needed there too. // be needed there too.
// //
// TODO(b/177892522): Avoid having to perform this type of check or if necessary dedup it. // TODO(b/177892522): Avoid having to perform this type of check or if necessary dedup it.
func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, module android.Module) (int, android.Path) { func getBootJar(ctx android.SingletonContext, bootjars android.ConfiguredJarList,
module android.Module, fromWhere string) (int, android.Path, *android.ApexInfo) {
name := ctx.ModuleName(module) name := ctx.ModuleName(module)
// Strip a prebuilt_ prefix so that this can access the dex jar from a prebuilt module. // Strip a prebuilt_ prefix so that this can access the dex jar from a prebuilt module.
name = android.RemoveOptionalPrebuiltPrefix(name) name = android.RemoveOptionalPrebuiltPrefix(name)
// Ignore any module that is not listed in the boot image configuration. // Ignore any module that is not listed in the boot image configuration.
index := image.modules.IndexOfJar(name) index := bootjars.IndexOfJar(name)
if index == -1 { if index == -1 {
return -1, nil return -1, nil, nil
} }
// It is an error if a module configured in the boot image does not support accessing the dex jar. // It is an error if a module configured in the boot image does not support accessing the dex jar.
// This is safe because every module that has the same name has to have the same module type. // This is safe because every module that has the same name has to have the same module type.
jar, hasJar := module.(interface{ DexJarBuildPath() android.Path }) jar, hasJar := module.(interface{ DexJarBuildPath() android.Path })
if !hasJar { if !hasJar {
ctx.Errorf("module %q configured in boot image %q does not support accessing dex jar", module, image.name) ctx.Errorf("module %q %sdoes not support accessing dex jar", module, fromWhere)
return -1, nil return -1, nil, nil
} }
// It is also an error if the module is not an ApexModule. // It is also an error if the module is not an ApexModule.
if _, ok := module.(android.ApexModule); !ok { if _, ok := module.(android.ApexModule); !ok {
ctx.Errorf("module %q configured in boot image %q does not support being added to an apex", module, image.name) ctx.Errorf("module %q %sdoes not support being added to an apex", module, fromWhere)
return -1, nil return -1, nil, nil
} }
apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
// Now match the apex part of the boot image configuration. // Now match the apex part of the boot image configuration.
requiredApex := image.modules.Apex(index) requiredApex := bootjars.Apex(index)
if requiredApex == "platform" { if requiredApex == "platform" {
if len(apexInfo.InApexes) != 0 { if len(apexInfo.InApexes) != 0 {
// A platform variant is required but this is for an apex so ignore it. // A platform variant is required but this is for an apex so ignore it.
return -1, nil return -1, nil, nil
} }
} else if !apexInfo.InApexByBaseName(requiredApex) { } else if !apexInfo.InApexByBaseName(requiredApex) {
// An apex variant for a specific apex is required but this is the wrong apex. // An apex variant for a specific apex is required but this is the wrong apex.
return -1, nil, nil
}
return index, jar.DexJarBuildPath(), &apexInfo
}
// Inspect this module to see if it contains a bootclasspath dex jar from a given boot image.
func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, module android.Module) (int, android.Path) {
fromImage := fmt.Sprintf("configured in boot image %q ", image.name)
index, jarPath, apexInfo := getBootJar(ctx, image.modules, module, fromImage)
if index == -1 {
return -1, nil return -1, nil
} }
name := ctx.ModuleName(module)
// Check that this module satisfies any boot image specific constraints. // Check that this module satisfies any boot image specific constraints.
fromUpdatableApex := apexInfo.Updatable fromUpdatableApex := apexInfo.Updatable
@ -525,39 +541,40 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul
panic("unknown boot image: " + image.name) panic("unknown boot image: " + image.name)
} }
return index, jar.DexJarBuildPath() return index, jarPath
} }
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image. // Generate commands that will copy boot jars to predefined paths in the global config.
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig { func findAndCopyBootJars(ctx android.SingletonContext, bootjars android.ConfiguredJarList,
// Collect dex jar paths for the boot image modules. jarPathsPredefined android.WritablePaths,
getBootJar func(module android.Module) (int, android.Path)) []string {
// This logic is tested in the apex package to avoid import cycle apex <-> java. // This logic is tested in the apex package to avoid import cycle apex <-> java.
bootDexJars := make(android.Paths, image.modules.Len()) jarPaths := make(android.Paths, bootjars.Len())
ctx.VisitAllModules(func(module android.Module) { ctx.VisitAllModules(func(module android.Module) {
if !isActiveModule(module) { if !isActiveModule(module) {
return return
} }
if i, j := getBootJar(module); i != -1 {
if i, j := getBootImageJar(ctx, image, module); i != -1 { if existing := jarPaths[i]; existing != nil {
if existing := bootDexJars[i]; existing != nil { ctx.Errorf("Multiple dex jars found for %s:%s - %q and %q",
ctx.Errorf("Multiple dex jars found for %s:%s - %s and %s", bootjars.Apex(i), bootjars.Jar(i), existing, j)
image.modules.Apex(i), image.modules.Jar(i), existing, j)
return return
} }
jarPaths[i] = j
bootDexJars[i] = j
} }
}) })
var missingDeps []string var missingDeps []string
// Ensure all modules were converted to paths // Ensure all modules were converted to paths
for i := range bootDexJars { for i := range jarPaths {
if bootDexJars[i] == nil { if jarPaths[i] == nil {
m := image.modules.Jar(i) m := bootjars.Jar(i)
if ctx.Config().AllowMissingDependencies() { if ctx.Config().AllowMissingDependencies() {
missingDeps = append(missingDeps, m) missingDeps = append(missingDeps, m)
bootDexJars[i] = android.PathForOutput(ctx, "missing/module", m, "from/apex", image.modules.Apex(i)) jarPaths[i] = android.PathForOutput(ctx, "missing/module", m, "from/apex",
bootjars.Apex(i))
} else { } else {
ctx.Errorf("failed to find a dex jar path for module '%s'"+ ctx.Errorf("failed to find a dex jar path for module '%s'"+
", note that some jars may be filtered out by module constraints", m) ", note that some jars may be filtered out by module constraints", m)
@ -569,14 +586,24 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
// time, before the boot images are built (these paths are used in dexpreopt rule generation for // time, before the boot images are built (these paths are used in dexpreopt rule generation for
// Java libraries and apps). Generate rules that copy bootclasspath DEX jars to the predefined // Java libraries and apps). Generate rules that copy bootclasspath DEX jars to the predefined
// paths. // paths.
for i := range bootDexJars { for i := range jarPaths {
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: android.Cp, Rule: android.Cp,
Input: bootDexJars[i], Input: jarPaths[i],
Output: image.dexPaths[i], Output: jarPathsPredefined[i],
}) })
} }
return missingDeps
}
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
getBootJarFunc := func(module android.Module) (int, android.Path) {
return getBootImageJar(ctx, image, module)
}
missingDeps := findAndCopyBootJars(ctx, image.modules, image.dexPaths, getBootJarFunc)
profile := bootImageProfileRule(ctx, image, missingDeps) profile := bootImageProfileRule(ctx, image, missingDeps)
bootFrameworkProfileRule(ctx, image, missingDeps) bootFrameworkProfileRule(ctx, image, missingDeps)
updatableBcpPackagesRule(ctx, image, missingDeps) updatableBcpPackagesRule(ctx, image, missingDeps)