Allow installing boot images outside of APEX for prebuilt.
This change is similar to aosp/1947127, but for prebuilts. After this change, if `bootImageConfig.installDirOnDevice` is set to a path outside of the APEX, the build system will build a boot image from the dex files and the profile extracted from the prebuilt APEX. Otherwise, it keeps the current behavior: extracting the boot image from the prebuilt APEX. This is a no-op change. Current behavior is not affected. Bug: 211973309 Test: m nothing Test: - On internal master: 1. Patch aosp/1947128. 2. Patch ag/16743847 and ag/16746804. 3. m SOONG_CONFIG_art_module_source_build=false com.google.android.art 4. See the boot image being installed in `/system/framework/<arch>`. Change-Id: I24ca525309fecaf3ab7a67960fbf118cd00ecd1d
This commit is contained in:
@@ -553,12 +553,66 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
|||||||
`prebuilt_com.android.art`,
|
`prebuilt_com.android.art`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// The boot images are installed in the APEX by Soong, so there shouldn't be any dexpreopt-related Make modules.
|
||||||
|
ensureDoesNotContainRequiredDeps(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot.vdex",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot-bar.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot-bar.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot-bar.vdex",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot.vdex",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot-bar.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot-bar.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot-bar.vdex",
|
||||||
|
})
|
||||||
|
|
||||||
// Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
|
// Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
|
||||||
// locations for the art image.
|
// locations for the art image.
|
||||||
module := result.ModuleForTests("prebuilt_mybootclasspathfragment", "android_common_com.android.art")
|
module := result.ModuleForTests("prebuilt_mybootclasspathfragment", "android_common_com.android.art")
|
||||||
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("boot image files from preferred prebuilt no boot image in apex", 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"),
|
||||||
|
|
||||||
|
// Make sure that a preferred prebuilt with consistent contents doesn't affect the apex.
|
||||||
|
addPrebuilt(true, "foo", "bar"),
|
||||||
|
|
||||||
|
java.FixtureSetBootImageInstallDirOnDevice("art", "system/framework"),
|
||||||
|
).RunTest(t)
|
||||||
|
|
||||||
|
ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
|
||||||
|
"etc/boot-image.prof",
|
||||||
|
"etc/classpaths/bootclasspath.pb",
|
||||||
|
"javalib/bar.jar",
|
||||||
|
"javalib/foo.jar",
|
||||||
|
})
|
||||||
|
|
||||||
|
ensureContainsRequiredDeps(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot.vdex",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot-bar.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot-bar.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm64-boot-bar.vdex",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot.vdex",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot-bar.art",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot-bar.oat",
|
||||||
|
"mybootclasspathfragment-dexpreopt-arm-boot-bar.vdex",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
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) {
|
||||||
android.GroupFixturePreparers(
|
android.GroupFixturePreparers(
|
||||||
commonPreparer,
|
commonPreparer,
|
||||||
@@ -631,6 +685,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
|||||||
|
|
||||||
// Configure some libraries in the art bootclasspath_fragment.
|
// Configure some libraries in the art bootclasspath_fragment.
|
||||||
java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
|
java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
|
||||||
|
java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
|
||||||
)
|
)
|
||||||
|
|
||||||
bp := `
|
bp := `
|
||||||
|
@@ -65,7 +65,8 @@ type prebuiltCommon struct {
|
|||||||
// Installed locations of symlinks for backward compatibility.
|
// Installed locations of symlinks for backward compatibility.
|
||||||
compatSymlinks android.InstallPaths
|
compatSymlinks android.InstallPaths
|
||||||
|
|
||||||
hostRequired []string
|
hostRequired []string
|
||||||
|
requiredModuleNames []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type sanitizedPrebuilt interface {
|
type sanitizedPrebuilt interface {
|
||||||
@@ -195,9 +196,19 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
|
p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
|
||||||
}
|
}
|
||||||
} else if tag == exportedBootclasspathFragmentTag ||
|
} else if tag == exportedBootclasspathFragmentTag {
|
||||||
tag == exportedSystemserverclasspathFragmentTag {
|
bcpfModule, ok := child.(*java.PrebuiltBootclasspathFragmentModule)
|
||||||
// Visit the children of the bootclasspath_fragment and systemserver_fragment.
|
if !ok {
|
||||||
|
ctx.PropertyErrorf("exported_bootclasspath_fragments", "%q is not a prebuilt_bootclasspath_fragment module", name)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
|
||||||
|
p.requiredModuleNames = append(p.requiredModuleNames, makeModuleName)
|
||||||
|
}
|
||||||
|
// Visit the children of the bootclasspath_fragment.
|
||||||
|
return true
|
||||||
|
} else if tag == exportedSystemserverclasspathFragmentTag {
|
||||||
|
// Visit the children of the systemserver_fragment.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,6 +222,7 @@ func (p *prebuiltCommon) addRequiredModules(entries *android.AndroidMkEntries) {
|
|||||||
entries.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", fi.targetRequiredModuleNames...)
|
entries.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", fi.targetRequiredModuleNames...)
|
||||||
entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", fi.hostRequiredModuleNames...)
|
entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", fi.hostRequiredModuleNames...)
|
||||||
}
|
}
|
||||||
|
entries.AddStrings("LOCAL_REQUIRED_MODULES", p.requiredModuleNames...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
|
func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
|
||||||
|
@@ -1071,7 +1071,7 @@ type prebuiltBootclasspathFragmentProperties struct {
|
|||||||
// At the moment this is basically just a bootclasspath_fragment module that can be used as a
|
// At the moment this is basically just a bootclasspath_fragment module that can be used as a
|
||||||
// prebuilt. Eventually as more functionality is migrated into the bootclasspath_fragment module
|
// prebuilt. Eventually as more functionality is migrated into the bootclasspath_fragment module
|
||||||
// type from the various singletons then this will diverge.
|
// type from the various singletons then this will diverge.
|
||||||
type prebuiltBootclasspathFragmentModule struct {
|
type PrebuiltBootclasspathFragmentModule struct {
|
||||||
BootclasspathFragmentModule
|
BootclasspathFragmentModule
|
||||||
prebuilt android.Prebuilt
|
prebuilt android.Prebuilt
|
||||||
|
|
||||||
@@ -1079,16 +1079,16 @@ type prebuiltBootclasspathFragmentModule struct {
|
|||||||
prebuiltProperties prebuiltBootclasspathFragmentProperties
|
prebuiltProperties prebuiltBootclasspathFragmentProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *prebuiltBootclasspathFragmentModule) Prebuilt() *android.Prebuilt {
|
func (module *PrebuiltBootclasspathFragmentModule) Prebuilt() *android.Prebuilt {
|
||||||
return &module.prebuilt
|
return &module.prebuilt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (module *prebuiltBootclasspathFragmentModule) Name() string {
|
func (module *PrebuiltBootclasspathFragmentModule) Name() string {
|
||||||
return module.prebuilt.Name(module.ModuleBase.Name())
|
return module.prebuilt.Name(module.ModuleBase.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
// produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified.
|
// produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified.
|
||||||
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
|
func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
|
||||||
pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path {
|
pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
return defaultPath
|
return defaultPath
|
||||||
@@ -1129,7 +1129,7 @@ func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
|
|||||||
}
|
}
|
||||||
|
|
||||||
// produceBootImageFiles extracts the boot image files from the APEX if available.
|
// produceBootImageFiles extracts the boot image files from the APEX if available.
|
||||||
func (module *prebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
|
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
|
||||||
if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
|
if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -1139,37 +1139,53 @@ func (module *prebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
|
|||||||
return nil // An error has been reported by FindDeapexerProviderForModule.
|
return nil // An error has been reported by FindDeapexerProviderForModule.
|
||||||
}
|
}
|
||||||
|
|
||||||
files := bootImageFilesByArch{}
|
profile := (android.WritablePath)(nil)
|
||||||
for _, variant := range imageConfig.apexVariants() {
|
if imageConfig.profileInstallPathInApex != "" {
|
||||||
arch := variant.target.Arch.ArchType
|
profile = di.PrebuiltExportPath(imageConfig.profileInstallPathInApex)
|
||||||
for _, toPath := range variant.imagesDeps {
|
|
||||||
apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base())
|
|
||||||
// Get the path to the file that the deapexer extracted from the prebuilt apex file.
|
|
||||||
fromPath := di.PrebuiltExportPath(apexRelativePath)
|
|
||||||
|
|
||||||
// Return the toPath as the calling code expects the paths in the returned map to be the
|
|
||||||
// paths predefined in the bootImageConfig.
|
|
||||||
files[arch] = append(files[arch], toPath)
|
|
||||||
|
|
||||||
// Copy the file to the predefined location.
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: android.Cp,
|
|
||||||
Input: fromPath,
|
|
||||||
Output: toPath,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the boot image files for the host variants. These are built from the dex files provided
|
// Build the boot image files for the host variants. These are always built from the dex files
|
||||||
// by the contents of this module as prebuilt versions of the host boot image files are not
|
// provided by the contents of this module as prebuilt versions of the host boot image files are
|
||||||
// available, i.e. there is no host specific prebuilt apex containing them. This has to be built
|
// not available, i.e. there is no host specific prebuilt apex containing them. This has to be
|
||||||
// without a profile as the prebuilt modules do not provide a profile.
|
// built without a profile as the prebuilt modules do not provide a profile.
|
||||||
buildBootImageVariantsForBuildOs(ctx, imageConfig, nil)
|
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
|
||||||
|
|
||||||
return files
|
if imageConfig.shouldInstallInApex() {
|
||||||
|
// If the boot image files for the android variants are in the prebuilt apex, we must use those
|
||||||
|
// rather than building new ones because those boot image files are going to be used on device.
|
||||||
|
files := bootImageFilesByArch{}
|
||||||
|
for _, variant := range imageConfig.apexVariants() {
|
||||||
|
arch := variant.target.Arch.ArchType
|
||||||
|
for _, toPath := range variant.imagesDeps {
|
||||||
|
apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base())
|
||||||
|
// Get the path to the file that the deapexer extracted from the prebuilt apex file.
|
||||||
|
fromPath := di.PrebuiltExportPath(apexRelativePath)
|
||||||
|
|
||||||
|
// Return the toPath as the calling code expects the paths in the returned map to be the
|
||||||
|
// paths predefined in the bootImageConfig.
|
||||||
|
files[arch] = append(files[arch], toPath)
|
||||||
|
|
||||||
|
// Copy the file to the predefined location.
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: android.Cp,
|
||||||
|
Input: fromPath,
|
||||||
|
Output: toPath,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files
|
||||||
|
} else {
|
||||||
|
if profile == nil {
|
||||||
|
ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Build boot image files for the android variants from the dex files provided by the contents
|
||||||
|
// of this module.
|
||||||
|
return buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ commonBootclasspathFragment = (*prebuiltBootclasspathFragmentModule)(nil)
|
var _ commonBootclasspathFragment = (*PrebuiltBootclasspathFragmentModule)(nil)
|
||||||
|
|
||||||
// createBootImageTag creates the tag to uniquely identify the boot image file among all of the
|
// createBootImageTag creates the tag to uniquely identify the boot image file among all of the
|
||||||
// files that a module requires from the prebuilt .apex file.
|
// files that a module requires from the prebuilt .apex file.
|
||||||
@@ -1183,16 +1199,22 @@ func createBootImageTag(arch android.ArchType, baseName string) string {
|
|||||||
//
|
//
|
||||||
// If there is no image config associated with this fragment then it returns nil. Otherwise, it
|
// If there is no image config associated with this fragment then it returns nil. Otherwise, it
|
||||||
// returns the files that are listed in the image config.
|
// returns the files that are listed in the image config.
|
||||||
func (module *prebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
|
func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
|
||||||
imageConfig := module.getImageConfig(ctx)
|
imageConfig := module.getImageConfig(ctx)
|
||||||
if imageConfig != nil {
|
if imageConfig != nil {
|
||||||
// Add the boot image files, e.g. .art, .oat and .vdex files.
|
|
||||||
files := []string{}
|
files := []string{}
|
||||||
for _, variant := range imageConfig.apexVariants() {
|
if imageConfig.profileInstallPathInApex != "" {
|
||||||
arch := variant.target.Arch.ArchType
|
// Add the boot image profile.
|
||||||
for _, path := range variant.imagesDeps.Paths() {
|
files = append(files, imageConfig.profileInstallPathInApex)
|
||||||
base := path.Base()
|
}
|
||||||
files = append(files, apexRootRelativePathToBootImageFile(arch, base))
|
if imageConfig.shouldInstallInApex() {
|
||||||
|
// Add the boot image files, e.g. .art, .oat and .vdex files.
|
||||||
|
for _, variant := range imageConfig.apexVariants() {
|
||||||
|
arch := variant.target.Arch.ArchType
|
||||||
|
for _, path := range variant.imagesDeps.Paths() {
|
||||||
|
base := path.Base()
|
||||||
|
files = append(files, apexRootRelativePathToBootImageFile(arch, base))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return files
|
return files
|
||||||
@@ -1204,10 +1226,10 @@ func apexRootRelativePathToBootImageFile(arch android.ArchType, base string) str
|
|||||||
return filepath.Join("javalib", arch.String(), base)
|
return filepath.Join("javalib", arch.String(), base)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltBootclasspathFragmentModule)(nil)
|
var _ android.RequiredFilesFromPrebuiltApex = (*PrebuiltBootclasspathFragmentModule)(nil)
|
||||||
|
|
||||||
func prebuiltBootclasspathFragmentFactory() android.Module {
|
func prebuiltBootclasspathFragmentFactory() android.Module {
|
||||||
m := &prebuiltBootclasspathFragmentModule{}
|
m := &PrebuiltBootclasspathFragmentModule{}
|
||||||
m.AddProperties(&m.properties, &m.prebuiltProperties)
|
m.AddProperties(&m.properties, &m.prebuiltProperties)
|
||||||
// This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
|
// This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
|
||||||
// array.
|
// array.
|
||||||
|
Reference in New Issue
Block a user