summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2022-01-12 17:56:19 +0000
committer Jiakai Zhang <jiakaiz@google.com> 2022-01-13 14:50:05 +0000
commit6decef916c4a40855b506582620351a729ad76ea (patch)
tree6eb5815015ba8b16c7a045dbf5cc8920752dc710 /java
parent9ab9437b40564c25a0f4dfc71acfd117dc1d34dc (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.go50
-rw-r--r--java/dexpreopt.go33
-rw-r--r--java/dexpreopt_bootjars.go20
-rw-r--r--java/dexpreopt_config.go23
-rw-r--r--java/testing.go16
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
+ })
+}