Copy boot dex jars from prebuilt art-bootclasspath-fragment if preferred am: ce918b0278
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1736226 Change-Id: I116ef8467e180b691ba6e6f2bcf38cd275f6ecba
This commit is contained in:
commit
56a6834640
2 changed files with 117 additions and 6 deletions
|
@ -16,6 +16,7 @@ package apex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -359,6 +360,19 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
||||||
|
|
||||||
addPrebuilt := func(prefer bool, contents ...string) android.FixturePreparer {
|
addPrebuilt := func(prefer bool, contents ...string) android.FixturePreparer {
|
||||||
text := fmt.Sprintf(`
|
text := fmt.Sprintf(`
|
||||||
|
prebuilt_apex {
|
||||||
|
name: "com.android.art",
|
||||||
|
arch: {
|
||||||
|
arm64: {
|
||||||
|
src: "com.android.art-arm64.apex",
|
||||||
|
},
|
||||||
|
arm: {
|
||||||
|
src: "com.android.art-arm.apex",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
exported_bootclasspath_fragments: ["mybootclasspathfragment"],
|
||||||
|
}
|
||||||
|
|
||||||
prebuilt_bootclasspath_fragment {
|
prebuilt_bootclasspath_fragment {
|
||||||
name: "mybootclasspathfragment",
|
name: "mybootclasspathfragment",
|
||||||
image_name: "art",
|
image_name: "art",
|
||||||
|
@ -372,7 +386,47 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
||||||
return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text)
|
return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("boot image files", func(t *testing.T) {
|
t.Run("boot image files from source", func(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
commonPreparer,
|
||||||
|
|
||||||
|
// Configure some libraries in the art bootclasspath_fragment that match the source
|
||||||
|
// bootclasspath_fragment's contents property.
|
||||||
|
java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
|
||||||
|
addSource("foo", "bar"),
|
||||||
|
).RunTest(t)
|
||||||
|
|
||||||
|
ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
|
||||||
|
"etc/classpaths/bootclasspath.pb",
|
||||||
|
"javalib/arm/boot.art",
|
||||||
|
"javalib/arm/boot.oat",
|
||||||
|
"javalib/arm/boot.vdex",
|
||||||
|
"javalib/arm/boot-bar.art",
|
||||||
|
"javalib/arm/boot-bar.oat",
|
||||||
|
"javalib/arm/boot-bar.vdex",
|
||||||
|
"javalib/arm64/boot.art",
|
||||||
|
"javalib/arm64/boot.oat",
|
||||||
|
"javalib/arm64/boot.vdex",
|
||||||
|
"javalib/arm64/boot-bar.art",
|
||||||
|
"javalib/arm64/boot-bar.oat",
|
||||||
|
"javalib/arm64/boot-bar.vdex",
|
||||||
|
"javalib/bar.jar",
|
||||||
|
"javalib/foo.jar",
|
||||||
|
})
|
||||||
|
|
||||||
|
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
|
||||||
|
`bar`,
|
||||||
|
`com.android.art.key`,
|
||||||
|
`mybootclasspathfragment`,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Make sure that the source bootclasspath_fragment copies its dex files to the predefined
|
||||||
|
// locations for the art image.
|
||||||
|
module := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
|
||||||
|
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("boot image files with preferred prebuilt", func(t *testing.T) {
|
||||||
result := android.GroupFixturePreparers(
|
result := android.GroupFixturePreparers(
|
||||||
commonPreparer,
|
commonPreparer,
|
||||||
|
|
||||||
|
@ -407,7 +461,13 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
||||||
`bar`,
|
`bar`,
|
||||||
`com.android.art.key`,
|
`com.android.art.key`,
|
||||||
`mybootclasspathfragment`,
|
`mybootclasspathfragment`,
|
||||||
|
`prebuilt_com.android.art`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
|
||||||
|
// locations for the art image.
|
||||||
|
module := result.ModuleForTests("prebuilt_mybootclasspathfragment", "android_common_com.android.art")
|
||||||
|
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("source with inconsistency between config and contents", func(t *testing.T) {
|
t.Run("source with inconsistency between config and contents", func(t *testing.T) {
|
||||||
|
@ -528,11 +588,36 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
||||||
`prebuilt_mybootclasspathfragment`,
|
`prebuilt_mybootclasspathfragment`,
|
||||||
})
|
})
|
||||||
|
|
||||||
java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common", []string{
|
java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_com.android.art", []string{
|
||||||
`dex2oatd`,
|
`dex2oatd`,
|
||||||
`prebuilt_bar`,
|
`prebuilt_bar`,
|
||||||
`prebuilt_foo`,
|
`prebuilt_foo`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
module := result.ModuleForTests("mybootclasspathfragment", "android_common_com.android.art")
|
||||||
|
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the
|
||||||
|
// predefined locations of boot dex jars used as inputs for the ART boot image.
|
||||||
|
func checkCopiesToPredefinedLocationForArt(t *testing.T, config android.Config, module android.TestingModule, modules ...string) {
|
||||||
|
t.Helper()
|
||||||
|
bootJarLocations := []string{}
|
||||||
|
for _, output := range module.AllOutputs() {
|
||||||
|
output = android.StringRelativeToTop(config, output)
|
||||||
|
if strings.HasPrefix(output, "out/soong/test_device/dex_artjars_input/") {
|
||||||
|
bootJarLocations = append(bootJarLocations, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(bootJarLocations)
|
||||||
|
expected := []string{}
|
||||||
|
for _, m := range modules {
|
||||||
|
expected = append(expected, fmt.Sprintf("out/soong/test_device/dex_artjars_input/%s.jar", m))
|
||||||
|
}
|
||||||
|
sort.Strings(expected)
|
||||||
|
|
||||||
|
android.AssertArrayString(t, "copies to predefined locations for art", expected, bootJarLocations)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBootclasspathFragmentContentsNoName(t *testing.T) {
|
func TestBootclasspathFragmentContentsNoName(t *testing.T) {
|
||||||
|
|
|
@ -409,6 +409,13 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
|
||||||
// Perform hidden API processing.
|
// Perform hidden API processing.
|
||||||
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
|
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
|
||||||
|
|
||||||
|
if imageConfig != nil {
|
||||||
|
if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
|
||||||
|
// Copy the dex jars of this fragment's content modules to their predefined locations.
|
||||||
|
copyBootJarsToPredefinedLocations(ctx, hiddenAPIOutput.EncodedBootDexFilesByModule, imageConfig.dexPathsByModule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// A prebuilt fragment cannot contribute to an apex.
|
// A prebuilt fragment cannot contribute to an apex.
|
||||||
if !android.IsModulePrebuilt(ctx.Module()) {
|
if !android.IsModulePrebuilt(ctx.Module()) {
|
||||||
// Provide the apex content info.
|
// Provide the apex content info.
|
||||||
|
@ -417,6 +424,29 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shouldCopyBootFilesToPredefinedLocations determines whether the current module should copy boot
|
||||||
|
// files, e.g. boot dex jars or boot image files, to the predefined location expected by the rest
|
||||||
|
// of the build.
|
||||||
|
//
|
||||||
|
// This ensures that only a single module will copy its files to the image configuration.
|
||||||
|
func shouldCopyBootFilesToPredefinedLocations(ctx android.ModuleContext, imageConfig *bootImageConfig) bool {
|
||||||
|
// Bootclasspath fragment modules that are for the platform do not produce boot related files.
|
||||||
|
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
|
||||||
|
if apexInfo.IsForPlatform() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the image configuration has no modules specified then it means that the build has been
|
||||||
|
// configured to build something other than a boot image, e.g. an sdk, so do not try and copy the
|
||||||
|
// files.
|
||||||
|
if imageConfig.modules.Len() == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only copy files from the module that is preferred.
|
||||||
|
return isActiveModule(ctx.Module())
|
||||||
|
}
|
||||||
|
|
||||||
// provideApexContentInfo creates, initializes and stores the apex content info for use by other
|
// provideApexContentInfo creates, initializes and stores the apex content info for use by other
|
||||||
// modules.
|
// modules.
|
||||||
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIOutput *HiddenAPIOutput) {
|
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIOutput *HiddenAPIOutput) {
|
||||||
|
@ -635,10 +665,6 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the dex jars of this fragment's content modules to their predefined locations.
|
|
||||||
bootDexJarByModule := extractEncodedDexJarsFromModules(ctx, contents)
|
|
||||||
copyBootJarsToPredefinedLocations(ctx, bootDexJarByModule, imageConfig.dexPathsByModule)
|
|
||||||
|
|
||||||
// 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)
|
||||||
|
|
Loading…
Reference in a new issue