Merge "Move generation of the dexpreopt tool paths into Soong." am: 46f60291f3
am: 0233e754e8
Change-Id: If6c6d148ad03d20cf9643c86b00db2e1aa59d0f8
This commit is contained in:
@@ -22,7 +22,9 @@ import (
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
// GlobalConfig stores the configuration for dex preopting set by the product
|
||||
// GlobalConfig stores the configuration for dex preopting. The fields are set
|
||||
// from product variables via dex_preopt_config.mk, except for SoongConfig
|
||||
// which come from CreateGlobalSoongConfig.
|
||||
type GlobalConfig struct {
|
||||
DisablePreopt bool // disable preopt for all modules
|
||||
DisablePreoptModules []string // modules with preopt disabled by product-specific config
|
||||
@@ -82,19 +84,19 @@ type GlobalConfig struct {
|
||||
Dex2oatImageXmx string // max heap size for dex2oat for the boot image
|
||||
Dex2oatImageXms string // initial heap size for dex2oat for the boot image
|
||||
|
||||
Tools Tools // paths to tools possibly used by the generated commands
|
||||
SoongConfig GlobalSoongConfig // settings read from dexpreopt_soong.config
|
||||
}
|
||||
|
||||
// Tools contains paths to tools possibly used by the generated commands. If you add a new tool here you MUST add it
|
||||
// to the order-only dependency list in DEXPREOPT_GEN_DEPS.
|
||||
type Tools struct {
|
||||
// GlobalSoongConfig contains the global config that is generated from Soong,
|
||||
// stored in dexpreopt_soong.config.
|
||||
type GlobalSoongConfig struct {
|
||||
// Paths to tools possibly used by the generated commands.
|
||||
Profman android.Path
|
||||
Dex2oat android.Path
|
||||
Aapt android.Path
|
||||
SoongZip android.Path
|
||||
Zip2zip android.Path
|
||||
ManifestCheck android.Path
|
||||
|
||||
ConstructContext android.Path
|
||||
}
|
||||
|
||||
@@ -133,6 +135,17 @@ type ModuleConfig struct {
|
||||
PresignedPrebuilt bool
|
||||
}
|
||||
|
||||
type globalSoongConfigSingleton struct{}
|
||||
|
||||
var pctx = android.NewPackageContext("android/soong/dexpreopt")
|
||||
|
||||
func init() {
|
||||
pctx.Import("android/soong/android")
|
||||
android.RegisterSingletonType("dexpreopt-soong-config", func() android.Singleton {
|
||||
return &globalSoongConfigSingleton{}
|
||||
})
|
||||
}
|
||||
|
||||
func constructPath(ctx android.PathContext, path string) android.Path {
|
||||
buildDirPrefix := ctx.Config().BuildDir() + "/"
|
||||
if path == "" {
|
||||
@@ -167,9 +180,12 @@ func constructWritablePath(ctx android.PathContext, path string) android.Writabl
|
||||
return constructPath(ctx, path).(android.WritablePath)
|
||||
}
|
||||
|
||||
// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig struct. It is used directly in Soong
|
||||
// and in dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by Make.
|
||||
func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, []byte, error) {
|
||||
// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig
|
||||
// struct, except the SoongConfig field which is set from the provided
|
||||
// soongConfig argument. LoadGlobalConfig is used directly in Soong and in
|
||||
// dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by
|
||||
// Make.
|
||||
func LoadGlobalConfig(ctx android.PathContext, path string, soongConfig GlobalSoongConfig) (GlobalConfig, []byte, error) {
|
||||
type GlobalJSONConfig struct {
|
||||
GlobalConfig
|
||||
|
||||
@@ -177,17 +193,6 @@ func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, []byt
|
||||
// used to construct the real value manually below.
|
||||
DirtyImageObjects string
|
||||
BootImageProfiles []string
|
||||
|
||||
Tools struct {
|
||||
Profman string
|
||||
Dex2oat string
|
||||
Aapt string
|
||||
SoongZip string
|
||||
Zip2zip string
|
||||
ManifestCheck string
|
||||
|
||||
ConstructContext string
|
||||
}
|
||||
}
|
||||
|
||||
config := GlobalJSONConfig{}
|
||||
@@ -200,13 +205,9 @@ func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, []byt
|
||||
config.GlobalConfig.DirtyImageObjects = android.OptionalPathForPath(constructPath(ctx, config.DirtyImageObjects))
|
||||
config.GlobalConfig.BootImageProfiles = constructPaths(ctx, config.BootImageProfiles)
|
||||
|
||||
config.GlobalConfig.Tools.Profman = constructPath(ctx, config.Tools.Profman)
|
||||
config.GlobalConfig.Tools.Dex2oat = constructPath(ctx, config.Tools.Dex2oat)
|
||||
config.GlobalConfig.Tools.Aapt = constructPath(ctx, config.Tools.Aapt)
|
||||
config.GlobalConfig.Tools.SoongZip = constructPath(ctx, config.Tools.SoongZip)
|
||||
config.GlobalConfig.Tools.Zip2zip = constructPath(ctx, config.Tools.Zip2zip)
|
||||
config.GlobalConfig.Tools.ManifestCheck = constructPath(ctx, config.Tools.ManifestCheck)
|
||||
config.GlobalConfig.Tools.ConstructContext = constructPath(ctx, config.Tools.ConstructContext)
|
||||
// Set this here to force the caller to provide a value for this struct (from
|
||||
// either CreateGlobalSoongConfig or LoadGlobalSoongConfig).
|
||||
config.GlobalConfig.SoongConfig = soongConfig
|
||||
|
||||
return config.GlobalConfig, data, nil
|
||||
}
|
||||
@@ -253,6 +254,104 @@ func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error
|
||||
return config.ModuleConfig, nil
|
||||
}
|
||||
|
||||
// CreateGlobalSoongConfig creates a GlobalSoongConfig from the current context.
|
||||
// Should not be used in dexpreopt_gen.
|
||||
func CreateGlobalSoongConfig(ctx android.PathContext) GlobalSoongConfig {
|
||||
// Default to debug version to help find bugs.
|
||||
// Set USE_DEX2OAT_DEBUG to false for only building non-debug versions.
|
||||
var dex2oatBinary string
|
||||
if ctx.Config().Getenv("USE_DEX2OAT_DEBUG") == "false" {
|
||||
dex2oatBinary = "dex2oat"
|
||||
} else {
|
||||
dex2oatBinary = "dex2oatd"
|
||||
}
|
||||
|
||||
return GlobalSoongConfig{
|
||||
Profman: ctx.Config().HostToolPath(ctx, "profman"),
|
||||
Dex2oat: ctx.Config().HostToolPath(ctx, dex2oatBinary),
|
||||
Aapt: ctx.Config().HostToolPath(ctx, "aapt"),
|
||||
SoongZip: ctx.Config().HostToolPath(ctx, "soong_zip"),
|
||||
Zip2zip: ctx.Config().HostToolPath(ctx, "zip2zip"),
|
||||
ManifestCheck: ctx.Config().HostToolPath(ctx, "manifest_check"),
|
||||
ConstructContext: android.PathForSource(ctx, "build/make/core/construct_context.sh"),
|
||||
}
|
||||
}
|
||||
|
||||
type globalJsonSoongConfig struct {
|
||||
Profman string
|
||||
Dex2oat string
|
||||
Aapt string
|
||||
SoongZip string
|
||||
Zip2zip string
|
||||
ManifestCheck string
|
||||
ConstructContext string
|
||||
}
|
||||
|
||||
// LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a
|
||||
// GlobalSoongConfig struct. It is only used in dexpreopt_gen.
|
||||
func LoadGlobalSoongConfig(ctx android.PathContext, path string) (GlobalSoongConfig, error) {
|
||||
var jc globalJsonSoongConfig
|
||||
|
||||
_, err := loadConfig(ctx, path, &jc)
|
||||
if err != nil {
|
||||
return GlobalSoongConfig{}, err
|
||||
}
|
||||
|
||||
config := GlobalSoongConfig{
|
||||
Profman: constructPath(ctx, jc.Profman),
|
||||
Dex2oat: constructPath(ctx, jc.Dex2oat),
|
||||
Aapt: constructPath(ctx, jc.Aapt),
|
||||
SoongZip: constructPath(ctx, jc.SoongZip),
|
||||
Zip2zip: constructPath(ctx, jc.Zip2zip),
|
||||
ManifestCheck: constructPath(ctx, jc.ManifestCheck),
|
||||
ConstructContext: constructPath(ctx, jc.ConstructContext),
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (s *globalSoongConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
config := CreateGlobalSoongConfig(ctx)
|
||||
jc := globalJsonSoongConfig{
|
||||
Profman: config.Profman.String(),
|
||||
Dex2oat: config.Dex2oat.String(),
|
||||
Aapt: config.Aapt.String(),
|
||||
SoongZip: config.SoongZip.String(),
|
||||
Zip2zip: config.Zip2zip.String(),
|
||||
ManifestCheck: config.ManifestCheck.String(),
|
||||
ConstructContext: config.ConstructContext.String(),
|
||||
}
|
||||
|
||||
data, err := json.Marshal(jc)
|
||||
if err != nil {
|
||||
ctx.Errorf("failed to JSON marshal GlobalSoongConfig: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: android.WriteFile,
|
||||
Output: android.PathForOutput(ctx, "dexpreopt_soong.config"),
|
||||
Args: map[string]string{
|
||||
"content": string(data),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *globalSoongConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
|
||||
config := CreateGlobalSoongConfig(ctx)
|
||||
|
||||
ctx.Strict("DEX2OAT", config.Dex2oat.String())
|
||||
ctx.Strict("DEXPREOPT_GEN_DEPS", strings.Join([]string{
|
||||
config.Profman.String(),
|
||||
config.Dex2oat.String(),
|
||||
config.Aapt.String(),
|
||||
config.SoongZip.String(),
|
||||
config.Zip2zip.String(),
|
||||
config.ManifestCheck.String(),
|
||||
config.ConstructContext.String(),
|
||||
}, " "))
|
||||
}
|
||||
|
||||
func loadConfig(ctx android.PathContext, path string, config interface{}) ([]byte, error) {
|
||||
r, err := ctx.Fs().Open(path)
|
||||
if err != nil {
|
||||
@@ -312,7 +411,7 @@ func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
|
||||
BootFlags: "",
|
||||
Dex2oatImageXmx: "",
|
||||
Dex2oatImageXms: "",
|
||||
Tools: Tools{
|
||||
SoongConfig: GlobalSoongConfig{
|
||||
Profman: android.PathForTesting("profman"),
|
||||
Dex2oat: android.PathForTesting("dex2oat"),
|
||||
Aapt: android.PathForTesting("aapt"),
|
||||
|
@@ -131,7 +131,7 @@ func profileCommand(ctx android.PathContext, global GlobalConfig, module ModuleC
|
||||
|
||||
cmd := rule.Command().
|
||||
Text(`ANDROID_LOG_TAGS="*:e"`).
|
||||
Tool(global.Tools.Profman)
|
||||
Tool(global.SoongConfig.Profman)
|
||||
|
||||
if module.ProfileIsTextListing {
|
||||
// The profile is a test listing of classes (used for framework jars).
|
||||
@@ -170,7 +170,7 @@ func bootProfileCommand(ctx android.PathContext, global GlobalConfig, module Mod
|
||||
|
||||
cmd := rule.Command().
|
||||
Text(`ANDROID_LOG_TAGS="*:e"`).
|
||||
Tool(global.Tools.Profman)
|
||||
Tool(global.SoongConfig.Profman)
|
||||
|
||||
// The profile is a test listing of methods.
|
||||
// We need to generate the actual binary profile.
|
||||
@@ -299,14 +299,14 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
||||
if module.EnforceUsesLibraries {
|
||||
if module.ManifestPath != nil {
|
||||
rule.Command().Text(`target_sdk_version="$(`).
|
||||
Tool(global.Tools.ManifestCheck).
|
||||
Tool(global.SoongConfig.ManifestCheck).
|
||||
Flag("--extract-target-sdk-version").
|
||||
Input(module.ManifestPath).
|
||||
Text(`)"`)
|
||||
} else {
|
||||
// No manifest to extract targetSdkVersion from, hope that DexJar is an APK
|
||||
rule.Command().Text(`target_sdk_version="$(`).
|
||||
Tool(global.Tools.Aapt).
|
||||
Tool(global.SoongConfig.Aapt).
|
||||
Flag("dump badging").
|
||||
Input(module.DexPath).
|
||||
Text(`| grep "targetSdkVersion" | sed -n "s/targetSdkVersion:'\(.*\)'/\1/p"`).
|
||||
@@ -327,7 +327,7 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
||||
Implicits(conditionalClassLoaderContextHost29)
|
||||
rule.Command().Textf(`conditional_target_libs_29="%s"`,
|
||||
strings.Join(conditionalClassLoaderContextTarget29, " "))
|
||||
rule.Command().Text("source").Tool(global.Tools.ConstructContext).Input(module.DexPath)
|
||||
rule.Command().Text("source").Tool(global.SoongConfig.ConstructContext).Input(module.DexPath)
|
||||
}
|
||||
|
||||
// Devices that do not have a product partition use a symlink from /product to /system/product.
|
||||
@@ -340,7 +340,7 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
||||
|
||||
cmd := rule.Command().
|
||||
Text(`ANDROID_LOG_TAGS="*:e"`).
|
||||
Tool(global.Tools.Dex2oat).
|
||||
Tool(global.SoongConfig.Dex2oat).
|
||||
Flag("--avoid-storing-invocation").
|
||||
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
|
||||
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatXms).
|
||||
@@ -409,7 +409,7 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
|
||||
dmInstalledPath := pathtools.ReplaceExtension(module.DexLocation, "dm")
|
||||
tmpPath := module.BuildPath.InSameDir(ctx, "primary.vdex")
|
||||
rule.Command().Text("cp -f").Input(vdexPath).Output(tmpPath)
|
||||
rule.Command().Tool(global.Tools.SoongZip).
|
||||
rule.Command().Tool(global.SoongConfig.SoongZip).
|
||||
FlagWithArg("-L", "9").
|
||||
FlagWithOutput("-o", dmPath).
|
||||
Flag("-j").
|
||||
|
@@ -31,6 +31,7 @@ import (
|
||||
|
||||
var (
|
||||
dexpreoptScriptPath = flag.String("dexpreopt_script", "", "path to output dexpreopt script")
|
||||
globalSoongConfigPath = flag.String("global_soong", "", "path to global configuration file for settings originating from Soong")
|
||||
globalConfigPath = flag.String("global", "", "path to global configuration file")
|
||||
moduleConfigPath = flag.String("module", "", "path to module configuration file")
|
||||
outDir = flag.String("out_dir", "", "path to output directory")
|
||||
@@ -63,17 +64,27 @@ func main() {
|
||||
usage("path to output dexpreopt script is required")
|
||||
}
|
||||
|
||||
if *globalSoongConfigPath == "" {
|
||||
usage("--global_soong configuration file is required")
|
||||
}
|
||||
|
||||
if *globalConfigPath == "" {
|
||||
usage("path to global configuration file is required")
|
||||
usage("--global configuration file is required")
|
||||
}
|
||||
|
||||
if *moduleConfigPath == "" {
|
||||
usage("path to module configuration file is required")
|
||||
usage("--module configuration file is required")
|
||||
}
|
||||
|
||||
ctx := &pathContext{android.TestConfig(*outDir, nil, "", nil)}
|
||||
|
||||
globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath)
|
||||
globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, *globalSoongConfigPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalSoongConfigPath, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath, globalSoongConfig)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err)
|
||||
os.Exit(2)
|
||||
@@ -121,7 +132,7 @@ func writeScripts(ctx android.PathContext, global dexpreopt.GlobalConfig, module
|
||||
dexpreoptRule.Command().Text("mkdir -p").Flag(filepath.Dir(installPath.String()))
|
||||
dexpreoptRule.Command().Text("cp -f").Input(install.From).Output(installPath)
|
||||
}
|
||||
dexpreoptRule.Command().Tool(global.Tools.SoongZip).
|
||||
dexpreoptRule.Command().Tool(global.SoongConfig.SoongZip).
|
||||
FlagWithArg("-o ", "$2").
|
||||
FlagWithArg("-C ", installDir.String()).
|
||||
FlagWithArg("-D ", installDir.String())
|
||||
|
@@ -335,7 +335,7 @@ func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
|
||||
|
||||
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
|
||||
|
||||
cmd.Tool(global.Tools.Dex2oat).
|
||||
cmd.Tool(global.SoongConfig.Dex2oat).
|
||||
Flag("--avoid-storing-invocation").
|
||||
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
|
||||
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms).
|
||||
@@ -444,7 +444,6 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missin
|
||||
return nil
|
||||
}
|
||||
profile := ctx.Config().Once(bootImageProfileRuleKey, func() interface{} {
|
||||
tools := global.Tools
|
||||
defaultProfile := "frameworks/base/config/boot-image-profile.txt"
|
||||
|
||||
rule := android.NewRuleBuilder()
|
||||
@@ -470,7 +469,7 @@ func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missin
|
||||
|
||||
rule.Command().
|
||||
Text(`ANDROID_LOG_TAGS="*:e"`).
|
||||
Tool(tools.Profman).
|
||||
Tool(global.SoongConfig.Profman).
|
||||
FlagWithInput("--create-profile-from=", bootImageProfile).
|
||||
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
|
||||
FlagForEachArg("--dex-location=", image.dexLocationsDeps).
|
||||
@@ -499,8 +498,6 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, mi
|
||||
return nil
|
||||
}
|
||||
return ctx.Config().Once(bootFrameworkProfileRuleKey, func() interface{} {
|
||||
tools := global.Tools
|
||||
|
||||
rule := android.NewRuleBuilder()
|
||||
rule.MissingDeps(missingDeps)
|
||||
|
||||
@@ -521,7 +518,7 @@ func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, mi
|
||||
|
||||
rule.Command().
|
||||
Text(`ANDROID_LOG_TAGS="*:e"`).
|
||||
Tool(tools.Profman).
|
||||
Tool(global.SoongConfig.Profman).
|
||||
Flag("--generate-boot-profile").
|
||||
FlagWithInput("--create-profile-from=", bootFrameworkProfile).
|
||||
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
|
||||
@@ -598,6 +595,7 @@ func writeGlobalConfigForMake(ctx android.SingletonContext, path android.Writabl
|
||||
func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
|
||||
if d.dexpreoptConfigForMake != nil {
|
||||
ctx.Strict("DEX_PREOPT_CONFIG_FOR_MAKE", d.dexpreoptConfigForMake.String())
|
||||
ctx.Strict("DEX_PREOPT_SOONG_CONFIG_FOR_MAKE", android.PathForOutput(ctx, "dexpreopt_soong.config").String())
|
||||
}
|
||||
|
||||
image := d.defaultBootImage
|
||||
|
@@ -37,8 +37,9 @@ type globalConfigAndRaw struct {
|
||||
func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
|
||||
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
|
||||
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
|
||||
soongConfig := dexpreopt.CreateGlobalSoongConfig(ctx)
|
||||
ctx.AddNinjaFileDeps(f)
|
||||
globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f)
|
||||
globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f, soongConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user