Use boot image extension for framework libraries. am: 4d2eeed0da
am: c641b9e722
Change-Id: I7ec291d2e995604ed5201887a0662e2b65b862fe
This commit is contained in:
@@ -247,6 +247,33 @@ func PathsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) Path
|
||||
return ret
|
||||
}
|
||||
|
||||
// OutputPaths is a slice of OutputPath objects, with helpers to operate on the collection.
|
||||
type OutputPaths []OutputPath
|
||||
|
||||
// Paths returns the OutputPaths as a Paths
|
||||
func (p OutputPaths) Paths() Paths {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
ret := make(Paths, len(p))
|
||||
for i, path := range p {
|
||||
ret[i] = path
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Strings returns the string forms of the writable paths.
|
||||
func (p OutputPaths) Strings() []string {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
ret := make([]string, len(p))
|
||||
for i, path := range p {
|
||||
ret[i] = path.String()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// PathsAndMissingDepsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding
|
||||
// paths listed in the excludes arguments, and a list of missing dependencies. It expands globs, references to
|
||||
// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the
|
||||
|
@@ -41,7 +41,7 @@ type GlobalConfig struct {
|
||||
BootJars []string // modules for jars that form the boot class path
|
||||
UpdatableBootJars []string // jars within apex that form the boot class path
|
||||
|
||||
ArtApexJars []string // modules for jars that are in the ART APEX
|
||||
ArtApexJars []string // modules for jars that are in the ART APEX
|
||||
|
||||
SystemServerJars []string // jars that form the system server
|
||||
SystemServerApps []string // apps that are loaded into system server
|
||||
@@ -117,9 +117,10 @@ type ModuleConfig struct {
|
||||
UsesLibraries []string
|
||||
LibraryPaths map[string]android.Path
|
||||
|
||||
Archs []android.ArchType
|
||||
DexPreoptImages []android.Path
|
||||
DexPreoptImagesDeps []android.Paths
|
||||
Archs []android.ArchType
|
||||
DexPreoptImages []android.Path
|
||||
DexPreoptImagesDeps []android.OutputPaths
|
||||
DexPreoptImageLocations []string
|
||||
|
||||
PreoptBootClassPathDexFiles android.Paths // file paths of boot class path files
|
||||
PreoptBootClassPathDexLocations []string // virtual locations of boot class path files
|
||||
@@ -225,6 +226,7 @@ func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error
|
||||
ProfileClassListing string
|
||||
LibraryPaths map[string]string
|
||||
DexPreoptImages []string
|
||||
DexPreoptImageLocations []string
|
||||
PreoptBootClassPathDexFiles []string
|
||||
}
|
||||
|
||||
@@ -242,10 +244,11 @@ func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error
|
||||
config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing))
|
||||
config.ModuleConfig.LibraryPaths = constructPathMap(ctx, config.LibraryPaths)
|
||||
config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
|
||||
config.ModuleConfig.DexPreoptImageLocations = config.DexPreoptImageLocations
|
||||
config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
|
||||
|
||||
// This needs to exist, but dependencies are already handled in Make, so we don't need to pass them through JSON.
|
||||
config.ModuleConfig.DexPreoptImagesDeps = make([]android.Paths, len(config.ModuleConfig.DexPreoptImages))
|
||||
config.ModuleConfig.DexPreoptImagesDeps = make([]android.OutputPaths, len(config.ModuleConfig.DexPreoptImages))
|
||||
|
||||
return config.ModuleConfig, nil
|
||||
}
|
||||
|
@@ -86,10 +86,8 @@ func GenerateDexpreoptRule(ctx android.PathContext,
|
||||
|
||||
generateDM := shouldGenerateDM(module, global)
|
||||
|
||||
for i, arch := range module.Archs {
|
||||
image := module.DexPreoptImages[i]
|
||||
imageDeps := module.DexPreoptImagesDeps[i]
|
||||
dexpreoptCommand(ctx, global, module, rule, arch, profile, image, imageDeps, appImage, generateDM)
|
||||
for archIdx, _ := range module.Archs {
|
||||
dexpreoptCommand(ctx, global, module, rule, archIdx, profile, appImage, generateDM)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -193,7 +191,9 @@ func bootProfileCommand(ctx android.PathContext, global GlobalConfig, module Mod
|
||||
}
|
||||
|
||||
func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module ModuleConfig, rule *android.RuleBuilder,
|
||||
arch android.ArchType, profile, bootImage android.Path, bootImageDeps android.Paths, appImage, generateDM bool) {
|
||||
archIdx int, profile android.WritablePath, appImage bool, generateDM bool) {
|
||||
|
||||
arch := module.Archs[archIdx]
|
||||
|
||||
// HACK: make soname in Soong-generated .odex files match Make.
|
||||
base := filepath.Base(module.DexLocation)
|
||||
@@ -222,13 +222,6 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
||||
|
||||
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
|
||||
|
||||
// bootImage is .../dex_bootjars/system/framework/arm64/boot.art, but dex2oat wants
|
||||
// .../dex_bootjars/system/framework/boot.art on the command line
|
||||
var bootImageLocation string
|
||||
if bootImage != nil {
|
||||
bootImageLocation = PathToLocation(bootImage, arch)
|
||||
}
|
||||
|
||||
// The class loader context using paths in the build
|
||||
var classLoaderContextHost android.Paths
|
||||
|
||||
@@ -356,7 +349,7 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
||||
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":").
|
||||
Flag("${class_loader_context_arg}").
|
||||
Flag("${stored_class_loader_context_arg}").
|
||||
FlagWithArg("--boot-image=", bootImageLocation).Implicits(bootImageDeps).
|
||||
FlagWithArg("--boot-image=", strings.Join(module.DexPreoptImageLocations, ":")).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()).
|
||||
FlagWithInput("--dex-file=", module.DexPath).
|
||||
FlagWithArg("--dex-location=", dexLocationArg).
|
||||
FlagWithOutput("--oat-file=", odexPath).ImplicitOutput(vdexPath).
|
||||
@@ -554,9 +547,9 @@ func SplitApexJarPair(apexJarValue string) (string, string) {
|
||||
}
|
||||
|
||||
// Expected format for apexJarValue = <apex name>:<jar name>
|
||||
func GetJarLocationFromApexJarPair(apexJarValue string) (string) {
|
||||
func GetJarLocationFromApexJarPair(apexJarValue string) string {
|
||||
apex, jar := SplitApexJarPair(apexJarValue)
|
||||
return filepath.Join("/apex", apex, "javalib", jar + ".jar")
|
||||
return filepath.Join("/apex", apex, "javalib", jar+".jar")
|
||||
}
|
||||
|
||||
func contains(l []string, s string) bool {
|
||||
|
@@ -49,7 +49,8 @@ func testModuleConfig(ctx android.PathContext, name, partition string) ModuleCon
|
||||
LibraryPaths: nil,
|
||||
Archs: []android.ArchType{android.Arm},
|
||||
DexPreoptImages: android.Paths{android.PathForTesting("system/framework/arm/boot.art")},
|
||||
DexPreoptImagesDeps: []android.Paths{android.Paths{}},
|
||||
DexPreoptImagesDeps: []android.OutputPaths{android.OutputPaths{}},
|
||||
DexPreoptImageLocations: []string{},
|
||||
PreoptBootClassPathDexFiles: nil,
|
||||
PreoptBootClassPathDexLocations: nil,
|
||||
PreoptExtractedApk: false,
|
||||
|
@@ -124,7 +124,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
||||
}
|
||||
|
||||
var images android.Paths
|
||||
var imagesDeps []android.Paths
|
||||
var imagesDeps []android.OutputPaths
|
||||
for _, arch := range archs {
|
||||
images = append(images, bootImage.images[arch])
|
||||
imagesDeps = append(imagesDeps, bootImage.imagesDeps[arch])
|
||||
@@ -169,15 +169,16 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
||||
UsesLibraries: d.usesLibs,
|
||||
LibraryPaths: d.libraryPaths,
|
||||
|
||||
Archs: archs,
|
||||
DexPreoptImages: images,
|
||||
DexPreoptImagesDeps: imagesDeps,
|
||||
Archs: archs,
|
||||
DexPreoptImages: images,
|
||||
DexPreoptImagesDeps: imagesDeps,
|
||||
DexPreoptImageLocations: bootImage.imageLocations,
|
||||
|
||||
// We use the dex paths and dex locations of the default boot image, as it
|
||||
// contains the full dexpreopt boot classpath. Other images may just contain a subset of
|
||||
// the dexpreopt boot classpath.
|
||||
PreoptBootClassPathDexFiles: defaultBootImage.dexPaths.Paths(),
|
||||
PreoptBootClassPathDexLocations: defaultBootImage.dexLocations,
|
||||
PreoptBootClassPathDexFiles: defaultBootImage.dexPathsDeps.Paths(),
|
||||
PreoptBootClassPathDexLocations: defaultBootImage.dexLocationsDeps,
|
||||
|
||||
PreoptExtractedApk: false,
|
||||
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"android/soong/android"
|
||||
"android/soong/dexpreopt"
|
||||
|
||||
"github.com/google/blueprint/pathtools"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
@@ -50,38 +49,77 @@ func init() {
|
||||
// will then reconstruct the real path, so the rules must have a dependency on the real path.
|
||||
|
||||
type bootImageConfig struct {
|
||||
name string
|
||||
stem string
|
||||
modules []string
|
||||
dexLocations []string
|
||||
dexPaths android.WritablePaths
|
||||
dir android.OutputPath
|
||||
symbolsDir android.OutputPath
|
||||
targets []android.Target
|
||||
images map[android.ArchType]android.OutputPath
|
||||
imagesDeps map[android.ArchType]android.Paths
|
||||
zip android.WritablePath
|
||||
// Whether this image is an extension.
|
||||
extension bool
|
||||
|
||||
// Image name (used in directory names and ninja rule names).
|
||||
name string
|
||||
|
||||
// Basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}.
|
||||
stem string
|
||||
|
||||
// Output directory for the image files.
|
||||
dir android.OutputPath
|
||||
|
||||
// Output directory for the image files with debug symbols.
|
||||
symbolsDir android.OutputPath
|
||||
|
||||
// Subdirectory where the image files are installed.
|
||||
installSubdir string
|
||||
|
||||
// Targets for which the image is generated.
|
||||
targets []android.Target
|
||||
|
||||
// The names of jars that constitute this image.
|
||||
modules []string
|
||||
|
||||
// The "locations" of jars.
|
||||
dexLocations []string // for this image
|
||||
dexLocationsDeps []string // for the dependency images and in this image
|
||||
|
||||
// File paths to jars.
|
||||
dexPaths android.WritablePaths // for this image
|
||||
dexPathsDeps android.WritablePaths // for the dependency images and in this image
|
||||
|
||||
// The "locations" of the dependency images and in this image.
|
||||
imageLocations []string
|
||||
|
||||
// Paths to image files (grouped by target).
|
||||
images map[android.ArchType]android.OutputPath // first image file
|
||||
imagesDeps map[android.ArchType]android.OutputPaths // all files
|
||||
|
||||
// File path to a zip archive with all image files (or nil, if not needed).
|
||||
zip android.WritablePath
|
||||
}
|
||||
|
||||
func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) []android.OutputPath {
|
||||
ret := make([]android.OutputPath, 0, len(image.modules)*len(exts))
|
||||
|
||||
// dex preopt on the bootclasspath produces multiple files. The first dex file
|
||||
// is converted into to 'name'.art (to match the legacy assumption that 'name'.art
|
||||
func (image bootImageConfig) moduleName(idx int) string {
|
||||
// Dexpreopt on the boot class path produces multiple files. The first dex file
|
||||
// is converted into 'name'.art (to match the legacy assumption that 'name'.art
|
||||
// exists), and the rest are converted to 'name'-<jar>.art.
|
||||
// In addition, each .art file has an associated .oat and .vdex file, and an
|
||||
// unstripped .oat file
|
||||
for i, m := range image.modules {
|
||||
name := image.stem
|
||||
if i != 0 {
|
||||
name += "-" + stemOf(m)
|
||||
}
|
||||
m := image.modules[idx]
|
||||
name := image.stem
|
||||
if idx != 0 || image.extension {
|
||||
name += "-" + stemOf(m)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (image bootImageConfig) firstModuleNameOrStem() string {
|
||||
if len(image.modules) > 0 {
|
||||
return image.moduleName(0)
|
||||
} else {
|
||||
return image.stem
|
||||
}
|
||||
}
|
||||
|
||||
func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) android.OutputPaths {
|
||||
ret := make(android.OutputPaths, 0, len(image.modules)*len(exts))
|
||||
for i := range image.modules {
|
||||
name := image.moduleName(i)
|
||||
for _, ext := range exts {
|
||||
ret = append(ret, dir.Join(ctx, name+ext))
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -140,12 +178,6 @@ func skipDexpreoptBootJars(ctx android.PathContext) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func skipDexpreoptArtBootJars(ctx android.BuilderContext) bool {
|
||||
// with EMMA_INSTRUMENT_FRAMEWORK=true ART boot class path libraries have dependencies on framework,
|
||||
// therefore dexpreopt ART libraries cannot be dexpreopted in isolation => no ART boot image
|
||||
return ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK")
|
||||
}
|
||||
|
||||
type dexpreoptBootJars struct {
|
||||
defaultBootImage *bootImage
|
||||
otherImages []*bootImage
|
||||
@@ -154,8 +186,8 @@ type dexpreoptBootJars struct {
|
||||
}
|
||||
|
||||
// Accessor function for the apex package. Returns nil if dexpreopt is disabled.
|
||||
func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.Paths {
|
||||
if skipDexpreoptBootJars(ctx) || skipDexpreoptArtBootJars(ctx) {
|
||||
func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.OutputPaths {
|
||||
if skipDexpreoptBootJars(ctx) {
|
||||
return nil
|
||||
}
|
||||
return artBootImageConfig(ctx).imagesDeps
|
||||
@@ -184,10 +216,8 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
|
||||
// Always create the default boot image first, to get a unique profile rule for all images.
|
||||
d.defaultBootImage = buildBootImage(ctx, defaultBootImageConfig(ctx))
|
||||
if !skipDexpreoptArtBootJars(ctx) {
|
||||
// Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
|
||||
buildBootImage(ctx, artBootImageConfig(ctx))
|
||||
}
|
||||
// Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
|
||||
buildBootImage(ctx, artBootImageConfig(ctx))
|
||||
if global.GenerateApexImage {
|
||||
// Create boot images for the JIT-zygote experiment.
|
||||
d.otherImages = append(d.otherImages, buildBootImage(ctx, apexBootImageConfig(ctx)))
|
||||
@@ -201,7 +231,6 @@ func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootI
|
||||
image := newBootImage(ctx, config)
|
||||
|
||||
bootDexJars := make(android.Paths, len(image.modules))
|
||||
|
||||
ctx.VisitAllModules(func(module android.Module) {
|
||||
// Collect dex jar paths for the modules listed above.
|
||||
if j, ok := module.(interface{ DexJar() android.Path }); ok {
|
||||
@@ -265,11 +294,12 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
|
||||
|
||||
global := dexpreoptGlobalConfig(ctx)
|
||||
|
||||
symbolsDir := image.symbolsDir.Join(ctx, "system/framework", arch.String())
|
||||
symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String())
|
||||
symbolsFile := symbolsDir.Join(ctx, image.stem+".oat")
|
||||
outputDir := image.dir.Join(ctx, "system/framework", arch.String())
|
||||
outputPath := image.images[arch]
|
||||
oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath, arch), "oat")
|
||||
outputDir := image.dir.Join(ctx, image.installSubdir, arch.String())
|
||||
outputPath := outputDir.Join(ctx, image.stem+".oat")
|
||||
oatLocation := dexpreopt.PathToLocation(outputPath, arch)
|
||||
imagePath := outputPath.ReplaceExtension(ctx, "art")
|
||||
|
||||
rule := android.NewRuleBuilder()
|
||||
rule.MissingDeps(missingDeps)
|
||||
@@ -312,18 +342,27 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
|
||||
cmd.FlagWithInput("--dirty-image-objects=", global.DirtyImageObjects.Path())
|
||||
}
|
||||
|
||||
if image.extension {
|
||||
artImage := artBootImageConfig(ctx).images[arch]
|
||||
cmd.
|
||||
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
|
||||
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":").
|
||||
FlagWithArg("--boot-image=", dexpreopt.PathToLocation(artImage, arch)).Implicit(artImage)
|
||||
} else {
|
||||
cmd.FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress())
|
||||
}
|
||||
|
||||
cmd.
|
||||
FlagForEachInput("--dex-file=", image.dexPaths.Paths()).
|
||||
FlagForEachArg("--dex-location=", image.dexLocations).
|
||||
Flag("--generate-debug-info").
|
||||
Flag("--generate-build-id").
|
||||
Flag("--image-format=lz4hc").
|
||||
FlagWithOutput("--oat-symbols=", symbolsFile).
|
||||
FlagWithArg("--oat-symbols=", symbolsFile.String()).
|
||||
Flag("--strip").
|
||||
FlagWithOutput("--oat-file=", outputPath.ReplaceExtension(ctx, "oat")).
|
||||
FlagWithArg("--oat-file=", outputPath.String()).
|
||||
FlagWithArg("--oat-location=", oatLocation).
|
||||
FlagWithOutput("--image=", outputPath).
|
||||
FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress()).
|
||||
FlagWithArg("--image=", imagePath.String()).
|
||||
FlagWithArg("--instruction-set=", arch.String()).
|
||||
FlagWithArg("--instruction-set-variant=", global.CpuVariant[arch]).
|
||||
FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch]).
|
||||
@@ -341,8 +380,8 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
|
||||
|
||||
cmd.Textf(`|| ( echo %s ; false )`, proptools.ShellEscape(failureMessage))
|
||||
|
||||
installDir := filepath.Join("/system/framework", arch.String())
|
||||
vdexInstallDir := filepath.Join("/system/framework")
|
||||
installDir := filepath.Join("/", image.installSubdir, arch.String())
|
||||
vdexInstallDir := filepath.Join("/", image.installSubdir)
|
||||
|
||||
var vdexInstalls android.RuleBuilderInstalls
|
||||
var unstrippedInstalls android.RuleBuilderInstalls
|
||||
@@ -425,8 +464,8 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missin
|
||||
Text(`ANDROID_LOG_TAGS="*:e"`).
|
||||
Tool(tools.Profman).
|
||||
FlagWithInput("--create-profile-from=", bootImageProfile).
|
||||
FlagForEachInput("--apk=", image.dexPaths.Paths()).
|
||||
FlagForEachArg("--dex-location=", image.dexLocations).
|
||||
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
|
||||
FlagForEachArg("--dex-location=", image.dexLocationsDeps).
|
||||
FlagWithOutput("--reference-profile-file=", profile)
|
||||
|
||||
rule.Install(profile, "/system/etc/boot-image.prof")
|
||||
@@ -477,8 +516,8 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, mi
|
||||
Tool(tools.Profman).
|
||||
Flag("--generate-boot-profile").
|
||||
FlagWithInput("--create-profile-from=", bootFrameworkProfile).
|
||||
FlagForEachInput("--apk=", image.dexPaths.Paths()).
|
||||
FlagForEachArg("--dex-location=", image.dexLocations).
|
||||
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
|
||||
FlagForEachArg("--dex-location=", image.dexLocationsDeps).
|
||||
FlagWithOutput("--reference-profile-file=", profile)
|
||||
|
||||
rule.Install(profile, "/system/etc/boot-image.bprof")
|
||||
@@ -506,8 +545,8 @@ func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
|
||||
rule.Command().
|
||||
// TODO: for now, use the debug version for better error reporting
|
||||
BuiltTool(ctx, "oatdumpd").
|
||||
FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPaths.Paths(), ":").
|
||||
FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocations, ":").
|
||||
FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
|
||||
FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
|
||||
FlagWithArg("--image=", dexpreopt.PathToLocation(image.images[arch], arch)).Implicit(image.images[arch]).
|
||||
FlagWithOutput("--output=", output).
|
||||
FlagWithArg("--instruction-set=", arch.String())
|
||||
@@ -556,8 +595,9 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
|
||||
image := d.defaultBootImage
|
||||
if image != nil {
|
||||
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
|
||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPaths.Strings(), " "))
|
||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocations, " "))
|
||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " "))
|
||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocationsDeps, " "))
|
||||
ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS", strings.Join(image.imageLocations, ":"))
|
||||
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+image.name, image.zip.String())
|
||||
|
||||
var imageNames []string
|
||||
|
@@ -48,7 +48,7 @@ func TestDexpreoptBootJars(t *testing.T) {
|
||||
|
||||
pathCtx := android.PathContextForTesting(config, nil)
|
||||
dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
|
||||
dexpreoptConfig.ArtApexJars = []string{"foo", "bar", "baz"}
|
||||
dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"}
|
||||
setDexpreoptTestGlobalConfig(config, dexpreoptConfig)
|
||||
|
||||
ctx := testContext(bp, nil)
|
||||
@@ -59,9 +59,10 @@ func TestDexpreoptBootJars(t *testing.T) {
|
||||
|
||||
dexpreoptBootJars := ctx.SingletonForTests("dex_bootjars")
|
||||
|
||||
bootArt := dexpreoptBootJars.Output("boot.art")
|
||||
bootArt := dexpreoptBootJars.Output("boot-foo.art")
|
||||
|
||||
expectedInputs := []string{
|
||||
"dex_artjars/apex/com.android.art/javalib/arm64/boot.art",
|
||||
"dex_bootjars_input/foo.jar",
|
||||
"dex_bootjars_input/bar.jar",
|
||||
"dex_bootjars_input/baz.jar",
|
||||
@@ -82,19 +83,19 @@ func TestDexpreoptBootJars(t *testing.T) {
|
||||
expectedOutputs := []string{
|
||||
"dex_bootjars/system/framework/arm64/boot.invocation",
|
||||
|
||||
"dex_bootjars/system/framework/arm64/boot.art",
|
||||
"dex_bootjars/system/framework/arm64/boot-foo.art",
|
||||
"dex_bootjars/system/framework/arm64/boot-bar.art",
|
||||
"dex_bootjars/system/framework/arm64/boot-baz.art",
|
||||
|
||||
"dex_bootjars/system/framework/arm64/boot.oat",
|
||||
"dex_bootjars/system/framework/arm64/boot-foo.oat",
|
||||
"dex_bootjars/system/framework/arm64/boot-bar.oat",
|
||||
"dex_bootjars/system/framework/arm64/boot-baz.oat",
|
||||
|
||||
"dex_bootjars/system/framework/arm64/boot.vdex",
|
||||
"dex_bootjars/system/framework/arm64/boot-foo.vdex",
|
||||
"dex_bootjars/system/framework/arm64/boot-bar.vdex",
|
||||
"dex_bootjars/system/framework/arm64/boot-baz.vdex",
|
||||
|
||||
"dex_bootjars_unstripped/system/framework/arm64/boot.oat",
|
||||
"dex_bootjars_unstripped/system/framework/arm64/boot-foo.oat",
|
||||
"dex_bootjars_unstripped/system/framework/arm64/boot-bar.oat",
|
||||
"dex_bootjars_unstripped/system/framework/arm64/boot-baz.oat",
|
||||
}
|
||||
|
@@ -119,118 +119,147 @@ func getJarsFromApexJarPairs(apexJarPairs []string) []string {
|
||||
return modules
|
||||
}
|
||||
|
||||
// Construct a variant of the global config for dexpreopted bootclasspath jars. The variants differ
|
||||
// in the list of input jars (libcore, framework, or both), in the naming scheme for the dexpreopt
|
||||
// files (ART recognizes "apex" names as special), and whether to include a zip archive.
|
||||
//
|
||||
// 'name' is a string unique for each profile (used in directory names and ninja rule names)
|
||||
// 'stem' is the basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}.
|
||||
func getBootImageConfig(ctx android.PathContext, key android.OnceKey, name string, stem string,
|
||||
needZip bool, artApexJarsOnly bool) bootImageConfig {
|
||||
var (
|
||||
bootImageConfigKey = android.NewOnceKey("bootImageConfig")
|
||||
artBootImageName = "art"
|
||||
frameworkBootImageName = "boot"
|
||||
apexBootImageName = "apex"
|
||||
)
|
||||
|
||||
// Construct the global boot image configs.
|
||||
func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
|
||||
return ctx.Config().Once(bootImageConfigKey, func() interface{} {
|
||||
|
||||
return ctx.Config().Once(key, func() interface{} {
|
||||
global := dexpreoptGlobalConfig(ctx)
|
||||
targets := dexpreoptTargets(ctx)
|
||||
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
|
||||
|
||||
artModules := global.ArtApexJars
|
||||
imageModules := artModules
|
||||
// In coverage builds ART boot class path jars are instrumented and have additional dependencies.
|
||||
if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
|
||||
artModules = append(artModules, "jacocoagent")
|
||||
}
|
||||
frameworkModules := android.RemoveListFromList(global.BootJars,
|
||||
concat(artModules, getJarsFromApexJarPairs(global.UpdatableBootJars)))
|
||||
|
||||
var bootLocations []string
|
||||
artSubdir := "apex/com.android.art/javalib"
|
||||
frameworkSubdir := "system/framework"
|
||||
|
||||
var artLocations, frameworkLocations []string
|
||||
for _, m := range artModules {
|
||||
bootLocations = append(bootLocations,
|
||||
filepath.Join("/apex/com.android.art/javalib", stemOf(m)+".jar"))
|
||||
artLocations = append(artLocations, filepath.Join("/"+artSubdir, stemOf(m)+".jar"))
|
||||
}
|
||||
for _, m := range frameworkModules {
|
||||
frameworkLocations = append(frameworkLocations, filepath.Join("/"+frameworkSubdir, stemOf(m)+".jar"))
|
||||
}
|
||||
|
||||
if !artApexJarsOnly {
|
||||
nonFrameworkModules := concat(artModules, getJarsFromApexJarPairs(global.UpdatableBootJars))
|
||||
frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
|
||||
imageModules = concat(imageModules, frameworkModules)
|
||||
// ART config for the primary boot image in the ART apex.
|
||||
// It includes the Core Libraries.
|
||||
artCfg := bootImageConfig{
|
||||
extension: false,
|
||||
name: artBootImageName,
|
||||
stem: "boot",
|
||||
installSubdir: artSubdir,
|
||||
modules: artModules,
|
||||
dexLocations: artLocations,
|
||||
dexLocationsDeps: artLocations,
|
||||
}
|
||||
|
||||
for _, m := range frameworkModules {
|
||||
bootLocations = append(bootLocations,
|
||||
filepath.Join("/system/framework", stemOf(m)+".jar"))
|
||||
// Framework config for the boot image extension.
|
||||
// It includes framework libraries and depends on the ART config.
|
||||
frameworkCfg := bootImageConfig{
|
||||
extension: true,
|
||||
name: frameworkBootImageName,
|
||||
stem: "boot",
|
||||
installSubdir: frameworkSubdir,
|
||||
modules: frameworkModules,
|
||||
dexLocations: frameworkLocations,
|
||||
dexLocationsDeps: append(artLocations, frameworkLocations...),
|
||||
}
|
||||
|
||||
// Apex config for the boot image used in the JIT-zygote experiment.
|
||||
// It includes both the Core libraries and framework.
|
||||
apexCfg := bootImageConfig{
|
||||
extension: false,
|
||||
name: apexBootImageName,
|
||||
stem: "apex",
|
||||
installSubdir: frameworkSubdir,
|
||||
modules: concat(artModules, frameworkModules),
|
||||
dexLocations: concat(artLocations, frameworkLocations),
|
||||
dexLocationsDeps: concat(artLocations, frameworkLocations),
|
||||
}
|
||||
|
||||
configs := map[string]*bootImageConfig{
|
||||
artBootImageName: &artCfg,
|
||||
frameworkBootImageName: &frameworkCfg,
|
||||
apexBootImageName: &apexCfg,
|
||||
}
|
||||
|
||||
// common to all configs
|
||||
for _, c := range configs {
|
||||
c.targets = targets
|
||||
|
||||
c.dir = deviceDir.Join(ctx, "dex_"+c.name+"jars")
|
||||
c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped")
|
||||
|
||||
// expands to <stem>.art for primary image and <stem>-<1st module>.art for extension
|
||||
imageName := c.firstModuleNameOrStem() + ".art"
|
||||
|
||||
c.imageLocations = []string{c.dir.Join(ctx, c.installSubdir, imageName).String()}
|
||||
|
||||
// The path to bootclasspath dex files needs to be known at module
|
||||
// GenerateAndroidBuildAction time, before the bootclasspath modules have been compiled.
|
||||
// Set up known paths for them, the singleton rules will copy them there.
|
||||
// TODO(b/143682396): use module dependencies instead
|
||||
inputDir := deviceDir.Join(ctx, "dex_"+c.name+"jars_input")
|
||||
for _, m := range c.modules {
|
||||
c.dexPaths = append(c.dexPaths, inputDir.Join(ctx, stemOf(m)+".jar"))
|
||||
}
|
||||
c.dexPathsDeps = c.dexPaths
|
||||
|
||||
c.images = make(map[android.ArchType]android.OutputPath)
|
||||
c.imagesDeps = make(map[android.ArchType]android.OutputPaths)
|
||||
|
||||
for _, target := range targets {
|
||||
arch := target.Arch.ArchType
|
||||
imageDir := c.dir.Join(ctx, c.installSubdir, arch.String())
|
||||
c.images[arch] = imageDir.Join(ctx, imageName)
|
||||
c.imagesDeps[arch] = c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex")
|
||||
}
|
||||
}
|
||||
|
||||
// The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
|
||||
// the bootclasspath modules have been compiled. Set up known paths for them, the singleton rules will copy
|
||||
// them there.
|
||||
// TODO(b/143682396): use module dependencies instead
|
||||
var bootDexPaths android.WritablePaths
|
||||
for _, m := range imageModules {
|
||||
bootDexPaths = append(bootDexPaths,
|
||||
android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars_input", m+".jar"))
|
||||
}
|
||||
// specific to the framework config
|
||||
frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
|
||||
frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
|
||||
frameworkCfg.zip = frameworkCfg.dir.Join(ctx, frameworkCfg.stem+".zip")
|
||||
|
||||
dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars")
|
||||
symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars_unstripped")
|
||||
|
||||
var zip android.WritablePath
|
||||
if needZip {
|
||||
zip = dir.Join(ctx, stem+".zip")
|
||||
}
|
||||
|
||||
targets := dexpreoptTargets(ctx)
|
||||
|
||||
imageConfig := bootImageConfig{
|
||||
name: name,
|
||||
stem: stem,
|
||||
modules: imageModules,
|
||||
dexLocations: bootLocations,
|
||||
dexPaths: bootDexPaths,
|
||||
dir: dir,
|
||||
symbolsDir: symbolsDir,
|
||||
targets: targets,
|
||||
images: make(map[android.ArchType]android.OutputPath),
|
||||
imagesDeps: make(map[android.ArchType]android.Paths),
|
||||
zip: zip,
|
||||
}
|
||||
|
||||
for _, target := range targets {
|
||||
imageDir := dir.Join(ctx, "system/framework", target.Arch.ArchType.String())
|
||||
imageConfig.images[target.Arch.ArchType] = imageDir.Join(ctx, stem+".art")
|
||||
|
||||
imagesDeps := make([]android.Path, 0, len(imageConfig.modules)*3)
|
||||
for _, dep := range imageConfig.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex") {
|
||||
imagesDeps = append(imagesDeps, dep)
|
||||
}
|
||||
imageConfig.imagesDeps[target.Arch.ArchType] = imagesDeps
|
||||
}
|
||||
|
||||
return imageConfig
|
||||
}).(bootImageConfig)
|
||||
return configs
|
||||
}).(map[string]*bootImageConfig)
|
||||
}
|
||||
|
||||
// Default config is the one that goes in the system image. It includes both libcore and framework.
|
||||
var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig")
|
||||
|
||||
func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
|
||||
return getBootImageConfig(ctx, defaultBootImageConfigKey, "boot", "boot", true, false)
|
||||
}
|
||||
|
||||
// Apex config is used for the JIT-zygote experiment. It includes both libcore and framework, but AOT-compiles only libcore.
|
||||
var apexBootImageConfigKey = android.NewOnceKey("apexBootImageConfig")
|
||||
|
||||
func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
|
||||
return getBootImageConfig(ctx, apexBootImageConfigKey, "apex", "apex", false, false)
|
||||
}
|
||||
|
||||
// ART config is the one used for the ART apex. It includes only libcore.
|
||||
var artBootImageConfigKey = android.NewOnceKey("artBootImageConfig")
|
||||
|
||||
func artBootImageConfig(ctx android.PathContext) bootImageConfig {
|
||||
return getBootImageConfig(ctx, artBootImageConfigKey, "art", "boot", false, true)
|
||||
return *genBootImageConfigs(ctx)[artBootImageName]
|
||||
}
|
||||
|
||||
func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
|
||||
return *genBootImageConfigs(ctx)[frameworkBootImageName]
|
||||
}
|
||||
|
||||
func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
|
||||
return *genBootImageConfigs(ctx)[apexBootImageName]
|
||||
}
|
||||
|
||||
func defaultBootclasspath(ctx android.PathContext) []string {
|
||||
return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string {
|
||||
global := dexpreoptGlobalConfig(ctx)
|
||||
image := defaultBootImageConfig(ctx)
|
||||
|
||||
updatableBootclasspath := make([]string, len(global.UpdatableBootJars))
|
||||
for i, p := range global.UpdatableBootJars {
|
||||
updatableBootclasspath[i] = dexpreopt.GetJarLocationFromApexJarPair(p)
|
||||
}
|
||||
bootclasspath := append(copyOf(image.dexLocations), updatableBootclasspath...)
|
||||
|
||||
bootclasspath := append(copyOf(image.dexLocationsDeps), updatableBootclasspath...)
|
||||
return bootclasspath
|
||||
})
|
||||
}
|
||||
@@ -245,7 +274,7 @@ func init() {
|
||||
|
||||
func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
|
||||
ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
|
||||
ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocations, ":"))
|
||||
ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocationsDeps, ":"))
|
||||
ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
|
||||
|
||||
ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules, ":"))
|
||||
|
Reference in New Issue
Block a user