diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2019-02-22 15:34:40 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2019-02-22 15:37:48 +0000 |
commit | 72892f103573468fd8d79b03b9403c27c707abfe (patch) | |
tree | 637c48e27e66518c49c25ea5017e8eca4a768067 | |
parent | e91a07827117a26f4231eda6f58d24aa5ec70492 (diff) | |
download | build_soong-72892f103573468fd8d79b03b9403c27c707abfe.tar.gz build_soong-72892f103573468fd8d79b03b9403c27c707abfe.tar.bz2 build_soong-72892f103573468fd8d79b03b9403c27c707abfe.zip |
Support for install multiple boot images.
Bug: 119800099
Test: m && /system/framework/arm/apex*.art files exist
Change-Id: I8b708a0c495193e5455e03eaa575ce55a482a95d
-rw-r--r-- | dexpreopt/config.go | 2 | ||||
-rw-r--r-- | java/dexpreopt_bootjars.go | 112 | ||||
-rw-r--r-- | java/dexpreopt_config.go | 46 |
3 files changed, 110 insertions, 50 deletions
diff --git a/dexpreopt/config.go b/dexpreopt/config.go index 99814019..15008b96 100644 --- a/dexpreopt/config.go +++ b/dexpreopt/config.go @@ -31,6 +31,8 @@ type GlobalConfig struct { OnlyPreoptBootImageAndSystemServer bool // only preopt jars in the boot image or system server + GenerateApexImage bool // generate an extra boot image only containing jars from the runtime apex + HasSystemOther bool // store odex files that match PatternsOnSystemOther on the system_other partition PatternsOnSystemOther []string // patterns (using '%' to denote a prefix match) to put odex on the system_other partition diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 0ad7a275..a93d1804 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -70,7 +70,7 @@ type bootImage struct { func newBootImage(ctx android.PathContext, config bootImageConfig) *bootImage { image := &bootImage{ - bootImageConfig: defaultBootImageConfig(ctx), + bootImageConfig: config, installs: make(map[android.ArchType]android.RuleBuilderInstalls), vdexInstalls: make(map[android.ArchType]android.RuleBuilderInstalls), @@ -111,6 +111,7 @@ func skipDexpreoptBootJars(ctx android.PathContext) bool { type dexpreoptBootJars struct { defaultBootImage *bootImage + otherImages []*bootImage } // dexpreoptBoot singleton rules @@ -131,7 +132,11 @@ func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) { return } + // Always create the default boot image first, to get a unique profile rule for all images. d.defaultBootImage = buildBootImage(ctx, defaultBootImageConfig(ctx)) + if global.GenerateApexImage { + d.otherImages = append(d.otherImages, buildBootImage(ctx, apexBootImageConfig(ctx))) + } } // buildBootImage takes a bootImageConfig, creates rules to build it, and returns a *bootImage. @@ -199,7 +204,7 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage, global := dexpreoptGlobalConfig(ctx) symbolsDir := image.symbolsDir.Join(ctx, "system/framework", arch.String()) - symbolsFile := symbolsDir.Join(ctx, "boot.oat") + symbolsFile := symbolsDir.Join(ctx, image.name+".oat") outputDir := image.dir.Join(ctx, "system/framework", arch.String()) outputPath := image.images[arch] oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath, arch), "oat") @@ -283,8 +288,8 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage, var unstrippedInstalls android.RuleBuilderInstalls // dex preopt on the bootclasspath produces multiple files. The first dex file - // is converted into to boot.art (to match the legacy assumption that boot.art - // exists), and the rest are converted to boot-<name>.art. + // is converted into to '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 { @@ -330,72 +335,79 @@ It is likely that the boot classpath is inconsistent. Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.` func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath { - global := dexpreoptGlobalConfig(ctx) + return ctx.Config().Once(bootImageProfileRuleKey, func() interface{} { + global := dexpreoptGlobalConfig(ctx) - if !global.UseProfileForBootImage || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() { - return nil - } + if !global.UseProfileForBootImage || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() { + return nil + } - tools := global.Tools + tools := global.Tools - rule := android.NewRuleBuilder() - rule.MissingDeps(missingDeps) + rule := android.NewRuleBuilder() + rule.MissingDeps(missingDeps) - var bootImageProfile android.Path - if len(global.BootImageProfiles) > 1 { - combinedBootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt") - rule.Command().Text("cat").Inputs(global.BootImageProfiles).Text(">").Output(combinedBootImageProfile) - bootImageProfile = combinedBootImageProfile - } else if len(global.BootImageProfiles) == 1 { - bootImageProfile = global.BootImageProfiles[0] - } else { - // If not set, use the default. Some branches like master-art-host don't have frameworks/base, so manually - // handle the case that the default is missing. Those branches won't attempt to build the profile rule, - // and if they do they'll get a missing deps error. - defaultProfile := "frameworks/base/config/boot-image-profile.txt" - path := android.ExistentPathForSource(ctx, defaultProfile) - if path.Valid() { - bootImageProfile = path.Path() + var bootImageProfile android.Path + if len(global.BootImageProfiles) > 1 { + combinedBootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt") + rule.Command().Text("cat").Inputs(global.BootImageProfiles).Text(">").Output(combinedBootImageProfile) + bootImageProfile = combinedBootImageProfile + } else if len(global.BootImageProfiles) == 1 { + bootImageProfile = global.BootImageProfiles[0] } else { - missingDeps = append(missingDeps, defaultProfile) - bootImageProfile = android.PathForOutput(ctx, "missing") + // If not set, use the default. Some branches like master-art-host don't have frameworks/base, so manually + // handle the case that the default is missing. Those branches won't attempt to build the profile rule, + // and if they do they'll get a missing deps error. + defaultProfile := "frameworks/base/config/boot-image-profile.txt" + path := android.ExistentPathForSource(ctx, defaultProfile) + if path.Valid() { + bootImageProfile = path.Path() + } else { + missingDeps = append(missingDeps, defaultProfile) + bootImageProfile = android.PathForOutput(ctx, "missing") + } } - } - profile := image.dir.Join(ctx, "boot.prof") + profile := image.dir.Join(ctx, "boot.prof") - rule.Command(). - Text(`ANDROID_LOG_TAGS="*:e"`). - Tool(tools.Profman). - FlagWithInput("--create-profile-from=", bootImageProfile). - FlagForEachInput("--apk=", image.dexPaths.Paths()). - FlagForEachArg("--dex-location=", image.dexLocations). - FlagWithOutput("--reference-profile-file=", profile) + rule.Command(). + Text(`ANDROID_LOG_TAGS="*:e"`). + Tool(tools.Profman). + FlagWithInput("--create-profile-from=", bootImageProfile). + FlagForEachInput("--apk=", image.dexPaths.Paths()). + FlagForEachArg("--dex-location=", image.dexLocations). + FlagWithOutput("--reference-profile-file=", profile) - rule.Install(profile, "/system/etc/boot-image.prof") + rule.Install(profile, "/system/etc/boot-image.prof") - rule.Build(pctx, ctx, "bootJarsProfile", "profile boot jars") + rule.Build(pctx, ctx, "bootJarsProfile", "profile boot jars") - image.profileInstalls = rule.Installs() + image.profileInstalls = rule.Installs() - return profile + return profile + }).(android.WritablePath) } +var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule") + // Export paths for default boot image to Make func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { image := d.defaultBootImage if image != nil { - for arch, _ := range image.images { - ctx.Strict("DEXPREOPT_IMAGE_"+arch.String(), image.images[arch].String()) - - ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+arch.String(), image.installs[arch].String()) - ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+arch.String(), image.unstrippedInstalls[arch].String()) - ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+arch.String(), image.vdexInstalls[arch].String()) - } - 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, " ")) + + var imageNames []string + for _, current := range append(d.otherImages, image) { + imageNames = append(imageNames, current.name) + for arch, _ := range current.images { + ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.vdexInstalls[arch].String()) + ctx.Strict("DEXPREOPT_IMAGE_"+current.name+"_"+arch.String(), current.images[arch].String()) + ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.installs[arch].String()) + ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.unstrippedInstalls[arch].String()) + } + } + ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " ")) } } diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index 3d4042b0..31a3e26c 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -131,6 +131,52 @@ func defaultBootImageConfig(ctx android.PathContext) bootImageConfig { var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig") +func apexBootImageConfig(ctx android.PathContext) bootImageConfig { + return ctx.Config().Once(apexBootImageConfigKey, func() interface{} { + global := dexpreoptGlobalConfig(ctx) + + runtimeModules := global.RuntimeApexJars + + var runtimeBootLocations []string + + for _, m := range runtimeModules { + runtimeBootLocations = append(runtimeBootLocations, + filepath.Join("/apex/com.android.runtime/javalib", m+".jar")) + } + + // 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: use module dependencies instead + var runtimeBootDexPaths android.WritablePaths + for _, m := range runtimeModules { + runtimeBootDexPaths = append(runtimeBootDexPaths, + android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_input", m+".jar")) + } + + dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars") + symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_unstripped") + images := make(map[android.ArchType]android.OutputPath) + + for _, target := range ctx.Config().Targets[android.Android] { + images[target.Arch.ArchType] = dir.Join(ctx, + "system/framework", target.Arch.ArchType.String(), "apex.art") + } + + return bootImageConfig{ + name: "apex", + modules: runtimeModules, + dexLocations: runtimeBootLocations, + dexPaths: runtimeBootDexPaths, + dir: dir, + symbolsDir: symbolsDir, + images: images, + } + }).(bootImageConfig) +} + +var apexBootImageConfigKey = android.NewOnceKey("apexBootImageConfig") + func defaultBootclasspath(ctx android.PathContext) []string { return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string { global := dexpreoptGlobalConfig(ctx) |