Refactor dexpreopt_bootjars.go to prepare for multiple boot images am: 44df581457
am: ac405aa805
Change-Id: I9b2fc817fb13988f2954d6d74605572300b307fa
This commit is contained in:
@@ -253,6 +253,7 @@ bootstrap_go_package {
|
|||||||
"java/dex.go",
|
"java/dex.go",
|
||||||
"java/dexpreopt.go",
|
"java/dexpreopt.go",
|
||||||
"java/dexpreopt_bootjars.go",
|
"java/dexpreopt_bootjars.go",
|
||||||
|
"java/dexpreopt_config.go",
|
||||||
"java/droiddoc.go",
|
"java/droiddoc.go",
|
||||||
"java/gen.go",
|
"java/gen.go",
|
||||||
"java/genrule.go",
|
"java/genrule.go",
|
||||||
|
@@ -87,34 +87,6 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
|
|
||||||
var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
|
|
||||||
|
|
||||||
func setDexpreoptGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) {
|
|
||||||
config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfig })
|
|
||||||
}
|
|
||||||
|
|
||||||
func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig {
|
|
||||||
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
|
|
||||||
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
|
|
||||||
ctx.AddNinjaFileDeps(f)
|
|
||||||
globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, f)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return globalConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// No global config filename set, see if there is a test config set
|
|
||||||
return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} {
|
|
||||||
// Nope, return a config with preopting disabled
|
|
||||||
return dexpreopt.GlobalConfig{
|
|
||||||
DisablePreopt: true,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}).(dexpreopt.GlobalConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
func odexOnSystemOther(ctx android.ModuleContext, installPath android.OutputPath) bool {
|
func odexOnSystemOther(ctx android.ModuleContext, installPath android.OutputPath) bool {
|
||||||
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx))
|
return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx))
|
||||||
}
|
}
|
||||||
@@ -124,7 +96,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||||||
return dexJarFile
|
return dexJarFile
|
||||||
}
|
}
|
||||||
|
|
||||||
info := dexpreoptBootJarsInfo(ctx)
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
bootImage := defaultBootImageConfig(ctx)
|
||||||
|
|
||||||
var archs []android.ArchType
|
var archs []android.ArchType
|
||||||
for _, a := range ctx.MultiTargets() {
|
for _, a := range ctx.MultiTargets() {
|
||||||
@@ -135,7 +108,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||||||
for _, target := range ctx.Config().Targets[android.Android] {
|
for _, target := range ctx.Config().Targets[android.Android] {
|
||||||
archs = append(archs, target.Arch.ArchType)
|
archs = append(archs, target.Arch.ArchType)
|
||||||
}
|
}
|
||||||
if inList(ctx.ModuleName(), info.global.SystemServerJars) && !d.isSDKLibrary {
|
if inList(ctx.ModuleName(), global.SystemServerJars) && !d.isSDKLibrary {
|
||||||
// If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
|
// If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
|
||||||
archs = archs[:1]
|
archs = archs[:1]
|
||||||
}
|
}
|
||||||
@@ -147,7 +120,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||||||
|
|
||||||
var images android.Paths
|
var images android.Paths
|
||||||
for _, arch := range archs {
|
for _, arch := range archs {
|
||||||
images = append(images, info.images[arch])
|
images = append(images, bootImage.images[arch])
|
||||||
}
|
}
|
||||||
|
|
||||||
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
|
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
|
||||||
@@ -165,7 +138,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||||||
profileIsTextListing = true
|
profileIsTextListing = true
|
||||||
} else {
|
} else {
|
||||||
profileClassListing = android.ExistentPathForSource(ctx,
|
profileClassListing = android.ExistentPathForSource(ctx,
|
||||||
info.global.ProfileDir, ctx.ModuleName()+".prof")
|
global.ProfileDir, ctx.ModuleName()+".prof")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,8 +162,8 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||||||
Archs: archs,
|
Archs: archs,
|
||||||
DexPreoptImages: images,
|
DexPreoptImages: images,
|
||||||
|
|
||||||
PreoptBootClassPathDexFiles: info.preoptBootDex.Paths(),
|
PreoptBootClassPathDexFiles: bootImage.dexPaths.Paths(),
|
||||||
PreoptBootClassPathDexLocations: info.preoptBootLocations,
|
PreoptBootClassPathDexLocations: bootImage.dexLocations,
|
||||||
|
|
||||||
PreoptExtractedApk: false,
|
PreoptExtractedApk: false,
|
||||||
|
|
||||||
@@ -202,7 +175,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||||||
StripOutputPath: strippedDexJarFile.OutputPath,
|
StripOutputPath: strippedDexJarFile.OutputPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, info.global, dexpreoptConfig)
|
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, global, dexpreoptConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
|
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
|
||||||
return dexJarFile
|
return dexJarFile
|
||||||
@@ -212,7 +185,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Mo
|
|||||||
|
|
||||||
d.builtInstalled = dexpreoptRule.Installs().String()
|
d.builtInstalled = dexpreoptRule.Installs().String()
|
||||||
|
|
||||||
stripRule, err := dexpreopt.GenerateStripRule(info.global, dexpreoptConfig)
|
stripRule, err := dexpreopt.GenerateStripRule(global, dexpreoptConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ModuleErrorf("error generating dexpreopt strip rule: %s", err.Error())
|
ctx.ModuleErrorf("error generating dexpreopt strip rule: %s", err.Error())
|
||||||
return dexJarFile
|
return dexJarFile
|
||||||
|
@@ -48,56 +48,36 @@ func init() {
|
|||||||
// The location is passed as an argument to the ART tools like dex2oat instead of the real path. The ART tools
|
// The location is passed as an argument to the ART tools like dex2oat instead of the real path. The ART tools
|
||||||
// will then reconstruct the real path, so the rules must have a dependency on the real path.
|
// will then reconstruct the real path, so the rules must have a dependency on the real path.
|
||||||
|
|
||||||
type bootJarsInfo struct {
|
type bootImageConfig struct {
|
||||||
dir android.OutputPath
|
name string
|
||||||
symbolsDir android.OutputPath
|
modules []string
|
||||||
images map[android.ArchType]android.OutputPath
|
dexLocations []string
|
||||||
installs map[android.ArchType]android.RuleBuilderInstalls
|
dexPaths android.WritablePaths
|
||||||
|
dir android.OutputPath
|
||||||
vdexInstalls map[android.ArchType]android.RuleBuilderInstalls
|
symbolsDir android.OutputPath
|
||||||
unstrippedInstalls map[android.ArchType]android.RuleBuilderInstalls
|
images map[android.ArchType]android.OutputPath
|
||||||
profileInstalls android.RuleBuilderInstalls
|
|
||||||
|
|
||||||
global dexpreopt.GlobalConfig
|
|
||||||
|
|
||||||
preoptBootModules []string
|
|
||||||
preoptBootLocations []string
|
|
||||||
preoptBootDex android.WritablePaths
|
|
||||||
allBootModules []string
|
|
||||||
allBootLocations []string
|
|
||||||
bootclasspath string
|
|
||||||
systemServerClasspath string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var dexpreoptBootJarsInfoKey = android.NewOnceKey("dexpreoptBootJarsInfoKey")
|
type bootImage struct {
|
||||||
|
bootImageConfig
|
||||||
|
|
||||||
// dexpreoptBootJarsInfo creates all the paths for singleton files the first time it is called, which may be
|
installs map[android.ArchType]android.RuleBuilderInstalls
|
||||||
// from a ModuleContext that needs to reference a file that will be created by a singleton rule that hasn't
|
vdexInstalls map[android.ArchType]android.RuleBuilderInstalls
|
||||||
// yet been created.
|
unstrippedInstalls map[android.ArchType]android.RuleBuilderInstalls
|
||||||
func dexpreoptBootJarsInfo(ctx android.PathContext) *bootJarsInfo {
|
|
||||||
return ctx.Config().Once(dexpreoptBootJarsInfoKey, func() interface{} {
|
|
||||||
|
|
||||||
info := &bootJarsInfo{
|
profileInstalls android.RuleBuilderInstalls
|
||||||
dir: android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars"),
|
}
|
||||||
symbolsDir: android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_unstripped"),
|
|
||||||
images: make(map[android.ArchType]android.OutputPath),
|
|
||||||
installs: make(map[android.ArchType]android.RuleBuilderInstalls),
|
|
||||||
|
|
||||||
vdexInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
|
func newBootImage(ctx android.PathContext, config bootImageConfig) *bootImage {
|
||||||
unstrippedInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
|
image := &bootImage{
|
||||||
}
|
bootImageConfig: defaultBootImageConfig(ctx),
|
||||||
|
|
||||||
for _, target := range ctx.Config().Targets[android.Android] {
|
installs: make(map[android.ArchType]android.RuleBuilderInstalls),
|
||||||
info.images[target.Arch.ArchType] = info.dir.Join(ctx,
|
vdexInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
|
||||||
"system/framework", target.Arch.ArchType.String(), "boot.art")
|
unstrippedInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
|
||||||
}
|
}
|
||||||
|
|
||||||
info.global = dexpreoptGlobalConfig(ctx)
|
return image
|
||||||
computeBootClasspath(ctx, info)
|
|
||||||
computeSystemServerClasspath(ctx, info)
|
|
||||||
|
|
||||||
return info
|
|
||||||
}).(*bootJarsInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func concat(lists ...[]string) []string {
|
func concat(lists ...[]string) []string {
|
||||||
@@ -112,60 +92,8 @@ func concat(lists ...[]string) []string {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeBootClasspath(ctx android.PathContext, info *bootJarsInfo) {
|
|
||||||
runtimeModules := info.global.RuntimeApexJars
|
|
||||||
nonFrameworkModules := concat(runtimeModules, info.global.ProductUpdatableBootModules)
|
|
||||||
frameworkModules := android.RemoveListFromList(info.global.BootJars, nonFrameworkModules)
|
|
||||||
|
|
||||||
var nonUpdatableBootModules []string
|
|
||||||
var nonUpdatableBootLocations []string
|
|
||||||
|
|
||||||
for _, m := range runtimeModules {
|
|
||||||
nonUpdatableBootModules = append(nonUpdatableBootModules, m)
|
|
||||||
nonUpdatableBootLocations = append(nonUpdatableBootLocations,
|
|
||||||
filepath.Join("/apex/com.android.runtime/javalib", m+".jar"))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, m := range frameworkModules {
|
|
||||||
nonUpdatableBootModules = append(nonUpdatableBootModules, m)
|
|
||||||
nonUpdatableBootLocations = append(nonUpdatableBootLocations,
|
|
||||||
filepath.Join("/system/framework", m+".jar"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
|
|
||||||
// the bootclasspath modules have been compiled. Set up known paths for them, the singleton rules will copy
|
|
||||||
// them there.
|
|
||||||
// TODO: use module dependencies instead
|
|
||||||
var nonUpdatableBootDex android.WritablePaths
|
|
||||||
for _, m := range nonUpdatableBootModules {
|
|
||||||
nonUpdatableBootDex = append(nonUpdatableBootDex,
|
|
||||||
android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_input", m+".jar"))
|
|
||||||
}
|
|
||||||
|
|
||||||
allBootModules := concat(nonUpdatableBootModules, info.global.ProductUpdatableBootModules)
|
|
||||||
allBootLocations := concat(nonUpdatableBootLocations, info.global.ProductUpdatableBootLocations)
|
|
||||||
|
|
||||||
bootclasspath := strings.Join(allBootLocations, ":")
|
|
||||||
|
|
||||||
info.preoptBootModules = nonUpdatableBootModules
|
|
||||||
info.preoptBootLocations = nonUpdatableBootLocations
|
|
||||||
info.preoptBootDex = nonUpdatableBootDex
|
|
||||||
info.allBootModules = allBootModules
|
|
||||||
info.allBootLocations = allBootLocations
|
|
||||||
info.bootclasspath = bootclasspath
|
|
||||||
}
|
|
||||||
|
|
||||||
func computeSystemServerClasspath(ctx android.PathContext, info *bootJarsInfo) {
|
|
||||||
var systemServerClasspathLocations []string
|
|
||||||
for _, m := range info.global.SystemServerJars {
|
|
||||||
systemServerClasspathLocations = append(systemServerClasspathLocations,
|
|
||||||
filepath.Join("/system/framework", m+".jar"))
|
|
||||||
}
|
|
||||||
|
|
||||||
info.systemServerClasspath = strings.Join(systemServerClasspathLocations, ":")
|
|
||||||
}
|
|
||||||
func dexpreoptBootJarsFactory() android.Singleton {
|
func dexpreoptBootJarsFactory() android.Singleton {
|
||||||
return dexpreoptBootJars{}
|
return &dexpreoptBootJars{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func skipDexpreoptBootJars(ctx android.PathContext) bool {
|
func skipDexpreoptBootJars(ctx android.PathContext) bool {
|
||||||
@@ -181,15 +109,17 @@ func skipDexpreoptBootJars(ctx android.PathContext) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type dexpreoptBootJars struct{}
|
type dexpreoptBootJars struct {
|
||||||
|
defaultBootImage *bootImage
|
||||||
|
}
|
||||||
|
|
||||||
// dexpreoptBoot singleton rules
|
// dexpreoptBoot singleton rules
|
||||||
func (dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
|
func (d *dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
|
||||||
if skipDexpreoptBootJars(ctx) {
|
if skipDexpreoptBootJars(ctx) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
info := dexpreoptBootJarsInfo(ctx)
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
|
||||||
// Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
|
// Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
|
||||||
// and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds.
|
// and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds.
|
||||||
@@ -197,17 +127,26 @@ func (dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
// on ASAN settings.
|
// on ASAN settings.
|
||||||
if len(ctx.Config().SanitizeDevice()) == 1 &&
|
if len(ctx.Config().SanitizeDevice()) == 1 &&
|
||||||
ctx.Config().SanitizeDevice()[0] == "address" &&
|
ctx.Config().SanitizeDevice()[0] == "address" &&
|
||||||
info.global.SanitizeLite {
|
global.SanitizeLite {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bootDexJars := make(android.Paths, len(info.preoptBootModules))
|
d.defaultBootImage = buildBootImage(ctx, defaultBootImageConfig(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns a *bootImage.
|
||||||
|
func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootImage {
|
||||||
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
|
||||||
|
image := newBootImage(ctx, config)
|
||||||
|
|
||||||
|
bootDexJars := make(android.Paths, len(image.modules))
|
||||||
|
|
||||||
ctx.VisitAllModules(func(module android.Module) {
|
ctx.VisitAllModules(func(module android.Module) {
|
||||||
// Collect dex jar paths for the modules listed above.
|
// Collect dex jar paths for the modules listed above.
|
||||||
if j, ok := module.(Dependency); ok {
|
if j, ok := module.(Dependency); ok {
|
||||||
name := ctx.ModuleName(module)
|
name := ctx.ModuleName(module)
|
||||||
if i := android.IndexList(name, info.preoptBootModules); i != -1 {
|
if i := android.IndexList(name, image.modules); i != -1 {
|
||||||
bootDexJars[i] = j.DexJar()
|
bootDexJars[i] = j.DexJar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,11 +157,11 @@ func (dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
for i := range bootDexJars {
|
for i := range bootDexJars {
|
||||||
if bootDexJars[i] == nil {
|
if bootDexJars[i] == nil {
|
||||||
if ctx.Config().AllowMissingDependencies() {
|
if ctx.Config().AllowMissingDependencies() {
|
||||||
missingDeps = append(missingDeps, info.preoptBootModules[i])
|
missingDeps = append(missingDeps, image.modules[i])
|
||||||
bootDexJars[i] = android.PathForOutput(ctx, "missing")
|
bootDexJars[i] = android.PathForOutput(ctx, "missing")
|
||||||
} else {
|
} else {
|
||||||
ctx.Errorf("failed to find dex jar path for module %q",
|
ctx.Errorf("failed to find dex jar path for module %q",
|
||||||
info.preoptBootModules[i])
|
image.modules[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,31 +173,35 @@ func (dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: android.Cp,
|
Rule: android.Cp,
|
||||||
Input: bootDexJars[i],
|
Input: bootDexJars[i],
|
||||||
Output: info.preoptBootDex[i],
|
Output: image.dexPaths[i],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
profile := bootImageProfileRule(ctx, info, missingDeps)
|
profile := bootImageProfileRule(ctx, image, missingDeps)
|
||||||
|
|
||||||
if !info.global.DisablePreopt {
|
if !global.DisablePreopt {
|
||||||
targets := ctx.Config().Targets[android.Android]
|
targets := ctx.Config().Targets[android.Android]
|
||||||
if ctx.Config().SecondArchIsTranslated() {
|
if ctx.Config().SecondArchIsTranslated() {
|
||||||
targets = targets[:1]
|
targets = targets[:1]
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
dexPreoptBootImageRule(ctx, info, target.Arch.ArchType, profile, missingDeps)
|
buildBootImageRuleForArch(ctx, image, target.Arch.ArchType, profile, missingDeps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return image
|
||||||
}
|
}
|
||||||
|
|
||||||
func dexPreoptBootImageRule(ctx android.SingletonContext, info *bootJarsInfo,
|
func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
|
||||||
arch android.ArchType, profile android.Path, missingDeps []string) {
|
arch android.ArchType, profile android.Path, missingDeps []string) {
|
||||||
|
|
||||||
symbolsDir := info.symbolsDir.Join(ctx, "system/framework", arch.String())
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
|
||||||
|
symbolsDir := image.symbolsDir.Join(ctx, "system/framework", arch.String())
|
||||||
symbolsFile := symbolsDir.Join(ctx, "boot.oat")
|
symbolsFile := symbolsDir.Join(ctx, "boot.oat")
|
||||||
outputDir := info.dir.Join(ctx, "system/framework", arch.String())
|
outputDir := image.dir.Join(ctx, "system/framework", arch.String())
|
||||||
outputPath := info.images[arch]
|
outputPath := image.images[arch]
|
||||||
oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath, arch), "oat")
|
oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath, arch), "oat")
|
||||||
|
|
||||||
rule := android.NewRuleBuilder()
|
rule := android.NewRuleBuilder()
|
||||||
@@ -287,26 +230,26 @@ func dexPreoptBootImageRule(ctx android.SingletonContext, info *bootJarsInfo,
|
|||||||
|
|
||||||
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
|
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
|
||||||
|
|
||||||
cmd.Tool(info.global.Tools.Dex2oat).
|
cmd.Tool(global.Tools.Dex2oat).
|
||||||
Flag("--avoid-storing-invocation").
|
Flag("--avoid-storing-invocation").
|
||||||
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
|
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
|
||||||
Flag("--runtime-arg").FlagWithArg("-Xms", info.global.Dex2oatImageXms).
|
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms).
|
||||||
Flag("--runtime-arg").FlagWithArg("-Xmx", info.global.Dex2oatImageXmx)
|
Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatImageXmx)
|
||||||
|
|
||||||
if profile != nil {
|
if profile != nil {
|
||||||
cmd.FlagWithArg("--compiler-filter=", "speed-profile")
|
cmd.FlagWithArg("--compiler-filter=", "speed-profile")
|
||||||
cmd.FlagWithInput("--profile-file=", profile)
|
cmd.FlagWithInput("--profile-file=", profile)
|
||||||
} else if info.global.PreloadedClasses.Valid() {
|
} else if global.PreloadedClasses.Valid() {
|
||||||
cmd.FlagWithInput("--image-classes=", info.global.PreloadedClasses.Path())
|
cmd.FlagWithInput("--image-classes=", global.PreloadedClasses.Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.global.DirtyImageObjects.Valid() {
|
if global.DirtyImageObjects.Valid() {
|
||||||
cmd.FlagWithInput("--dirty-image-objects=", info.global.DirtyImageObjects.Path())
|
cmd.FlagWithInput("--dirty-image-objects=", global.DirtyImageObjects.Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.
|
cmd.
|
||||||
FlagForEachInput("--dex-file=", info.preoptBootDex.Paths()).
|
FlagForEachInput("--dex-file=", image.dexPaths.Paths()).
|
||||||
FlagForEachArg("--dex-location=", info.preoptBootLocations).
|
FlagForEachArg("--dex-location=", image.dexLocations).
|
||||||
Flag("--generate-debug-info").
|
Flag("--generate-debug-info").
|
||||||
Flag("--generate-build-id").
|
Flag("--generate-build-id").
|
||||||
FlagWithOutput("--oat-symbols=", symbolsFile).
|
FlagWithOutput("--oat-symbols=", symbolsFile).
|
||||||
@@ -316,14 +259,14 @@ func dexPreoptBootImageRule(ctx android.SingletonContext, info *bootJarsInfo,
|
|||||||
FlagWithOutput("--image=", outputPath).
|
FlagWithOutput("--image=", outputPath).
|
||||||
FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress()).
|
FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress()).
|
||||||
FlagWithArg("--instruction-set=", arch.String()).
|
FlagWithArg("--instruction-set=", arch.String()).
|
||||||
FlagWithArg("--instruction-set-variant=", info.global.CpuVariant[arch]).
|
FlagWithArg("--instruction-set-variant=", global.CpuVariant[arch]).
|
||||||
FlagWithArg("--instruction-set-features=", info.global.InstructionSetFeatures[arch]).
|
FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch]).
|
||||||
FlagWithArg("--android-root=", info.global.EmptyDirectory).
|
FlagWithArg("--android-root=", global.EmptyDirectory).
|
||||||
FlagWithArg("--no-inline-from=", "core-oj.jar").
|
FlagWithArg("--no-inline-from=", "core-oj.jar").
|
||||||
Flag("--abort-on-hard-verifier-error")
|
Flag("--abort-on-hard-verifier-error")
|
||||||
|
|
||||||
if info.global.BootFlags != "" {
|
if global.BootFlags != "" {
|
||||||
cmd.Flag(info.global.BootFlags)
|
cmd.Flag(global.BootFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if extraFlags != "" {
|
if extraFlags != "" {
|
||||||
@@ -344,8 +287,8 @@ func dexPreoptBootImageRule(ctx android.SingletonContext, info *bootJarsInfo,
|
|||||||
// exists), and the rest are converted to boot-<name>.art.
|
// exists), and the rest are converted to boot-<name>.art.
|
||||||
// In addition, each .art file has an associated .oat and .vdex file, and an
|
// In addition, each .art file has an associated .oat and .vdex file, and an
|
||||||
// unstripped .oat file
|
// unstripped .oat file
|
||||||
for i, m := range info.preoptBootModules {
|
for i, m := range image.modules {
|
||||||
name := "boot"
|
name := image.name
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
name += "-" + m
|
name += "-" + m
|
||||||
}
|
}
|
||||||
@@ -374,35 +317,37 @@ func dexPreoptBootImageRule(ctx android.SingletonContext, info *bootJarsInfo,
|
|||||||
|
|
||||||
cmd.ImplicitOutputs(extraFiles)
|
cmd.ImplicitOutputs(extraFiles)
|
||||||
|
|
||||||
rule.Build(pctx, ctx, "bootJarsDexpreopt_"+arch.String(), "dexpreopt boot jars "+arch.String())
|
rule.Build(pctx, ctx, image.name+"JarsDexpreopt_"+arch.String(), "dexpreopt "+image.name+" jars "+arch.String())
|
||||||
|
|
||||||
// save output and installed files for makevars
|
// save output and installed files for makevars
|
||||||
info.installs[arch] = rule.Installs()
|
image.installs[arch] = rule.Installs()
|
||||||
info.vdexInstalls[arch] = vdexInstalls
|
image.vdexInstalls[arch] = vdexInstalls
|
||||||
info.unstrippedInstalls[arch] = unstrippedInstalls
|
image.unstrippedInstalls[arch] = unstrippedInstalls
|
||||||
}
|
}
|
||||||
|
|
||||||
const failureMessage = `ERROR: Dex2oat failed to compile a boot image.
|
const failureMessage = `ERROR: Dex2oat failed to compile a boot image.
|
||||||
It is likely that the boot classpath is inconsistent.
|
It is likely that the boot classpath is inconsistent.
|
||||||
Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
|
Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
|
||||||
|
|
||||||
func bootImageProfileRule(ctx android.SingletonContext, info *bootJarsInfo, missingDeps []string) android.WritablePath {
|
func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath {
|
||||||
if !info.global.UseProfileForBootImage || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
|
||||||
|
if !global.UseProfileForBootImage || ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tools := info.global.Tools
|
tools := global.Tools
|
||||||
|
|
||||||
rule := android.NewRuleBuilder()
|
rule := android.NewRuleBuilder()
|
||||||
rule.MissingDeps(missingDeps)
|
rule.MissingDeps(missingDeps)
|
||||||
|
|
||||||
var bootImageProfile android.Path
|
var bootImageProfile android.Path
|
||||||
if len(info.global.BootImageProfiles) > 1 {
|
if len(global.BootImageProfiles) > 1 {
|
||||||
combinedBootImageProfile := info.dir.Join(ctx, "boot-image-profile.txt")
|
combinedBootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt")
|
||||||
rule.Command().Text("cat").Inputs(info.global.BootImageProfiles).Text(">").Output(combinedBootImageProfile)
|
rule.Command().Text("cat").Inputs(global.BootImageProfiles).Text(">").Output(combinedBootImageProfile)
|
||||||
bootImageProfile = combinedBootImageProfile
|
bootImageProfile = combinedBootImageProfile
|
||||||
} else if len(info.global.BootImageProfiles) == 1 {
|
} else if len(global.BootImageProfiles) == 1 {
|
||||||
bootImageProfile = info.global.BootImageProfiles[0]
|
bootImageProfile = global.BootImageProfiles[0]
|
||||||
} else {
|
} else {
|
||||||
// If not set, use the default. Some branches like master-art-host don't have frameworks/base, so manually
|
// If not set, use the default. Some branches like master-art-host don't have frameworks/base, so manually
|
||||||
// handle the case that the default is missing. Those branches won't attempt to build the profile rule,
|
// handle the case that the default is missing. Those branches won't attempt to build the profile rule,
|
||||||
@@ -417,49 +362,40 @@ func bootImageProfileRule(ctx android.SingletonContext, info *bootJarsInfo, miss
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profile := info.dir.Join(ctx, "boot.prof")
|
profile := image.dir.Join(ctx, "boot.prof")
|
||||||
|
|
||||||
rule.Command().
|
rule.Command().
|
||||||
Text(`ANDROID_LOG_TAGS="*:e"`).
|
Text(`ANDROID_LOG_TAGS="*:e"`).
|
||||||
Tool(tools.Profman).
|
Tool(tools.Profman).
|
||||||
FlagWithInput("--create-profile-from=", bootImageProfile).
|
FlagWithInput("--create-profile-from=", bootImageProfile).
|
||||||
FlagForEachInput("--apk=", info.preoptBootDex.Paths()).
|
FlagForEachInput("--apk=", image.dexPaths.Paths()).
|
||||||
FlagForEachArg("--dex-location=", info.preoptBootLocations).
|
FlagForEachArg("--dex-location=", image.dexLocations).
|
||||||
FlagWithOutput("--reference-profile-file=", profile)
|
FlagWithOutput("--reference-profile-file=", profile)
|
||||||
|
|
||||||
rule.Install(profile, "/system/etc/boot-image.prof")
|
rule.Install(profile, "/system/etc/boot-image.prof")
|
||||||
|
|
||||||
rule.Build(pctx, ctx, "bootJarsProfile", "profile boot jars")
|
rule.Build(pctx, ctx, "bootJarsProfile", "profile boot jars")
|
||||||
|
|
||||||
info.profileInstalls = rule.Installs()
|
image.profileInstalls = rule.Installs()
|
||||||
|
|
||||||
return profile
|
return profile
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
// Export paths for default boot image to Make
|
||||||
android.RegisterMakeVarsProvider(pctx, bootImageMakeVars)
|
func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
|
||||||
}
|
image := d.defaultBootImage
|
||||||
|
if image != nil {
|
||||||
|
for arch, _ := range image.images {
|
||||||
|
ctx.Strict("DEXPREOPT_IMAGE_"+arch.String(), image.images[arch].String())
|
||||||
|
|
||||||
// Export paths to Make. INTERNAL_PLATFORM_HIDDENAPI_FLAGS is used by Make rules in art/ and cts/.
|
ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+arch.String(), image.installs[arch].String())
|
||||||
// Both paths are used to call dist-for-goals.
|
ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+arch.String(), image.unstrippedInstalls[arch].String())
|
||||||
func bootImageMakeVars(ctx android.MakeVarsContext) {
|
ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+arch.String(), image.vdexInstalls[arch].String())
|
||||||
if skipDexpreoptBootJars(ctx) {
|
}
|
||||||
return
|
|
||||||
|
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
|
||||||
|
|
||||||
|
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPaths.Strings(), " "))
|
||||||
|
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocations, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
info := dexpreoptBootJarsInfo(ctx)
|
|
||||||
for arch, _ := range info.images {
|
|
||||||
ctx.Strict("DEXPREOPT_IMAGE_"+arch.String(), info.images[arch].String())
|
|
||||||
|
|
||||||
ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+arch.String(), info.installs[arch].String())
|
|
||||||
ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+arch.String(), info.unstrippedInstalls[arch].String())
|
|
||||||
ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+arch.String(), info.vdexInstalls[arch].String())
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", info.profileInstalls.String())
|
|
||||||
|
|
||||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(info.preoptBootDex.Strings(), " "))
|
|
||||||
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(info.preoptBootLocations, " "))
|
|
||||||
ctx.Strict("PRODUCT_BOOTCLASSPATH", info.bootclasspath)
|
|
||||||
ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", info.systemServerClasspath)
|
|
||||||
}
|
}
|
||||||
|
154
java/dexpreopt_config.go
Normal file
154
java/dexpreopt_config.go
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
// Copyright 2019 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"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// dexpreoptGlobalConfig returns the global dexpreopt.config. It is loaded once the first time it is called for any
|
||||||
|
// ctx.Config(), and returns the same data for all future calls with the same ctx.Config(). A value can be inserted
|
||||||
|
// for tests using setDexpreoptTestGlobalConfig.
|
||||||
|
func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig {
|
||||||
|
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
|
||||||
|
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
|
||||||
|
ctx.AddNinjaFileDeps(f)
|
||||||
|
globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, f)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return globalConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// No global config filename set, see if there is a test config set
|
||||||
|
return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} {
|
||||||
|
// Nope, return a config with preopting disabled
|
||||||
|
return dexpreopt.GlobalConfig{
|
||||||
|
DisablePreopt: true,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).(dexpreopt.GlobalConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// setDexpreoptTestGlobalConfig sets a GlobalConfig that future calls to dexpreoptGlobalConfig will return. It must
|
||||||
|
// be called before the first call to dexpreoptGlobalConfig for the config.
|
||||||
|
func setDexpreoptTestGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) {
|
||||||
|
config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfig })
|
||||||
|
}
|
||||||
|
|
||||||
|
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
|
||||||
|
var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
|
||||||
|
|
||||||
|
// systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed
|
||||||
|
// once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
|
||||||
|
// ctx.Config().
|
||||||
|
func systemServerClasspath(ctx android.PathContext) []string {
|
||||||
|
return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string {
|
||||||
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
|
||||||
|
var systemServerClasspathLocations []string
|
||||||
|
for _, m := range global.SystemServerJars {
|
||||||
|
systemServerClasspathLocations = append(systemServerClasspathLocations,
|
||||||
|
filepath.Join("/system/framework", m+".jar"))
|
||||||
|
}
|
||||||
|
return systemServerClasspathLocations
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var systemServerClasspathKey = android.NewOnceKey("systemServerClasspath")
|
||||||
|
|
||||||
|
// defaultBootImageConfig returns the bootImageConfig that will be used to dexpreopt modules. It is computed once the
|
||||||
|
// first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
|
||||||
|
// ctx.Config().
|
||||||
|
func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
|
||||||
|
return ctx.Config().Once(defaultBootImageConfigKey, func() interface{} {
|
||||||
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
|
||||||
|
runtimeModules := global.RuntimeApexJars
|
||||||
|
nonFrameworkModules := concat(runtimeModules, global.ProductUpdatableBootModules)
|
||||||
|
frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
|
||||||
|
|
||||||
|
var nonUpdatableBootModules []string
|
||||||
|
var nonUpdatableBootLocations []string
|
||||||
|
|
||||||
|
for _, m := range runtimeModules {
|
||||||
|
nonUpdatableBootModules = append(nonUpdatableBootModules, m)
|
||||||
|
nonUpdatableBootLocations = append(nonUpdatableBootLocations,
|
||||||
|
filepath.Join("/apex/com.android.runtime/javalib", m+".jar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, m := range frameworkModules {
|
||||||
|
nonUpdatableBootModules = append(nonUpdatableBootModules, m)
|
||||||
|
nonUpdatableBootLocations = append(nonUpdatableBootLocations,
|
||||||
|
filepath.Join("/system/framework", m+".jar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
|
||||||
|
// the bootclasspath modules have been compiled. Set up known paths for them, the singleton rules will copy
|
||||||
|
// them there.
|
||||||
|
// TODO: use module dependencies instead
|
||||||
|
var nonUpdatableBootDexPaths android.WritablePaths
|
||||||
|
for _, m := range nonUpdatableBootModules {
|
||||||
|
nonUpdatableBootDexPaths = append(nonUpdatableBootDexPaths,
|
||||||
|
android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_input", m+".jar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars")
|
||||||
|
symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_unstripped")
|
||||||
|
images := make(map[android.ArchType]android.OutputPath)
|
||||||
|
|
||||||
|
for _, target := range ctx.Config().Targets[android.Android] {
|
||||||
|
images[target.Arch.ArchType] = dir.Join(ctx,
|
||||||
|
"system/framework", target.Arch.ArchType.String(), "boot.art")
|
||||||
|
}
|
||||||
|
|
||||||
|
return bootImageConfig{
|
||||||
|
name: "boot",
|
||||||
|
modules: nonUpdatableBootModules,
|
||||||
|
dexLocations: nonUpdatableBootLocations,
|
||||||
|
dexPaths: nonUpdatableBootDexPaths,
|
||||||
|
dir: dir,
|
||||||
|
symbolsDir: symbolsDir,
|
||||||
|
images: images,
|
||||||
|
}
|
||||||
|
}).(bootImageConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig")
|
||||||
|
|
||||||
|
func defaultBootclasspath(ctx android.PathContext) []string {
|
||||||
|
return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string {
|
||||||
|
global := dexpreoptGlobalConfig(ctx)
|
||||||
|
image := defaultBootImageConfig(ctx)
|
||||||
|
bootclasspath := append(copyOf(image.dexLocations), global.ProductUpdatableBootLocations...)
|
||||||
|
return bootclasspath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultBootclasspathKey = android.NewOnceKey("defaultBootclasspath")
|
||||||
|
|
||||||
|
var copyOf = android.CopyOf
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
android.RegisterMakeVarsProvider(pctx, dexpreoptConfigMakevars)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
|
||||||
|
ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
|
||||||
|
ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
|
||||||
|
}
|
@@ -32,7 +32,7 @@ func TestConfig(buildDir string, env map[string]string) android.Config {
|
|||||||
config.TestProductVariables.DeviceSystemSdkVersions = []string{"14", "15"}
|
config.TestProductVariables.DeviceSystemSdkVersions = []string{"14", "15"}
|
||||||
|
|
||||||
pathCtx := android.PathContextForTesting(config, nil)
|
pathCtx := android.PathContextForTesting(config, nil)
|
||||||
setDexpreoptGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
|
setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
|
||||||
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user