Refactor dexpreopt for boot jars to make it flexible to config changes. am: cb13b5d1bd
am: 0c03078eb1
am: d69968ad43
am: 670f82e021
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2652081 Change-Id: I262a01d6cd5bf6890f3997112c7178e73987d5a3 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -315,7 +315,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
||||
|
||||
// Make sure that the source bootclasspath_fragment copies its dex files to the predefined
|
||||
// locations for the art image.
|
||||
module := result.ModuleForTests("art-bootclasspath-fragment", "android_common_apex10000")
|
||||
module := result.ModuleForTests("dex_bootjars", "android_common")
|
||||
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||
})
|
||||
|
||||
@@ -386,7 +386,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
||||
|
||||
// Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
|
||||
// locations for the art image.
|
||||
module := result.ModuleForTests("prebuilt_art-bootclasspath-fragment", "android_common_com.android.art")
|
||||
module := result.ModuleForTests("dex_bootjars", "android_common")
|
||||
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||
})
|
||||
|
||||
@@ -537,7 +537,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
||||
`prebuilt_foo`,
|
||||
})
|
||||
|
||||
module := result.ModuleForTests("art-bootclasspath-fragment", "android_common_com.android.art")
|
||||
module := result.ModuleForTests("dex_bootjars", "android_common")
|
||||
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||
})
|
||||
|
||||
|
@@ -138,8 +138,8 @@ func testDexpreoptBoot(t *testing.T, ruleFile string, expectedInputs, expectedOu
|
||||
prepareForTestWithArtApex,
|
||||
).RunTestWithBp(t, fmt.Sprintf(bp, preferPrebuilt))
|
||||
|
||||
platformBootclasspath := result.ModuleForTests("platform-bootclasspath", "android_common")
|
||||
rule := platformBootclasspath.Output(ruleFile)
|
||||
dexBootJars := result.ModuleForTests("dex_bootjars", "android_common")
|
||||
rule := dexBootJars.Output(ruleFile)
|
||||
|
||||
inputs := rule.Implicits.Strings()
|
||||
sort.Strings(inputs)
|
||||
@@ -162,8 +162,8 @@ func TestDexpreoptBootJarsWithSourceArtApex(t *testing.T) {
|
||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar",
|
||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar",
|
||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
|
||||
"out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/art/boot.prof",
|
||||
"out/soong/.intermediates/platform-bootclasspath/android_common/boot/boot.prof",
|
||||
"out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/art-bootclasspath-fragment/boot.prof",
|
||||
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
|
||||
}
|
||||
|
||||
expectedOutputs := []string{
|
||||
@@ -200,7 +200,7 @@ func TestDexpreoptBootJarsWithPrebuiltArtApex(t *testing.T) {
|
||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar",
|
||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
|
||||
"out/soong/.intermediates/com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof",
|
||||
"out/soong/.intermediates/platform-bootclasspath/android_common/boot/boot.prof",
|
||||
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
|
||||
}
|
||||
|
||||
expectedOutputs := []string{
|
||||
|
@@ -185,6 +185,9 @@ var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{}
|
||||
// The tag used for dependencies onto bootclasspath_fragments.
|
||||
var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"}
|
||||
|
||||
// The tag used for dependencies onto platform_bootclasspath.
|
||||
var platformBootclasspathDepTag = bootclasspathDependencyTag{name: "platform"}
|
||||
|
||||
// BootclasspathNestedAPIProperties defines properties related to the API provided by parts of the
|
||||
// bootclasspath that are nested within the main BootclasspathAPIProperties.
|
||||
type BootclasspathNestedAPIProperties struct {
|
||||
|
@@ -242,7 +242,7 @@ type BootclasspathFragmentModule struct {
|
||||
modulePaths []string
|
||||
|
||||
// Path to the boot image profile.
|
||||
profilePath android.Path
|
||||
profilePath android.WritablePath
|
||||
}
|
||||
|
||||
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
|
||||
@@ -256,16 +256,6 @@ type commonBootclasspathFragment interface {
|
||||
// versioned sdk.
|
||||
produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
|
||||
|
||||
// produceBootImageFiles will attempt to produce rules to create the boot image files at the paths
|
||||
// predefined in the bootImageConfig.
|
||||
//
|
||||
// If it could not create the files then it will return nil. Otherwise, it will return a map from
|
||||
// android.ArchType to the predefined paths of the boot image files.
|
||||
produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs
|
||||
|
||||
// getImageName returns the `image_name` property of this fragment.
|
||||
getImageName() *string
|
||||
|
||||
// getProfilePath returns the path to the boot image profile.
|
||||
getProfilePath() android.Path
|
||||
}
|
||||
@@ -295,9 +285,6 @@ func bootclasspathFragmentFactory() android.Module {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the contents property from the image_name.
|
||||
bootclasspathFragmentInitContentsFromImage(ctx, m)
|
||||
})
|
||||
return m
|
||||
}
|
||||
@@ -308,9 +295,7 @@ func testBootclasspathFragmentFactory() android.Module {
|
||||
return m
|
||||
}
|
||||
|
||||
// bootclasspathFragmentInitContentsFromImage will initialize the contents property from the image_name if
|
||||
// necessary.
|
||||
func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext, m *BootclasspathFragmentModule) {
|
||||
func (m *BootclasspathFragmentModule) bootclasspathFragmentPropertyCheck(ctx android.EarlyModuleContext) {
|
||||
contents := m.properties.Contents
|
||||
if len(contents) == 0 {
|
||||
ctx.PropertyErrorf("contents", "required property is missing")
|
||||
@@ -332,6 +317,18 @@ func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext,
|
||||
// too early in the Soong processing for that to work.
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
modules := global.ArtApexJars
|
||||
configuredJars := modules.CopyOfJars()
|
||||
|
||||
// Skip the check if the configured jars list is empty as that is a common configuration when
|
||||
// building targets that do not result in a system image.
|
||||
if len(configuredJars) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(configuredJars, contents) {
|
||||
ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v",
|
||||
configuredJars, contents)
|
||||
}
|
||||
|
||||
// Make sure that the apex specified in the configuration is consistent and is one for which
|
||||
// this boot image is available.
|
||||
@@ -357,33 +354,6 @@ func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext,
|
||||
}
|
||||
}
|
||||
|
||||
// bootclasspathImageNameContentsConsistencyCheck checks that the configuration that applies to this
|
||||
// module (if any) matches the contents.
|
||||
//
|
||||
// This should be a noop as if image_name="art" then the contents will be set from the ArtApexJars
|
||||
// config by bootclasspathFragmentInitContentsFromImage so it will be guaranteed to match. However,
|
||||
// in future this will not be the case.
|
||||
func (b *BootclasspathFragmentModule) bootclasspathImageNameContentsConsistencyCheck(ctx android.BaseModuleContext) {
|
||||
imageName := proptools.String(b.properties.Image_name)
|
||||
if imageName == "art" {
|
||||
// Get the configuration for the art apex jars.
|
||||
modules := b.getImageConfig(ctx).modules
|
||||
configuredJars := modules.CopyOfJars()
|
||||
|
||||
// Skip the check if the configured jars list is empty as that is a common configuration when
|
||||
// building targets that do not result in a system image.
|
||||
if len(configuredJars) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
contents := b.properties.Contents
|
||||
if !reflect.DeepEqual(configuredJars, contents) {
|
||||
ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v",
|
||||
configuredJars, contents)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var BootclasspathFragmentApexContentInfoProvider = blueprint.NewProvider(BootclasspathFragmentApexContentInfo{})
|
||||
|
||||
// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
|
||||
@@ -495,7 +465,7 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
|
||||
// unused prebuilt that was created without instrumentation from breaking an instrumentation
|
||||
// build.
|
||||
if isActiveModule(ctx.Module()) {
|
||||
b.bootclasspathImageNameContentsConsistencyCheck(ctx)
|
||||
b.bootclasspathFragmentPropertyCheck(ctx)
|
||||
}
|
||||
|
||||
// Generate classpaths.proto config
|
||||
@@ -515,34 +485,15 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
|
||||
|
||||
fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
|
||||
|
||||
// Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a
|
||||
// prebuilt which will not use the image config.
|
||||
imageConfig := b.getImageConfig(ctx)
|
||||
|
||||
// Perform hidden API processing.
|
||||
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
|
||||
|
||||
var bootImageFiles bootImageOutputs
|
||||
if imageConfig != nil {
|
||||
// Delegate the production of the boot image files to a module type specific method.
|
||||
common := ctx.Module().(commonBootclasspathFragment)
|
||||
bootImageFiles = common.produceBootImageFiles(ctx, imageConfig)
|
||||
b.profilePath = bootImageFiles.profile
|
||||
|
||||
if shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
|
||||
// Zip the boot image files up, if available. This will generate the zip file in a
|
||||
// predefined location.
|
||||
buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFiles.byArch)
|
||||
|
||||
// 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.
|
||||
if !android.IsModulePrebuilt(ctx.Module()) {
|
||||
// Provide the apex content info.
|
||||
b.provideApexContentInfo(ctx, imageConfig, hiddenAPIOutput, bootImageFiles)
|
||||
if android.IsModulePrebuilt(ctx.Module()) {
|
||||
b.profilePath = ctx.Module().(*PrebuiltBootclasspathFragmentModule).produceBootImageProfile(ctx)
|
||||
} else {
|
||||
b.profilePath = b.produceBootImageProfileFromSource(ctx, contents, hiddenAPIOutput.EncodedBootDexFilesByModule)
|
||||
// Provide the apex content info. A prebuilt fragment cannot contribute to an apex.
|
||||
b.provideApexContentInfo(ctx, hiddenAPIOutput, b.profilePath)
|
||||
}
|
||||
|
||||
// In order for information about bootclasspath_fragment modules to be added to module-info.json
|
||||
@@ -556,44 +507,37 @@ 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 {
|
||||
// getProfileProviderApex returns the name of the apex that provides a boot image profile, or an
|
||||
// empty string if this module should not provide a boot image profile.
|
||||
func (b *BootclasspathFragmentModule) getProfileProviderApex(ctx android.BaseModuleContext) string {
|
||||
// Only use the profile from the module that is preferred.
|
||||
if !isActiveModule(ctx.Module()) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 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
|
||||
for _, apex := range apexInfo.InApexVariants {
|
||||
if isProfileProviderApex(ctx, apex) {
|
||||
return apex
|
||||
}
|
||||
}
|
||||
|
||||
// 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())
|
||||
return ""
|
||||
}
|
||||
|
||||
// provideApexContentInfo creates, initializes and stores the apex content info for use by other
|
||||
// modules.
|
||||
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, hiddenAPIOutput *HiddenAPIOutput, bootImageFiles bootImageOutputs) {
|
||||
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, hiddenAPIOutput *HiddenAPIOutput, profile android.WritablePath) {
|
||||
// Construct the apex content info from the config.
|
||||
info := BootclasspathFragmentApexContentInfo{
|
||||
// Populate the apex content info with paths to the dex jars.
|
||||
contentModuleDexJarPaths: hiddenAPIOutput.EncodedBootDexFilesByModule,
|
||||
}
|
||||
|
||||
if imageConfig != nil {
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
if !global.DisableGenerateProfile {
|
||||
info.profilePathOnHost = bootImageFiles.profile
|
||||
info.profileInstallPathInApex = imageConfig.profileInstallPathInApex
|
||||
}
|
||||
if profile != nil {
|
||||
info.profilePathOnHost = profile
|
||||
info.profileInstallPathInApex = profileInstallPathInApex
|
||||
}
|
||||
|
||||
// Make the apex content info available for other modules.
|
||||
@@ -614,12 +558,12 @@ func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx and
|
||||
}
|
||||
|
||||
func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
|
||||
if "art" == proptools.String(b.properties.Image_name) {
|
||||
return b.getImageConfig(ctx).modules
|
||||
}
|
||||
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
|
||||
if "art" == proptools.String(b.properties.Image_name) {
|
||||
return global.ArtApexJars
|
||||
}
|
||||
|
||||
possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, b.properties.Contents, bootclasspathFragmentContentDepTag)
|
||||
jars, unknown := global.ApexBootJars.Filter(possibleUpdatableModules)
|
||||
|
||||
@@ -645,25 +589,6 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext)
|
||||
return jars
|
||||
}
|
||||
|
||||
func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
|
||||
// Get a map of the image configs that are supported.
|
||||
imageConfigs := genBootImageConfigs(ctx)
|
||||
|
||||
// Retrieve the config for this image.
|
||||
imageNamePtr := b.properties.Image_name
|
||||
if imageNamePtr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
imageName := *imageNamePtr
|
||||
imageConfig := imageConfigs[imageName]
|
||||
if imageConfig == nil {
|
||||
ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedKeys(imageConfigs), ", "))
|
||||
return nil
|
||||
}
|
||||
return imageConfig
|
||||
}
|
||||
|
||||
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
|
||||
func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIOutput {
|
||||
|
||||
@@ -846,48 +771,22 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
|
||||
return output
|
||||
}
|
||||
|
||||
// produceBootImageFiles builds the boot image files from the source if it is required.
|
||||
func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
|
||||
// Only generate the boot image if the configuration does not skip it.
|
||||
return b.generateBootImageBuildActions(ctx, imageConfig)
|
||||
}
|
||||
|
||||
// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
|
||||
// module.
|
||||
//
|
||||
// If it could not create the files then it will return nil. Otherwise, it will return a map from
|
||||
// android.ArchType to the predefined paths of the boot image files.
|
||||
func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
if !shouldBuildBootImages(ctx.Config(), global) {
|
||||
return bootImageOutputs{}
|
||||
// produceBootImageProfileFromSource builds the boot image profile from the source if it is required.
|
||||
func (b *BootclasspathFragmentModule) produceBootImageProfileFromSource(ctx android.ModuleContext, contents []android.Module, modules bootDexJarByModule) android.WritablePath {
|
||||
apex := b.getProfileProviderApex(ctx)
|
||||
if apex == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 bootImageOutputs{}
|
||||
dexPaths := make(android.Paths, 0, len(contents))
|
||||
dexLocations := make([]string, 0, len(contents))
|
||||
for _, module := range contents {
|
||||
dexPaths = append(dexPaths, modules[module.Name()])
|
||||
dexLocations = append(dexLocations, filepath.Join("/", "apex", apex, "javalib", module.Name() + ".jar"))
|
||||
}
|
||||
|
||||
// Build a profile for the image config and then use that to build the boot image.
|
||||
profile := bootImageProfileRule(ctx, imageConfig)
|
||||
|
||||
// If dexpreopt of boot image jars should be skipped, generate only a profile.
|
||||
if SkipDexpreoptBootJars(ctx) {
|
||||
return bootImageOutputs{
|
||||
profile: profile,
|
||||
}
|
||||
}
|
||||
|
||||
// Build boot image files for the host variants.
|
||||
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
|
||||
|
||||
// Build boot image files for the android variants.
|
||||
bootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
|
||||
|
||||
// Return the boot image files for the android variants for inclusion in an APEX and to be zipped
|
||||
// up for the dist.
|
||||
return bootImageFiles
|
||||
// Build a profile for the modules in this fragment.
|
||||
return bootImageProfileRuleCommon(ctx, b.Name(), dexPaths, dexLocations)
|
||||
}
|
||||
|
||||
func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntries {
|
||||
@@ -910,10 +809,6 @@ func (b *BootclasspathFragmentModule) AndroidMkEntries() []android.AndroidMkEntr
|
||||
return entriesList
|
||||
}
|
||||
|
||||
func (b *BootclasspathFragmentModule) getImageName() *string {
|
||||
return b.properties.Image_name
|
||||
}
|
||||
|
||||
func (b *BootclasspathFragmentModule) getProfilePath() android.Path {
|
||||
return b.profilePath
|
||||
}
|
||||
@@ -1183,39 +1078,19 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
|
||||
return &output
|
||||
}
|
||||
|
||||
// produceBootImageFiles extracts the boot image files from the APEX if available.
|
||||
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
|
||||
if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
|
||||
return bootImageOutputs{}
|
||||
// produceBootImageProfile extracts the boot image profile from the APEX if available.
|
||||
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx android.ModuleContext) android.WritablePath {
|
||||
// This module does not provide a boot image profile.
|
||||
if module.getProfileProviderApex(ctx) == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
di := android.FindDeapexerProviderForModule(ctx)
|
||||
if di == nil {
|
||||
return bootImageOutputs{} // An error has been reported by FindDeapexerProviderForModule.
|
||||
return nil // An error has been reported by FindDeapexerProviderForModule.
|
||||
}
|
||||
|
||||
profile := (android.WritablePath)(nil)
|
||||
if imageConfig.profileInstallPathInApex != "" {
|
||||
profile = di.PrebuiltExportPath(imageConfig.profileInstallPathInApex)
|
||||
}
|
||||
|
||||
// Build the boot image files for the host variants. These are always built from the dex files
|
||||
// provided by the contents of this module as prebuilt versions of the host boot image files are
|
||||
// not available, i.e. there is no host specific prebuilt apex containing them. This has to be
|
||||
// built without a profile as the prebuilt modules do not provide a profile.
|
||||
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
|
||||
|
||||
if profile == nil && imageConfig.isProfileGuided() {
|
||||
ctx.ModuleErrorf("Unable to produce boot image files: profiles not found in the prebuilt apex")
|
||||
return bootImageOutputs{}
|
||||
}
|
||||
// Build boot image files for the android variants from the dex files provided by the contents
|
||||
// of this module.
|
||||
return buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
|
||||
}
|
||||
|
||||
func (b *PrebuiltBootclasspathFragmentModule) getImageName() *string {
|
||||
return b.properties.Image_name
|
||||
return di.PrebuiltExportPath(profileInstallPathInApex)
|
||||
}
|
||||
|
||||
func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path {
|
||||
@@ -1230,14 +1105,10 @@ var _ commonBootclasspathFragment = (*PrebuiltBootclasspathFragmentModule)(nil)
|
||||
// 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.
|
||||
func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
|
||||
imageConfig := module.getImageConfig(ctx)
|
||||
if imageConfig != nil {
|
||||
files := []string{}
|
||||
if imageConfig.profileInstallPathInApex != "" {
|
||||
// Add the boot image profile.
|
||||
files = append(files, imageConfig.profileInstallPathInApex)
|
||||
for _, apex := range module.ApexProperties.Apex_available {
|
||||
if isProfileProviderApex(ctx, apex) {
|
||||
return []string{profileInstallPathInApex}
|
||||
}
|
||||
return files
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1253,9 +1124,5 @@ func prebuiltBootclasspathFragmentFactory() android.Module {
|
||||
android.InitApexModule(m)
|
||||
android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
|
||||
|
||||
// Initialize the contents property from the image_name.
|
||||
android.AddLoadHook(m, func(ctx android.LoadHookContext) {
|
||||
bootclasspathFragmentInitContentsFromImage(ctx, &m.BootclasspathFragmentModule)
|
||||
})
|
||||
return m
|
||||
}
|
||||
|
@@ -16,7 +16,6 @@ package java
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"android/soong/android"
|
||||
@@ -224,6 +223,11 @@ var artApexNames = []string{
|
||||
"com.google.android.art.testing",
|
||||
}
|
||||
|
||||
var (
|
||||
dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"}
|
||||
dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments")
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterDexpreoptBootJarsComponents(android.InitRegistrationContext)
|
||||
}
|
||||
@@ -241,6 +245,9 @@ type bootImageConfig struct {
|
||||
// Image name (used in directory names and ninja rule names).
|
||||
name string
|
||||
|
||||
// If the module with the given name exists, this config is enabled.
|
||||
enabledIfExists string
|
||||
|
||||
// Basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}.
|
||||
stem string
|
||||
|
||||
@@ -257,10 +264,6 @@ type bootImageConfig struct {
|
||||
// the location is relative to "/".
|
||||
installDir string
|
||||
|
||||
// Install path of the boot image profile if it needs to be installed in the APEX, or empty if not
|
||||
// needed.
|
||||
profileInstallPathInApex string
|
||||
|
||||
// A list of (location, jar) pairs for the Java modules in this image.
|
||||
modules android.ConfiguredJarList
|
||||
|
||||
@@ -296,10 +299,9 @@ type bootImageConfig struct {
|
||||
// The "--single-image" argument.
|
||||
singleImage bool
|
||||
|
||||
// Profiles imported from other boot image configs. Each element must represent a
|
||||
// `bootclasspath_fragment` of an APEX (i.e., the `name` field of each element must refer to the
|
||||
// `image_name` property of a `bootclasspath_fragment`).
|
||||
profileImports []*bootImageConfig
|
||||
// Profiles imported from APEXes, in addition to the profile at the default path. Each entry must
|
||||
// be the name of an APEX module.
|
||||
profileImports []string
|
||||
}
|
||||
|
||||
// Target-dependent description of a boot image.
|
||||
@@ -458,18 +460,26 @@ func (image *bootImageConfig) isProfileGuided() bool {
|
||||
return image.compilerFilter == "speed-profile"
|
||||
}
|
||||
|
||||
func (image *bootImageConfig) isEnabled(ctx android.BaseModuleContext) bool {
|
||||
return ctx.OtherModuleExists(image.enabledIfExists)
|
||||
}
|
||||
|
||||
func dexpreoptBootJarsFactory() android.SingletonModule {
|
||||
m := &dexpreoptBootJars{}
|
||||
android.InitAndroidModule(m)
|
||||
android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
|
||||
return m
|
||||
}
|
||||
|
||||
func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
|
||||
ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory)
|
||||
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
||||
ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator).Parallel()
|
||||
})
|
||||
}
|
||||
|
||||
func SkipDexpreoptBootJars(ctx android.PathContext) bool {
|
||||
return dexpreopt.GetGlobalConfig(ctx).DisablePreoptBootImages
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
return global.DisablePreoptBootImages || !shouldBuildBootImages(ctx.Config(), global)
|
||||
}
|
||||
|
||||
// Singleton module for generating boot image build rules.
|
||||
@@ -492,38 +502,90 @@ type dexpreoptBootJars struct {
|
||||
dexpreoptConfigForMake android.WritablePath
|
||||
}
|
||||
|
||||
// Provide paths to boot images for use by modules that depend upon them.
|
||||
//
|
||||
// The build rules are created in GenerateSingletonBuildActions().
|
||||
func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
// Placeholder for now.
|
||||
func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) {
|
||||
if _, ok := ctx.Module().(*dexpreoptBootJars); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if dexpreopt.IsDex2oatNeeded(ctx) {
|
||||
// Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
|
||||
// path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
|
||||
dexpreopt.RegisterToolDeps(ctx)
|
||||
}
|
||||
|
||||
imageConfigs := genBootImageConfigs(ctx)
|
||||
for _, config := range imageConfigs {
|
||||
if !config.isEnabled(ctx) {
|
||||
continue
|
||||
}
|
||||
// For accessing the boot jars.
|
||||
addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag)
|
||||
}
|
||||
|
||||
if ctx.OtherModuleExists("platform-bootclasspath") {
|
||||
// For accessing all bootclasspath fragments.
|
||||
addDependencyOntoApexModulePair(ctx, "platform", "platform-bootclasspath", platformBootclasspathDepTag)
|
||||
} else if ctx.OtherModuleExists("art-bootclasspath-fragment") {
|
||||
// For accessing the ART bootclasspath fragment on a thin manifest (e.g., master-art) where
|
||||
// platform-bootclasspath doesn't exist.
|
||||
addDependencyOntoApexModulePair(ctx, "com.android.art", "art-bootclasspath-fragment", bootclasspathFragmentDepTag)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate build rules for boot images.
|
||||
func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) {
|
||||
if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil {
|
||||
// No module has enabled dexpreopting, so we assume there will be no boot image to make.
|
||||
return
|
||||
}
|
||||
d.dexpreoptConfigForMake = android.PathForOutput(ctx, getDexpreoptDirName(ctx), "dexpreopt.config")
|
||||
writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
|
||||
func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module {
|
||||
return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} {
|
||||
fragments := make(map[string]android.Module)
|
||||
ctx.WalkDeps(func(child, parent android.Module) bool {
|
||||
if !isActiveModule(child) {
|
||||
return false
|
||||
}
|
||||
tag := ctx.OtherModuleDependencyTag(child)
|
||||
if tag == platformBootclasspathDepTag {
|
||||
return true
|
||||
}
|
||||
if tag == bootclasspathFragmentDepTag {
|
||||
apexInfo := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo)
|
||||
for _, apex := range apexInfo.InApexVariants {
|
||||
fragments[apex] = child
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
})
|
||||
return fragments
|
||||
}).(map[string]android.Module)
|
||||
}
|
||||
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
if !shouldBuildBootImages(ctx.Config(), global) {
|
||||
return
|
||||
}
|
||||
func getBootclasspathFragmentByApex(ctx android.ModuleContext, apexName string) android.Module {
|
||||
return gatherBootclasspathFragments(ctx)[apexName]
|
||||
}
|
||||
|
||||
defaultImageConfig := defaultBootImageConfig(ctx)
|
||||
d.defaultBootImage = defaultImageConfig
|
||||
// GenerateAndroidBuildActions generates the build rules for boot images.
|
||||
func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||
imageConfigs := genBootImageConfigs(ctx)
|
||||
d.defaultBootImage = defaultBootImageConfig(ctx)
|
||||
d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1)
|
||||
for _, config := range imageConfigs {
|
||||
if config != defaultImageConfig {
|
||||
for _, name := range getImageNames() {
|
||||
config := imageConfigs[name]
|
||||
if config != d.defaultBootImage {
|
||||
d.otherImages = append(d.otherImages, config)
|
||||
}
|
||||
if !config.isEnabled(ctx) {
|
||||
continue
|
||||
}
|
||||
generateBootImage(ctx, config)
|
||||
if config == d.defaultBootImage {
|
||||
bootFrameworkProfileRule(ctx, config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateSingletonBuildActions generates build rules for the dexpreopt config for Make.
|
||||
func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) {
|
||||
d.dexpreoptConfigForMake = android.PathForOutput(ctx, getDexpreoptDirName(ctx), "dexpreopt.config")
|
||||
writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
|
||||
}
|
||||
|
||||
// shouldBuildBootImages determines whether boot images should be built.
|
||||
func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig) bool {
|
||||
// Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
|
||||
@@ -536,6 +598,101 @@ func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig
|
||||
return true
|
||||
}
|
||||
|
||||
func generateBootImage(ctx android.ModuleContext, imageConfig *bootImageConfig) {
|
||||
apexJarModulePairs := getModulesForImage(ctx, imageConfig)
|
||||
|
||||
// Copy module dex jars to their predefined locations.
|
||||
bootDexJarsByModule := extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx, apexJarModulePairs)
|
||||
copyBootJarsToPredefinedLocations(ctx, bootDexJarsByModule, imageConfig.dexPathsByModule)
|
||||
|
||||
// Build a profile for the image config from the profile at the default path. The profile will
|
||||
// then be used along with profiles imported from APEXes to build the boot image.
|
||||
profile := bootImageProfileRule(ctx, imageConfig)
|
||||
|
||||
// If dexpreopt of boot image jars should be skipped, stop after generating a profile.
|
||||
if SkipDexpreoptBootJars(ctx) {
|
||||
return
|
||||
}
|
||||
|
||||
// Build boot image files for the android variants.
|
||||
androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
|
||||
|
||||
// Zip the android variant boot image files up.
|
||||
buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch)
|
||||
|
||||
// Build boot image files for the host variants. There are use directly by ART host side tests.
|
||||
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
|
||||
|
||||
// Create a `dump-oat-<image-name>` rule that runs `oatdump` for debugging purposes.
|
||||
dumpOatRules(ctx, imageConfig)
|
||||
}
|
||||
|
||||
type apexJarModulePair struct {
|
||||
apex string
|
||||
jarModule android.Module
|
||||
}
|
||||
|
||||
func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []apexJarModulePair {
|
||||
modules := make([]apexJarModulePair, 0, imageConfig.modules.Len())
|
||||
for i := 0; i < imageConfig.modules.Len(); i++ {
|
||||
found := false
|
||||
for _, module := range gatherApexModulePairDepsWithTag(ctx, dexpreoptBootJarDepTag) {
|
||||
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
|
||||
if name == imageConfig.modules.Jar(i) {
|
||||
modules = append(modules, apexJarModulePair{
|
||||
apex: imageConfig.modules.Apex(i),
|
||||
jarModule: module,
|
||||
})
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found && !ctx.Config().AllowMissingDependencies() {
|
||||
ctx.ModuleErrorf(
|
||||
"Boot image '%s' module '%s' not added as a dependency of dex_bootjars",
|
||||
imageConfig.name,
|
||||
imageConfig.modules.Jar(i))
|
||||
return []apexJarModulePair{}
|
||||
}
|
||||
}
|
||||
return modules
|
||||
}
|
||||
|
||||
// extractEncodedDexJarsFromModulesOrBootclasspathFragments gets the hidden API encoded dex jars for
|
||||
// the given modules.
|
||||
func extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx android.ModuleContext, apexJarModulePairs []apexJarModulePair) bootDexJarByModule {
|
||||
encodedDexJarsByModuleName := bootDexJarByModule{}
|
||||
for _, pair := range apexJarModulePairs {
|
||||
var path android.Path
|
||||
if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) {
|
||||
// This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API
|
||||
// files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for
|
||||
// a source APEX because there is no guarantee that it is the same as the jar packed into the
|
||||
// APEX. In practice, they are the same when we are building from a full source tree, but they
|
||||
// are different when we are building from a thin manifest (e.g., master-art), where there is
|
||||
// no monolithic hidden API files at all.
|
||||
path = retrieveEncodedBootDexJarFromModule(ctx, pair.jarModule)
|
||||
} else {
|
||||
// Use exactly the same jar that is packed into the APEX.
|
||||
fragment := getBootclasspathFragmentByApex(ctx, pair.apex)
|
||||
if fragment == nil {
|
||||
ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+
|
||||
"APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars",
|
||||
pair.jarModule.Name(),
|
||||
pair.apex)
|
||||
}
|
||||
bootclasspathFragmentInfo := ctx.OtherModuleProvider(fragment, BootclasspathFragmentApexContentInfoProvider).(BootclasspathFragmentApexContentInfo)
|
||||
jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule)
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf("%s", err)
|
||||
}
|
||||
path = jar
|
||||
}
|
||||
encodedDexJarsByModuleName.addPath(pair.jarModule, path)
|
||||
}
|
||||
return encodedDexJarsByModuleName
|
||||
}
|
||||
|
||||
// copyBootJarsToPredefinedLocations generates commands that will copy boot jars to predefined
|
||||
// paths in the global config.
|
||||
func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJarsByModule bootDexJarByModule, dstBootJarsByModule map[string]android.WritablePath) {
|
||||
@@ -686,10 +843,12 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
|
||||
rule.Command().Text("rm").Flag("-f").
|
||||
Flag(symbolsDir.Join(ctx, "*.art").String()).
|
||||
Flag(symbolsDir.Join(ctx, "*.oat").String()).
|
||||
Flag(symbolsDir.Join(ctx, "*.vdex").String()).
|
||||
Flag(symbolsDir.Join(ctx, "*.invocation").String())
|
||||
rule.Command().Text("rm").Flag("-f").
|
||||
Flag(outputDir.Join(ctx, "*.art").String()).
|
||||
Flag(outputDir.Join(ctx, "*.oat").String()).
|
||||
Flag(outputDir.Join(ctx, "*.vdex").String()).
|
||||
Flag(outputDir.Join(ctx, "*.invocation").String())
|
||||
|
||||
cmd := rule.Command()
|
||||
@@ -711,36 +870,31 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p
|
||||
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms).
|
||||
Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatImageXmx)
|
||||
|
||||
if profile != nil {
|
||||
cmd.FlagWithInput("--profile-file=", profile)
|
||||
}
|
||||
if image.isProfileGuided() && !global.DisableGenerateProfile {
|
||||
if profile != nil {
|
||||
cmd.FlagWithInput("--profile-file=", profile)
|
||||
}
|
||||
|
||||
fragments := make(map[string]commonBootclasspathFragment)
|
||||
ctx.VisitDirectDepsWithTag(bootclasspathFragmentDepTag, func(child android.Module) {
|
||||
fragment := child.(commonBootclasspathFragment)
|
||||
if fragment.getImageName() != nil && android.IsModulePreferred(child) {
|
||||
fragments[*fragment.getImageName()] = fragment
|
||||
for _, apex := range image.profileImports {
|
||||
fragment := getBootclasspathFragmentByApex(ctx, apex)
|
||||
if fragment == nil {
|
||||
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+
|
||||
"bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+
|
||||
"dependency of dex_bootjars",
|
||||
image.name,
|
||||
apex)
|
||||
return bootImageVariantOutputs{}
|
||||
}
|
||||
importedProfile := fragment.(commonBootclasspathFragment).getProfilePath()
|
||||
if importedProfile == nil {
|
||||
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
|
||||
"doesn't provide a profile",
|
||||
image.name,
|
||||
apex)
|
||||
return bootImageVariantOutputs{}
|
||||
}
|
||||
cmd.FlagWithInput("--profile-file=", importedProfile)
|
||||
}
|
||||
})
|
||||
|
||||
for _, profileImport := range image.profileImports {
|
||||
fragment := fragments[profileImport.name]
|
||||
if fragment == nil {
|
||||
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+
|
||||
"bootclasspath_fragment with image name '%[2]s' doesn't exist or is not added as a "+
|
||||
"dependency of '%[1]s'",
|
||||
image.name,
|
||||
profileImport.name)
|
||||
return bootImageVariantOutputs{}
|
||||
}
|
||||
if fragment.getProfilePath() == nil {
|
||||
ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+
|
||||
"doesn't provide a profile",
|
||||
image.name,
|
||||
profileImport.name)
|
||||
return bootImageVariantOutputs{}
|
||||
}
|
||||
cmd.FlagWithInput("--profile-file=", fragment.getProfilePath())
|
||||
}
|
||||
|
||||
dirtyImageFile := "frameworks/base/config/dirty-image-objects"
|
||||
@@ -1059,11 +1213,9 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
|
||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " "))
|
||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(dexLocations, " "))
|
||||
|
||||
var imageNames []string
|
||||
// The primary ART boot image is exposed to Make for testing (gtests) and benchmarking
|
||||
// (golem) purposes.
|
||||
for _, current := range append(d.otherImages, image) {
|
||||
imageNames = append(imageNames, current.name)
|
||||
for _, variant := range current.variants {
|
||||
suffix := ""
|
||||
if variant.target.Os.Class == android.Host {
|
||||
@@ -1084,8 +1236,6 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
|
||||
ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICE"+current.name, strings.Join(imageLocationsOnDevice, ":"))
|
||||
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
|
||||
}
|
||||
// Ensure determinism.
|
||||
sort.Strings(imageNames)
|
||||
ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
|
||||
ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(getImageNames(), " "))
|
||||
}
|
||||
}
|
||||
|
@@ -40,57 +40,68 @@ func dexpreoptTargets(ctx android.PathContext) []android.Target {
|
||||
}
|
||||
|
||||
var (
|
||||
bootImageConfigKey = android.NewOnceKey("bootImageConfig")
|
||||
bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw")
|
||||
artBootImageName = "art"
|
||||
frameworkBootImageName = "boot"
|
||||
mainlineBootImageName = "mainline"
|
||||
bootImageStem = "boot"
|
||||
bootImageConfigKey = android.NewOnceKey("bootImageConfig")
|
||||
bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw")
|
||||
frameworkBootImageName = "boot"
|
||||
mainlineBootImageName = "mainline"
|
||||
bootImageStem = "boot"
|
||||
profileInstallPathInApex = "etc/boot-image.prof"
|
||||
)
|
||||
|
||||
// getImageNames returns an ordered list of image names. The order doesn't matter but needs to be
|
||||
// deterministic. The names listed here must match the map keys returned by genBootImageConfigs.
|
||||
func getImageNames() []string {
|
||||
return []string{"art", "boot", "mainline"}
|
||||
}
|
||||
|
||||
func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig {
|
||||
return ctx.Config().Once(bootImageConfigRawKey, func() interface{} {
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
|
||||
artBootImageName := "art" // Keep this local to avoid accidental references.
|
||||
artModules := global.ArtApexJars
|
||||
frameworkModules := global.BootJars // This includes `artModules`.
|
||||
frameworkModules := global.BootJars // This includes `global.ArtApexJars`.
|
||||
mainlineBcpModules := global.ApexBootJars
|
||||
frameworkSubdir := "system/framework"
|
||||
|
||||
// ART config for the primary boot image in the ART apex.
|
||||
// It includes the Core Libraries.
|
||||
profileImports := []string{"com.android.art"}
|
||||
|
||||
// ART boot image for testing only. Do not rely on it to make any build-time decision.
|
||||
artCfg := bootImageConfig{
|
||||
name: artBootImageName,
|
||||
stem: bootImageStem,
|
||||
installDir: "apex/art_boot_images/javalib",
|
||||
profileInstallPathInApex: "etc/boot-image.prof",
|
||||
modules: artModules,
|
||||
preloadedClassesFile: "art/build/boot/preloaded-classes",
|
||||
compilerFilter: "speed-profile",
|
||||
singleImage: false,
|
||||
name: artBootImageName,
|
||||
enabledIfExists: "art-bootclasspath-fragment",
|
||||
stem: bootImageStem,
|
||||
installDir: "apex/art_boot_images/javalib",
|
||||
modules: artModules,
|
||||
preloadedClassesFile: "art/build/boot/preloaded-classes",
|
||||
compilerFilter: "speed-profile",
|
||||
singleImage: false,
|
||||
profileImports: profileImports,
|
||||
}
|
||||
|
||||
// Framework config for the boot image extension.
|
||||
// It includes framework libraries and depends on the ART config.
|
||||
frameworkCfg := bootImageConfig{
|
||||
name: frameworkBootImageName,
|
||||
enabledIfExists: "platform-bootclasspath",
|
||||
stem: bootImageStem,
|
||||
installDir: frameworkSubdir,
|
||||
modules: frameworkModules,
|
||||
preloadedClassesFile: "frameworks/base/config/preloaded-classes",
|
||||
compilerFilter: "speed-profile",
|
||||
singleImage: false,
|
||||
profileImports: []*bootImageConfig{&artCfg},
|
||||
profileImports: profileImports,
|
||||
}
|
||||
|
||||
mainlineCfg := bootImageConfig{
|
||||
extends: &frameworkCfg,
|
||||
name: mainlineBootImageName,
|
||||
stem: bootImageStem,
|
||||
installDir: frameworkSubdir,
|
||||
modules: mainlineBcpModules,
|
||||
compilerFilter: "verify",
|
||||
singleImage: true,
|
||||
extends: &frameworkCfg,
|
||||
name: mainlineBootImageName,
|
||||
enabledIfExists: "platform-bootclasspath",
|
||||
stem: bootImageStem,
|
||||
installDir: frameworkSubdir,
|
||||
modules: mainlineBcpModules,
|
||||
compilerFilter: "verify",
|
||||
singleImage: true,
|
||||
}
|
||||
|
||||
return map[string]*bootImageConfig{
|
||||
@@ -180,10 +191,6 @@ func calculateDepsRecursive(c *bootImageConfig, targets []android.Target, visite
|
||||
}
|
||||
}
|
||||
|
||||
func artBootImageConfig(ctx android.PathContext) *bootImageConfig {
|
||||
return genBootImageConfigs(ctx)[artBootImageName]
|
||||
}
|
||||
|
||||
func defaultBootImageConfig(ctx android.PathContext) *bootImageConfig {
|
||||
return genBootImageConfigs(ctx)[frameworkBootImageName]
|
||||
}
|
||||
@@ -192,6 +199,18 @@ func mainlineBootImageConfig(ctx android.PathContext) *bootImageConfig {
|
||||
return genBootImageConfigs(ctx)[mainlineBootImageName]
|
||||
}
|
||||
|
||||
// isProfileProviderApex returns true if this apex provides a boot image profile.
|
||||
func isProfileProviderApex(ctx android.PathContext, apexName string) bool {
|
||||
for _, config := range genBootImageConfigs(ctx) {
|
||||
for _, profileImport := range config.profileImports {
|
||||
if profileImport == apexName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Apex boot config allows to access build/install paths of apex boot jars without going
|
||||
// through the usual trouble of registering dependencies on those modules and extracting build paths
|
||||
// from those dependencies.
|
||||
|
@@ -16,6 +16,7 @@ package java
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"android/soong/android"
|
||||
@@ -35,3 +36,22 @@ func TestBootImageConfig(t *testing.T) {
|
||||
CheckFrameworkBootImageConfig(t, result)
|
||||
CheckMainlineBootImageConfig(t, result)
|
||||
}
|
||||
|
||||
func TestImageNames(t *testing.T) {
|
||||
result := android.GroupFixturePreparers(
|
||||
PrepareForBootImageConfigTest,
|
||||
).RunTest(t)
|
||||
|
||||
names := getImageNames()
|
||||
sort.Strings(names)
|
||||
|
||||
ctx := &android.TestPathContext{TestResult: result}
|
||||
configs := genBootImageConfigs(ctx)
|
||||
namesFromConfigs := make([]string, 0, len(configs))
|
||||
for name, _ := range configs {
|
||||
namesFromConfigs = append(namesFromConfigs, name)
|
||||
}
|
||||
sort.Strings(namesFromConfigs)
|
||||
|
||||
android.AssertArrayString(t, "getImageNames vs genBootImageConfigs", names, namesFromConfigs)
|
||||
}
|
||||
|
@@ -813,8 +813,8 @@ func checkFrameworkBootImageConfig(t *testing.T, result *android.TestResult, mut
|
||||
},
|
||||
},
|
||||
profileInstalls: []normalizedInstall{
|
||||
{from: "out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof", to: "/system/etc/boot-image.prof"},
|
||||
{from: "out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof", to: "/system/etc/boot-image.bprof"},
|
||||
{from: "out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/boot/boot.prof", to: "/system/etc/boot-image.prof"},
|
||||
},
|
||||
profileLicenseMetadataFile: expectedLicenseMetadataFile,
|
||||
}
|
||||
@@ -1230,14 +1230,14 @@ DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm=%[1]s
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm64=%[1]s
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86=%[1]s
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86_64=%[1]s
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEart=/apex/art_boot_images/javalib/boot.art
|
||||
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEboot=/system/framework/boot.art
|
||||
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEmainline=/system/framework/boot.art:/system/framework/boot-framework-foo.art
|
||||
@@ -1245,8 +1245,8 @@ DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/dexpreopt_arm64/dex_artjars/andro
|
||||
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art
|
||||
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTmainline=out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/boot.art:out/soong/dexpreopt_arm64/dex_mainlinejars/android/system/framework/boot-framework-foo.art
|
||||
DEXPREOPT_IMAGE_NAMES=art boot mainline
|
||||
DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/boot/boot.prof:/system/etc/boot-image.prof
|
||||
DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof:/system/etc/boot-image.prof out/soong/dexpreopt_arm64/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof
|
||||
DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic
|
||||
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat
|
||||
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm64=out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot.oat:/apex/art_boot_images/javalib/arm64/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm64/boot-core2.oat:/apex/art_boot_images/javalib/arm64/boot-core2.oat
|
||||
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_host_x86=out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat:/apex/art_boot_images/javalib/x86/boot.oat out/soong/dexpreopt_arm64/dex_artjars_unstripped/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat:/apex/art_boot_images/javalib/x86/boot-core2.oat
|
||||
|
@@ -123,15 +123,15 @@ func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpM
|
||||
}
|
||||
|
||||
func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
|
||||
// Add dependencies on all the modules configured in the "art" boot image.
|
||||
artImageConfig := genBootImageConfigs(ctx)[artBootImageName]
|
||||
addDependenciesOntoBootImageModules(ctx, artImageConfig.modules, platformBootclasspathArtBootJarDepTag)
|
||||
// Add dependencies on all the ART jars.
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag)
|
||||
|
||||
// Add dependencies on all the non-updatable module configured in the "boot" boot image. That does
|
||||
// not include modules configured in the "art" boot image.
|
||||
// Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable
|
||||
// APEXes.
|
||||
addDependenciesOntoBootImageModules(ctx, b.platformJars(ctx), platformBootclasspathBootJarDepTag)
|
||||
|
||||
// Add dependencies on all the apex jars.
|
||||
// Add dependencies on all the updatable jars, except the ART jars.
|
||||
apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
|
||||
addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag)
|
||||
|
||||
@@ -186,7 +186,6 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo
|
||||
bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments)
|
||||
buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule)
|
||||
|
||||
b.generateBootImageBuildActions(ctx)
|
||||
b.copyApexBootJarsForAppsDexpreopt(ctx, apexModules)
|
||||
}
|
||||
|
||||
@@ -218,7 +217,8 @@ func (b *platformBootclasspathModule) configuredJars(ctx android.ModuleContext)
|
||||
}
|
||||
|
||||
func (b *platformBootclasspathModule) platformJars(ctx android.PathContext) android.ConfiguredJarList {
|
||||
return defaultBootImageConfig(ctx).modules.RemoveList(artBootImageConfig(ctx).modules)
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
return global.BootJars.RemoveList(global.ArtApexJars)
|
||||
}
|
||||
|
||||
// checkPlatformModules ensures that the non-updatable modules supplied are not part of an
|
||||
@@ -399,78 +399,9 @@ func (b *platformBootclasspathModule) generateHiddenApiMakeVars(ctx android.Make
|
||||
ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_FLAGS", b.hiddenAPIFlagsCSV.String())
|
||||
}
|
||||
|
||||
// generateBootImageBuildActions generates ninja rules related to the boot image creation.
|
||||
func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android.ModuleContext) {
|
||||
// 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)
|
||||
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
if !shouldBuildBootImages(ctx.Config(), global) {
|
||||
return
|
||||
}
|
||||
|
||||
frameworkBootImageConfig := defaultBootImageConfig(ctx)
|
||||
bootFrameworkProfileRule(ctx, frameworkBootImageConfig)
|
||||
b.generateBootImage(ctx, frameworkBootImageName)
|
||||
b.generateBootImage(ctx, mainlineBootImageName)
|
||||
dumpOatRules(ctx, frameworkBootImageConfig)
|
||||
}
|
||||
|
||||
func (b *platformBootclasspathModule) generateBootImage(ctx android.ModuleContext, imageName string) {
|
||||
imageConfig := genBootImageConfigs(ctx)[imageName]
|
||||
|
||||
modules := b.getModulesForImage(ctx, imageConfig)
|
||||
|
||||
// Copy module dex jars to their predefined locations.
|
||||
bootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, modules)
|
||||
copyBootJarsToPredefinedLocations(ctx, bootDexJarsByModule, imageConfig.dexPathsByModule)
|
||||
|
||||
// Build a profile for the image config and then use that to build the boot image.
|
||||
profile := bootImageProfileRule(ctx, imageConfig)
|
||||
|
||||
// If dexpreopt of boot image jars should be skipped, generate only a profile.
|
||||
global := dexpreopt.GetGlobalConfig(ctx)
|
||||
if global.DisablePreoptBootImages {
|
||||
return
|
||||
}
|
||||
|
||||
// Build boot image files for the android variants.
|
||||
androidBootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
|
||||
|
||||
// Zip the android variant boot image files up.
|
||||
buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFiles.byArch)
|
||||
|
||||
// Build boot image files for the host variants. There are use directly by ART host side tests.
|
||||
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
|
||||
}
|
||||
|
||||
// Copy apex module dex jars to their predefined locations. They will be used for dexpreopt for apps.
|
||||
func (b *platformBootclasspathModule) copyApexBootJarsForAppsDexpreopt(ctx android.ModuleContext, apexModules []android.Module) {
|
||||
config := GetApexBootConfig(ctx)
|
||||
apexBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, apexModules)
|
||||
copyBootJarsToPredefinedLocations(ctx, apexBootDexJarsByModule, config.dexPathsByModule)
|
||||
}
|
||||
|
||||
func (b *platformBootclasspathModule) getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) []android.Module {
|
||||
modules := make([]android.Module, 0, imageConfig.modules.Len())
|
||||
for i := 0; i < imageConfig.modules.Len(); i++ {
|
||||
found := false
|
||||
for _, module := range b.configuredModules {
|
||||
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
|
||||
if name == imageConfig.modules.Jar(i) {
|
||||
modules = append(modules, module)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found && !ctx.Config().AllowMissingDependencies() {
|
||||
ctx.ModuleErrorf(
|
||||
"Boot image '%s' module '%s' not added as a dependency of platform_bootclasspath",
|
||||
imageConfig.name,
|
||||
imageConfig.modules.Jar(i))
|
||||
return []android.Module{}
|
||||
}
|
||||
}
|
||||
return modules
|
||||
}
|
||||
|
@@ -145,8 +145,8 @@ func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) {
|
||||
preparerForSnapshot := fixtureAddPrebuiltApexForBootclasspathFragment("com.android.art", "art-bootclasspath-fragment")
|
||||
|
||||
// Check that source on its own configures the bootImageConfig correctly.
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic")
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
|
||||
CheckSnapshot(t, result, "mysdk", "",
|
||||
checkAndroidBpContents(`
|
||||
@@ -213,24 +213,24 @@ java_import {
|
||||
java.ApexBootJarDexJarPaths...,
|
||||
)...,
|
||||
)
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/snapshot/art-bootclasspath-fragment/android_common_com.android.art/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic")
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
}),
|
||||
|
||||
snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot),
|
||||
|
||||
// Check the behavior of the snapshot when the source is preferred.
|
||||
snapshotTestChecker(checkSnapshotWithSourcePreferred, func(t *testing.T, result *android.TestResult) {
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/art-bootclasspath-fragment/android_common_apex10000/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic")
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
}),
|
||||
|
||||
snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot),
|
||||
|
||||
// Check the behavior of the snapshot when it is preferred.
|
||||
snapshotTestChecker(checkSnapshotPreferredWithSource, func(t *testing.T, result *android.TestResult) {
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/snapshot/prebuilt_art-bootclasspath-fragment/android_common_com.android.art/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic")
|
||||
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/default/java/dex_bootjars/android_common/meta_lic")
|
||||
}),
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user