Move copying of dex files from dexpreopt_bootjars singleton
The art dex files are copied in the bootclasspath_fragment and the
non-updatable and updatable dex files are copied in the
platform_bootclasspath.
Bug: 177892522
Test: m nothing
Change-Id: I5d3d533d1a7a9f8e7ae20c12eb33029a898a2cd6
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index bed629d..5b1be22 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -361,6 +361,15 @@
// Generate classpaths.proto config
b.generateClasspathProtoBuildActions(ctx)
+ // Gather the bootclasspath fragment's contents.
+ var contents []android.Module
+ ctx.VisitDirectDeps(func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
+ if IsBootclasspathFragmentContentDepTag(tag) {
+ contents = append(contents, module)
+ }
+ })
+
// Perform hidden API processing.
b.generateHiddenAPIBuildActions(ctx)
@@ -376,6 +385,9 @@
// GenerateSingletonBuildActions method as it cannot create it for itself.
dexpreopt.GetGlobalSoongConfig(ctx)
info.imageConfig = b.getImageConfig(ctx)
+
+ // Only generate the boot image if the configuration does not skip it.
+ b.generateBootImageBuildActions(ctx, contents)
}
// Make it available for other modules.
@@ -434,6 +446,40 @@
ctx.SetProvider(bootclasspathApiInfoProvider, bootclasspathApiInfo)
}
+// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
+// module.
+func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, contents []android.Module) {
+ global := dexpreopt.GetGlobalConfig(ctx)
+ if !shouldBuildBootImages(ctx.Config(), global) {
+ return
+ }
+
+ // Bootclasspath fragment modules that are not preferred do not produce a boot image.
+ if !isActiveModule(ctx.Module()) {
+ return
+ }
+
+ // Bootclasspath fragment modules that have no image_name property do not produce a boot image.
+ imageConfig := b.getImageConfig(ctx)
+ if imageConfig == nil {
+ return
+ }
+
+ // Bootclasspath fragment modules that are for the platform do not produce a boot image.
+ apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+ if apexInfo.IsForPlatform() {
+ return
+ }
+
+ // Bootclasspath fragment modules that are versioned do not produce a boot image.
+ if android.IsModuleInVersionedSdk(ctx.Module()) {
+ return
+ }
+
+ // Copy the dex jars of this fragment's content modules to their predefined locations.
+ copyBootJarsToPredefinedLocations(ctx, contents, imageConfig.modules, imageConfig.dexPaths)
+}
+
type bootclasspathFragmentMemberType struct {
android.SdkMemberTypeBase
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index ce68c48..0a324a9 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -436,8 +436,6 @@
// Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
d.otherImages = append(d.otherImages, buildBootImage(ctx, artBootImageConfig(ctx), profile))
-
- copyUpdatableBootJars(ctx)
}
// shouldBuildBootImages determines whether boot images should be built.
@@ -452,77 +450,19 @@
return true
}
-// A copy of isModuleInConfiguredList created to work with singleton context.
-//
-// TODO(b/177892522): Remove this.
-func isModuleInConfiguredListForSingleton(ctx android.SingletonContext, module android.Module, configuredBootJars android.ConfiguredJarList) bool {
- name := ctx.ModuleName(module)
-
- // Strip a prebuilt_ prefix so that this can match a prebuilt module that has not been renamed.
- name = android.RemoveOptionalPrebuiltPrefix(name)
-
- // Ignore any module that is not listed in the boot image configuration.
- index := configuredBootJars.IndexOfJar(name)
- if index == -1 {
- return false
- }
-
- // It is an error if the module is not an ApexModule.
- if _, ok := module.(android.ApexModule); !ok {
- ctx.Errorf("%s is configured in boot jars but does not support being added to an apex", ctx.ModuleName(module))
- return false
- }
-
- apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
-
- // Now match the apex part of the boot image configuration.
- requiredApex := configuredBootJars.Apex(index)
- if requiredApex == "platform" || requiredApex == "system_ext" {
- if len(apexInfo.InApexes) != 0 {
- // A platform variant is required but this is for an apex so ignore it.
- return false
- }
- } else if !apexInfo.InApexByBaseName(requiredApex) {
- // An apex variant for a specific apex is required but this is the wrong apex.
- return false
- }
-
- return true
-}
-
-// findBootJarModules finds the boot jar module variants specified in the bootjars parameter.
-//
-// It returns a list of modules such that the module at index i corresponds to the configured jar
-// at index i.
-func findBootJarModules(ctx android.SingletonContext, bootjars android.ConfiguredJarList) []android.Module {
- modules := make([]android.Module, bootjars.Len())
-
- // This logic is tested in the apex package to avoid import cycle apex <-> java.
- ctx.VisitAllModules(func(module android.Module) {
- if !isActiveModule(module) || !isModuleInConfiguredListForSingleton(ctx, module, bootjars) {
- return
- }
-
- name := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName(module))
- index := bootjars.IndexOfJar(name)
- if existing := modules[index]; existing != nil {
- ctx.Errorf("Multiple boot jar modules found for %s:%s - %q and %q",
- bootjars.Apex(index), bootjars.Jar(index), existing, module)
- return
- }
- modules[index] = module
- })
- return modules
-}
-
// copyBootJarsToPredefinedLocations generates commands that will copy boot jars to
// predefined paths in the global config.
-func copyBootJarsToPredefinedLocations(ctx android.SingletonContext, bootModules []android.Module, bootjars android.ConfiguredJarList, jarPathsPredefined android.WritablePaths) {
+func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, bootModules []android.Module, bootjars android.ConfiguredJarList, jarPathsPredefined android.WritablePaths) {
jarPaths := make(android.Paths, bootjars.Len())
for i, module := range bootModules {
if module != nil {
bootDexJar := module.(interface{ DexJarBuildPath() android.Path }).DexJarBuildPath()
jarPaths[i] = bootDexJar
+
+ name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(module))
+ if bootjars.Jar(i) != name {
+ ctx.ModuleErrorf("expected module %s at position %d but found %s", bootjars.Jar(i), i, name)
+ }
}
}
@@ -548,7 +488,7 @@
},
})
} else {
- ctx.Errorf("failed to find a dex jar path for module '%s'"+
+ ctx.ModuleErrorf("failed to find a dex jar path for module '%s'"+
", note that some jars may be filtered out by module constraints", module)
}
@@ -564,9 +504,6 @@
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig, profile android.WritablePath) *bootImageConfig {
- bootModules := findBootJarModules(ctx, image.modules)
- copyBootJarsToPredefinedLocations(ctx, bootModules, image.modules, image.dexPaths)
-
var zipFiles android.Paths
for _, variant := range image.variants {
files := buildBootImageVariant(ctx, variant, profile)
@@ -589,13 +526,6 @@
return image
}
-// Generate commands that will copy updatable boot jars to predefined paths in the global config.
-func copyUpdatableBootJars(ctx android.SingletonContext) {
- config := GetUpdatableBootConfig(ctx)
- bootModules := findBootJarModules(ctx, config.modules)
- copyBootJarsToPredefinedLocations(ctx, bootModules, config.modules, config.dexPaths)
-}
-
// Generate boot image build rules for a specific target.
func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant, profile android.Path) android.WritablePaths {
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index f6af501..676a0e7 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -151,9 +151,7 @@
// Checks to see whether the supplied module variant is in the list of boot jars.
//
-// Apart from the context this is identical to isModuleInConfiguredListForSingleton.
-//
-// TODO(b/179354495): Avoid having to perform this type of check or if necessary dedup it.
+// TODO(b/179354495): Avoid having to perform this type of check.
func isModuleInConfiguredList(ctx android.BaseModuleContext, module android.Module, configuredBootJars android.ConfiguredJarList) bool {
name := ctx.OtherModuleName(module)
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index c787e47..eccea61 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -196,7 +196,7 @@
return
}
- b.generateBootImageBuildActions(ctx, updatableModules)
+ b.generateBootImageBuildActions(ctx, nonUpdatableModules, updatableModules)
}
// Generate classpaths.proto config
@@ -430,7 +430,7 @@
}
// generateBootImageBuildActions generates ninja rules related to the boot image creation.
-func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.ModuleContext, updatableModules []android.Module) {
+func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.ModuleContext, nonUpdatableModules, updatableModules []android.Module) {
// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
// GenerateSingletonBuildActions method as it cannot create it for itself.
dexpreopt.GetGlobalSoongConfig(ctx)
@@ -451,5 +451,12 @@
// Generate the updatable bootclasspath packages rule.
generateUpdatableBcpPackagesRule(ctx, imageConfig, updatableModules)
+ // Copy non-updatable module dex jars to their predefined locations.
+ copyBootJarsToPredefinedLocations(ctx, nonUpdatableModules, imageConfig.modules, imageConfig.dexPaths)
+
+ // Copy updatable module dex jars to their predefined locations.
+ config := GetUpdatableBootConfig(ctx)
+ copyBootJarsToPredefinedLocations(ctx, updatableModules, config.modules, config.dexPaths)
+
dumpOatRules(ctx, imageConfig)
}