diff options
| author | 2022-01-12 17:56:19 +0000 | |
|---|---|---|
| committer | 2022-01-13 14:50:05 +0000 | |
| commit | 6decef916c4a40855b506582620351a729ad76ea (patch) | |
| tree | 6eb5815015ba8b16c7a045dbf5cc8920752dc710 /java | |
| parent | 9ab9437b40564c25a0f4dfc71acfd117dc1d34dc (diff) | |
Allow installing boot images outside of APEX.
After this change, `bootImageConfig.installDirOnDevice` can be set to a
path outside of the APEX, in which case, the boot image will not be
installed in the APEX. Instead, it will be installed to the given path
by Make.
This is a no-op change. Current behavior is not affected.
Bug: 211973309
Test: m nothing
Test: -
1. m com.android.art
2. See the boot image still being installed in the ART APEX.
Test: -
1. Change `installDirOnDevice` of the ART boot image config to
`system/framework`.
2. See the boot image being installed in `/system/framework/<arch>`.
Change-Id: Ib13b17cc9e94dc5754c9b51b04df3307323b8783
Diffstat (limited to 'java')
| -rw-r--r-- | java/bootclasspath_fragment.go | 50 | ||||
| -rw-r--r-- | java/dexpreopt.go | 33 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 20 | ||||
| -rw-r--r-- | java/dexpreopt_config.go | 23 | ||||
| -rw-r--r-- | java/testing.go | 16 |
5 files changed, 121 insertions, 21 deletions
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index bfe895c17..fee51d72b 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -219,6 +219,11 @@ type BootclasspathFragmentModule struct { // Collect the module directory for IDE info in java/jdeps.go. modulePaths []string + + // Installs for on-device boot image files. This list has entries only if the installs should be + // handled by Make (e.g., the boot image should be installed on the system partition, rather than + // in the APEX). + bootImageDeviceInstalls []dexpreopterInstall } // commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt @@ -387,6 +392,9 @@ type BootclasspathFragmentApexContentInfo struct { // Map from arch type to the boot image files. bootImageFilesByArch bootImageFilesByArch + // True if the boot image should be installed in the APEX. + shouldInstallBootImageInApex bool + // Map from the base module name (without prebuilt_ prefix) of a fragment's contents module to the // hidden API encoded dex jar path. contentModuleDexJarPaths bootDexJarByModule @@ -410,6 +418,11 @@ func (i BootclasspathFragmentApexContentInfo) AndroidBootImageFilesByArchType() return i.bootImageFilesByArch } +// Return true if the boot image should be installed in the APEX. +func (i *BootclasspathFragmentApexContentInfo) ShouldInstallBootImageInApex() bool { + return i.shouldInstallBootImageInApex +} + // DexBootJarPathForContentModule returns the path to the dex boot jar for specified module. // // The dex boot jar is one which has had hidden API encoding performed on it. @@ -550,6 +563,24 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo // Copy the dex jars of this fragment's content modules to their predefined locations. copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule) } + + for _, variant := range imageConfig.apexVariants() { + arch := variant.target.Arch.ArchType.String() + for _, install := range variant.deviceInstalls { + // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. + installDir := strings.TrimPrefix(filepath.Dir(install.To), "/") + installBase := filepath.Base(install.To) + installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir) + + b.bootImageDeviceInstalls = append(b.bootImageDeviceInstalls, dexpreopterInstall{ + name: arch + "-" + installBase, + moduleName: b.Name(), + outputPathOnHost: install.From, + installDirOnDevice: installPath, + installFileOnDevice: installBase, + }) + } + } } // A prebuilt fragment cannot contribute to an apex. @@ -599,6 +630,8 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC info.profilePathOnHost = imageConfig.profilePathOnHost info.profileInstallPathInApex = imageConfig.profileInstallPathInApex } + + info.shouldInstallBootImageInApex = imageConfig.shouldInstallInApex() } info.bootImageFilesByArch = bootImageFilesByArch @@ -813,6 +846,23 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android. return androidBootImageFilesByArch } +func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries { + var entriesList []android.AndroidMkEntries + for _, install := range b.bootImageDeviceInstalls { + entriesList = append(entriesList, install.ToMakeEntries()) + } + return entriesList +} + +// Returns the names of all Make modules that handle the installation of the boot image. +func (b *BootclasspathFragmentModule) BootImageDeviceInstallMakeModules() []string { + var makeModules []string + for _, install := range b.bootImageDeviceInstalls { + makeModules = append(makeModules, install.FullModuleName()) + } + return makeModules +} + // Collect information for opening IDE project files in java/jdeps.go. func (b *BootclasspathFragmentModule) IDEInfo(dpInfo *android.IdeInfo) { dpInfo.Deps = append(dpInfo.Deps, b.properties.Contents...) diff --git a/java/dexpreopt.go b/java/dexpreopt.go index e9bc51878..7c5f055e6 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -57,6 +57,25 @@ func (install *dexpreopterInstall) SubModuleName() string { return "-dexpreopt-" + install.name } +// Returns Make entries for installing the file. +// +// This function uses a value receiver rather than a pointer receiver to ensure that the object is +// safe to use in `android.AndroidMkExtraEntriesFunc`. +func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries { + return android.AndroidMkEntries{ + Class: "ETC", + SubName: install.SubModuleName(), + OutputFile: android.OptionalPathForPath(install.outputPathOnHost), + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String()) + entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice) + entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false") + }, + }, + } +} + type dexpreopter struct { dexpreoptProperties DexpreoptProperties @@ -383,19 +402,7 @@ func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall { func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries { var entries []android.AndroidMkEntries for _, install := range d.builtInstalledForApex { - install := install - entries = append(entries, android.AndroidMkEntries{ - Class: "ETC", - SubName: install.SubModuleName(), - OutputFile: android.OptionalPathForPath(install.outputPathOnHost), - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String()) - entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice) - entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false") - }, - }, - }) + entries = append(entries, install.ToMakeEntries()) } return entries } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index c599c4da0..cad9c332a 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -313,10 +313,13 @@ type bootImageVariant struct { // This is only set for a variant of an image that extends another image. primaryImagesDeps android.Paths - // Rules which should be used in make to install the outputs. + // Rules which should be used in make to install the outputs on host. installs android.RuleBuilderInstalls vdexInstalls android.RuleBuilderInstalls unstrippedInstalls android.RuleBuilderInstalls + + // Rules which should be used in make to install the outputs on device. + deviceInstalls android.RuleBuilderInstalls } // Get target-specific boot image variant for the given boot image config and target. @@ -388,6 +391,11 @@ func (image *bootImageConfig) apexVariants() []*bootImageVariant { return variants } +// Returns true if the boot image should be installed in the APEX. +func (image *bootImageConfig) shouldInstallInApex() bool { + return strings.HasPrefix(image.installDirOnDevice, "apex/") +} + // Return boot image locations (as a list of symbolic paths). // // The image "location" is a symbolic path that, with multiarchitecture support, doesn't really @@ -710,6 +718,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p var vdexInstalls android.RuleBuilderInstalls var unstrippedInstalls android.RuleBuilderInstalls + var deviceInstalls android.RuleBuilderInstalls for _, artOrOat := range image.moduleFiles(ctx, outputDir, ".art", ".oat") { cmd.ImplicitOutput(artOrOat) @@ -735,12 +744,21 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p android.RuleBuilderInstall{unstrippedOat, filepath.Join(installDir, unstrippedOat.Base())}) } + if image.installDirOnHost != image.installDirOnDevice && !image.shouldInstallInApex() && !ctx.Config().UnbundledBuild() { + installDirOnDevice := filepath.Join("/", image.installDirOnDevice, arch.String()) + for _, file := range image.moduleFiles(ctx, outputDir, ".art", ".oat", ".vdex") { + deviceInstalls = append(deviceInstalls, + android.RuleBuilderInstall{file, filepath.Join(installDirOnDevice, file.Base())}) + } + } + rule.Build(image.name+"JarsDexpreopt_"+image.target.String(), "dexpreopt "+image.name+" jars "+arch.String()) // save output and installed files for makevars image.installs = rule.Installs() image.vdexInstalls = vdexInstalls image.unstrippedInstalls = unstrippedInstalls + image.deviceInstalls = deviceInstalls } const failureMessage = `ERROR: Dex2oat failed to compile a boot image. diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index 26c110544..df8d8c80a 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -41,17 +41,14 @@ func dexpreoptTargets(ctx android.PathContext) []android.Target { var ( bootImageConfigKey = android.NewOnceKey("bootImageConfig") + bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw") artBootImageName = "art" frameworkBootImageName = "boot" ) -// Construct the global boot image configs. -func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { - return ctx.Config().Once(bootImageConfigKey, func() interface{} { - +func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig { + return ctx.Config().Once(bootImageConfigRawKey, func() interface{} { global := dexpreopt.GetGlobalConfig(ctx) - targets := dexpreoptTargets(ctx) - deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName()) artModules := global.ArtApexJars frameworkModules := global.BootJars.RemoveList(artModules) @@ -79,10 +76,22 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { modules: frameworkModules, } - configs := map[string]*bootImageConfig{ + return map[string]*bootImageConfig{ artBootImageName: &artCfg, frameworkBootImageName: &frameworkCfg, } + }).(map[string]*bootImageConfig) +} + +// Construct the global boot image configs. +func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { + return ctx.Config().Once(bootImageConfigKey, func() interface{} { + targets := dexpreoptTargets(ctx) + deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName()) + + configs := genBootImageConfigRaw(ctx) + artCfg := configs[artBootImageName] + frameworkCfg := configs[frameworkBootImageName] // common to all configs for _, c := range configs { diff --git a/java/testing.go b/java/testing.go index 7441e4497..6c49bc866 100644 --- a/java/testing.go +++ b/java/testing.go @@ -506,3 +506,19 @@ func fakeApexMutator(mctx android.BottomUpMutatorContext) { } } } + +// Applies the given modifier on the boot image config with the given name. +func FixtureModifyBootImageConfig(name string, configModifier func(*bootImageConfig)) android.FixturePreparer { + return android.FixtureModifyConfig(func(androidConfig android.Config) { + pathCtx := android.PathContextForTesting(androidConfig) + config := genBootImageConfigRaw(pathCtx) + configModifier(config[name]) + }) +} + +// Sets the value of `installDirOnDevice` of the boot image config with the given name. +func FixtureSetBootImageInstallDirOnDevice(name string, installDir string) android.FixturePreparer { + return FixtureModifyBootImageConfig(name, func(config *bootImageConfig) { + config.installDirOnDevice = installDir + }) +} |