Merge "Only export boot image files to APEX if they are actually created" am: 6778edb558 am: 923bb78212

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1716109

Change-Id: I5214f09a1510dc7e9072f04f3536bdde804fb69e
This commit is contained in:
Paul Duffin 2021-05-24 22:58:30 +00:00 committed by Automerger Merge Worker
commit dafcf9c54d
2 changed files with 43 additions and 65 deletions

View file

@ -62,6 +62,7 @@ func TestBootclasspathFragments(t *testing.T) {
apex { apex {
name: "com.android.art", name: "com.android.art",
key: "com.android.art.key", key: "com.android.art.key",
bootclasspath_fragments: ["art-bootclasspath-fragment"],
java_libs: [ java_libs: [
"baz", "baz",
"quuz", "quuz",
@ -100,32 +101,12 @@ func TestBootclasspathFragments(t *testing.T) {
"com.android.art", "com.android.art",
], ],
} }
bootclasspath_fragment {
name: "framework-bootclasspath-fragment",
image_name: "boot",
}
`, `,
) )
// Make sure that the framework-bootclasspath-fragment is using the correct configuration.
checkBootclasspathFragment(t, result, "framework-bootclasspath-fragment", "platform:foo,platform:bar", `
test_device/dex_bootjars/android/system/framework/arm/boot-foo.art
test_device/dex_bootjars/android/system/framework/arm/boot-foo.oat
test_device/dex_bootjars/android/system/framework/arm/boot-foo.vdex
test_device/dex_bootjars/android/system/framework/arm/boot-bar.art
test_device/dex_bootjars/android/system/framework/arm/boot-bar.oat
test_device/dex_bootjars/android/system/framework/arm/boot-bar.vdex
test_device/dex_bootjars/android/system/framework/arm64/boot-foo.art
test_device/dex_bootjars/android/system/framework/arm64/boot-foo.oat
test_device/dex_bootjars/android/system/framework/arm64/boot-foo.vdex
test_device/dex_bootjars/android/system/framework/arm64/boot-bar.art
test_device/dex_bootjars/android/system/framework/arm64/boot-bar.oat
test_device/dex_bootjars/android/system/framework/arm64/boot-bar.vdex
`)
// Make sure that the art-bootclasspath-fragment is using the correct configuration. // Make sure that the art-bootclasspath-fragment is using the correct configuration.
checkBootclasspathFragment(t, result, "art-bootclasspath-fragment", "com.android.art:baz,com.android.art:quuz", ` checkBootclasspathFragment(t, result, "art-bootclasspath-fragment", "android_common_apex10000",
"com.android.art:baz,com.android.art:quuz", `
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex
@ -263,10 +244,10 @@ func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
checkSdkKindStubs("other", otherInfo, android.SdkCorePlatform) checkSdkKindStubs("other", otherInfo, android.SdkCorePlatform)
} }
func checkBootclasspathFragment(t *testing.T, result *android.TestResult, moduleName string, expectedConfiguredModules string, expectedBootclasspathFragmentFiles string) { func checkBootclasspathFragment(t *testing.T, result *android.TestResult, moduleName, variantName string, expectedConfiguredModules string, expectedBootclasspathFragmentFiles string) {
t.Helper() t.Helper()
bootclasspathFragment := result.ModuleForTests(moduleName, "android_common").Module().(*java.BootclasspathFragmentModule) bootclasspathFragment := result.ModuleForTests(moduleName, variantName).Module().(*java.BootclasspathFragmentModule)
bootclasspathFragmentInfo := result.ModuleProvider(bootclasspathFragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo) bootclasspathFragmentInfo := result.ModuleProvider(bootclasspathFragment, java.BootclasspathFragmentApexContentInfoProvider).(java.BootclasspathFragmentApexContentInfo)
modules := bootclasspathFragmentInfo.Modules() modules := bootclasspathFragmentInfo.Modules()

View file

@ -270,11 +270,12 @@ var BootclasspathFragmentApexContentInfoProvider = blueprint.NewProvider(Bootcla
// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the // BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
// apex contents. // apex contents.
type BootclasspathFragmentApexContentInfo struct { type BootclasspathFragmentApexContentInfo struct {
// The image config, internal to this module (and the dex_bootjars singleton). // The configured modules, will be empty if this is from a bootclasspath_fragment that does not
// // set image_name: "art".
// Will be nil if the BootclasspathFragmentApexContentInfo has not been provided for a specific module. That can occur modules android.ConfiguredJarList
// when SkipDexpreoptBootJars(ctx) returns true.
imageConfig *bootImageConfig // Map from arch type to the boot image files.
bootImageFilesByArch map[android.ArchType]android.OutputPaths
// Map from the name of the context module (as returned by Name()) to the hidden API encoded dex // Map from the name of the context module (as returned by Name()) to the hidden API encoded dex
// jar path. // jar path.
@ -282,24 +283,14 @@ type BootclasspathFragmentApexContentInfo struct {
} }
func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList { func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
return i.imageConfig.modules return i.modules
} }
// Get a map from ArchType to the associated boot image's contents for Android. // Get a map from ArchType to the associated boot image's contents for Android.
// //
// Extension boot images only return their own files, not the files of the boot images they extend. // Extension boot images only return their own files, not the files of the boot images they extend.
func (i BootclasspathFragmentApexContentInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths { func (i BootclasspathFragmentApexContentInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
files := map[android.ArchType]android.OutputPaths{} return i.bootImageFilesByArch
if i.imageConfig != nil {
for _, variant := range i.imageConfig.variants {
// We also generate boot images for host (for testing), but we don't need those in the apex.
// TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
if variant.target.Os == android.Android {
files[variant.target.Arch.ArchType] = variant.imagesDeps
}
}
}
return files
} }
// DexBootJarPathForContentModule returns the path to the dex boot jar for specified module. // DexBootJarPathForContentModule returns the path to the dex boot jar for specified module.
@ -412,20 +403,33 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
// modules. // modules.
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) { func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) {
// Construct the apex content info from the config. // Construct the apex content info from the config.
info := BootclasspathFragmentApexContentInfo{ info := BootclasspathFragmentApexContentInfo{}
imageConfig: imageConfig,
}
// Populate the apex content info with paths to the dex jars. // Populate the apex content info with paths to the dex jars.
b.populateApexContentInfoDexJars(ctx, &info, contents, hiddenAPIFlagOutput) b.populateApexContentInfoDexJars(ctx, &info, contents, hiddenAPIFlagOutput)
if !SkipDexpreoptBootJars(ctx) { if imageConfig != nil {
// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars info.modules = imageConfig.modules
// GenerateSingletonBuildActions method as it cannot create it for itself.
dexpreopt.GetGlobalSoongConfig(ctx)
// Only generate the boot image if the configuration does not skip it. if !SkipDexpreoptBootJars(ctx) {
b.generateBootImageBuildActions(ctx, contents) // 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)
// Only generate the boot image if the configuration does not skip it.
if b.generateBootImageBuildActions(ctx, contents, imageConfig) {
// Allow the apex to access the boot image files.
files := map[android.ArchType]android.OutputPaths{}
for _, variant := range imageConfig.variants {
// We also generate boot images for host (for testing), but we don't need those in the apex.
// TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
if variant.target.Os == android.Android {
files[variant.target.Arch.ArchType] = variant.imagesDeps
}
}
info.bootImageFilesByArch = files
}
}
} }
// Make the apex content info available for other modules. // Make the apex content info available for other modules.
@ -589,32 +593,23 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.M
// generateBootImageBuildActions generates ninja rules to create the boot image if required for this // generateBootImageBuildActions generates ninja rules to create the boot image if required for this
// module. // module.
func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, contents []android.Module) { //
// Returns true if the boot image is created, false otherwise.
func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, contents []android.Module, imageConfig *bootImageConfig) bool {
global := dexpreopt.GetGlobalConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx)
if !shouldBuildBootImages(ctx.Config(), global) { if !shouldBuildBootImages(ctx.Config(), global) {
return return false
}
// 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. // Bootclasspath fragment modules that are for the platform do not produce a boot image.
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if apexInfo.IsForPlatform() { if apexInfo.IsForPlatform() {
return return false
} }
// Bootclasspath fragment modules that are versioned do not produce a boot image. // Bootclasspath fragment modules that are versioned do not produce a boot image.
if android.IsModuleInVersionedSdk(ctx.Module()) { if android.IsModuleInVersionedSdk(ctx.Module()) {
return return false
} }
// Copy the dex jars of this fragment's content modules to their predefined locations. // Copy the dex jars of this fragment's content modules to their predefined locations.
@ -623,6 +618,8 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.
// Build a profile for the image config and then use that to build the boot image. // Build a profile for the image config and then use that to build the boot image.
profile := bootImageProfileRule(ctx, imageConfig) profile := bootImageProfileRule(ctx, imageConfig)
buildBootImage(ctx, imageConfig, profile) buildBootImage(ctx, imageConfig, profile)
return true
} }
type bootclasspathFragmentMemberType struct { type bootclasspathFragmentMemberType struct {