platform_build_soong/java/dexpreopt.go
Jeongik Cha b19b58a015 Drop DexPreoptImages field in dexpreopt config
The field isn't used anymore.
And DexPreoptImagesDeps will have the slice of which size is the same as
Archs to avoid an error.

Bug: 158843648
Test: m
Change-Id: I520063ff7376811febbc82e1a0a43785feb5bbb2
2021-04-26 23:41:40 +09:00

260 lines
8.6 KiB
Go

// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package java
import (
"android/soong/android"
"android/soong/dexpreopt"
)
type dexpreopterInterface interface {
IsInstallable() bool // Structs that embed dexpreopter must implement this.
dexpreoptDisabled(ctx android.BaseModuleContext) bool
}
type dexpreopter struct {
dexpreoptProperties DexpreoptProperties
installPath android.InstallPath
uncompressedDex bool
isSDKLibrary bool
isApp bool
isTest bool
isPresignedPrebuilt bool
manifestFile android.Path
statusFile android.WritablePath
enforceUsesLibs bool
classLoaderContexts dexpreopt.ClassLoaderContextMap
builtInstalled string
// The config is used for two purposes:
// - Passing dexpreopt information about libraries from Soong to Make. This is needed when
// a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py).
// Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself.
// - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally
// dexpreopt another partition).
configPath android.WritablePath
}
type DexpreoptProperties struct {
Dex_preopt struct {
// If false, prevent dexpreopting. Defaults to true.
Enabled *bool
// If true, generate an app image (.art file) for this module.
App_image *bool
// If true, use a checked-in profile to guide optimization. Defaults to false unless
// a matching profile is set or a profile is found in PRODUCT_DEX_PREOPT_PROFILE_DIR
// that matches the name of this module, in which case it is defaulted to true.
Profile_guided *bool
// If set, provides the path to profile relative to the Android.bp file. If not set,
// defaults to searching for a file that matches the name of this module in the default
// profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found.
Profile *string `android:"path"`
}
}
func init() {
dexpreopt.DexpreoptRunningInSoong = true
}
func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
global := dexpreopt.GetGlobalConfig(ctx)
if global.DisablePreopt {
return true
}
if inList(ctx.ModuleName(), global.DisablePreoptModules) {
return true
}
if d.isTest {
return true
}
if !BoolDefault(d.dexpreoptProperties.Dex_preopt.Enabled, true) {
return true
}
if !ctx.Module().(dexpreopterInterface).IsInstallable() {
return true
}
if ctx.Host() {
return true
}
// Don't preopt APEX variant module
if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
return true
}
// TODO: contains no java code
return false
}
func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) {
if d, ok := ctx.Module().(dexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) {
return
}
dexpreopt.RegisterToolDeps(ctx)
}
func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
}
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) {
// TODO(b/148690468): The check on d.installPath is to bail out in cases where
// the dexpreopter struct hasn't been fully initialized before we're called,
// e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively
// disabled, even if installable is true.
if d.installPath.Base() == "." {
return
}
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
providesUsesLib := ctx.ModuleName()
if ulib, ok := ctx.Module().(ProvidesUsesLib); ok {
name := ulib.ProvidesUsesLib()
if name != nil {
providesUsesLib = *name
}
}
// If it is neither app nor test, make config files regardless of its dexpreopt setting.
// The config files are required for apps defined in make which depend on the lib.
// TODO(b/158843648): The config for apps should be generated as well regardless of setting.
if (d.isApp || d.isTest) && d.dexpreoptDisabled(ctx) {
return
}
global := dexpreopt.GetGlobalConfig(ctx)
isSystemServerJar := inList(ctx.ModuleName(), global.SystemServerJars)
bootImage := defaultBootImageConfig(ctx)
if global.UseArtImage {
bootImage = artBootImageConfig(ctx)
}
// System server jars are an exception: they are dexpreopted without updatable bootclasspath.
dexFiles, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp && !isSystemServerJar)
targets := ctx.MultiTargets()
if len(targets) == 0 {
// assume this is a java library, dexpreopt for all arches for now
for _, target := range ctx.Config().Targets[android.Android] {
if target.NativeBridge == android.NativeBridgeDisabled {
targets = append(targets, target)
}
}
if isSystemServerJar && !d.isSDKLibrary {
// If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
targets = targets[:1]
}
}
var archs []android.ArchType
var images android.Paths
var imagesDeps []android.OutputPaths
for _, target := range targets {
archs = append(archs, target.Arch.ArchType)
variant := bootImage.getVariant(target)
images = append(images, variant.images)
imagesDeps = append(imagesDeps, variant.imagesDeps)
}
// The image locations for all Android variants are identical.
imageLocations := bootImage.getAnyAndroidVariant().imageLocations()
var profileClassListing android.OptionalPath
var profileBootListing android.OptionalPath
profileIsTextListing := false
if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) {
// If dex_preopt.profile_guided is not set, default it based on the existence of the
// dexprepot.profile option or the profile class listing.
if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" {
profileClassListing = android.OptionalPathForPath(
android.PathForModuleSrc(ctx, String(d.dexpreoptProperties.Dex_preopt.Profile)))
profileBootListing = android.ExistentPathForSource(ctx,
ctx.ModuleDir(), String(d.dexpreoptProperties.Dex_preopt.Profile)+"-boot")
profileIsTextListing = true
} else if global.ProfileDir != "" {
profileClassListing = android.ExistentPathForSource(ctx,
global.ProfileDir, ctx.ModuleName()+".prof")
}
}
// Full dexpreopt config, used to create dexpreopt build rules.
dexpreoptConfig := &dexpreopt.ModuleConfig{
Name: ctx.ModuleName(),
DexLocation: dexLocation,
BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath,
DexPath: dexJarFile,
ManifestPath: android.OptionalPathForPath(d.manifestFile),
UncompressedDex: d.uncompressedDex,
HasApkLibraries: false,
PreoptFlags: nil,
ProfileClassListing: profileClassListing,
ProfileIsTextListing: profileIsTextListing,
ProfileBootListing: profileBootListing,
EnforceUsesLibrariesStatusFile: dexpreopt.UsesLibrariesStatusFile(ctx),
EnforceUsesLibraries: d.enforceUsesLibs,
ProvidesUsesLibrary: providesUsesLib,
ClassLoaderContexts: d.classLoaderContexts,
Archs: archs,
DexPreoptImagesDeps: imagesDeps,
DexPreoptImageLocations: imageLocations,
PreoptBootClassPathDexFiles: dexFiles.Paths(),
PreoptBootClassPathDexLocations: dexLocations,
PreoptExtractedApk: false,
NoCreateAppImage: !BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, true),
ForceCreateAppImage: BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, false),
PresignedPrebuilt: d.isPresignedPrebuilt,
}
d.configPath = android.PathForModuleOut(ctx, "dexpreopt", "dexpreopt.config")
dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath)
if d.dexpreoptDisabled(ctx) {
return
}
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, dexpreoptConfig)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
return
}
dexpreoptRule.Build("dexpreopt", "dexpreopt")
d.builtInstalled = dexpreoptRule.Installs().String()
}