Merge changes I4e721b47,I1bf05ade

* changes:
  Generate app profiles even if dexpreopt is disabled.
  Generate boot image profiles even if dexpreopt is disabled.
This commit is contained in:
Jiakai Zhang 2023-05-04 22:13:08 +00:00 committed by Gerrit Code Review
commit dbfcf85c53
12 changed files with 109 additions and 40 deletions

View file

@ -813,6 +813,20 @@ func normalizePathRelativeToTop(path Path) Path {
return path.RelativeToTop()
}
func allOutputs(p BuildParams) []string {
outputs := append(WritablePaths(nil), p.Outputs...)
outputs = append(outputs, p.ImplicitOutputs...)
if p.Output != nil {
outputs = append(outputs, p.Output)
}
return outputs.Strings()
}
// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
func (p TestingBuildParams) AllOutputs() []string {
return allOutputs(p.BuildParams)
}
// baseTestingComponent provides functionality common to both TestingModule and TestingSingleton.
type baseTestingComponent struct {
config Config
@ -954,12 +968,7 @@ func (b baseTestingComponent) buildParamsFromOutput(file string) TestingBuildPar
func (b baseTestingComponent) allOutputs() []string {
var outputFullPaths []string
for _, p := range b.provider.BuildParamsForTests() {
outputs := append(WritablePaths(nil), p.Outputs...)
outputs = append(outputs, p.ImplicitOutputs...)
if p.Output != nil {
outputs = append(outputs, p.Output)
}
outputFullPaths = append(outputFullPaths, outputs.Strings()...)
outputFullPaths = append(outputFullPaths, allOutputs(p)...)
}
return outputFullPaths
}

View file

@ -2681,7 +2681,7 @@ func apexBootclasspathFragmentFiles(ctx android.ModuleContext, module blueprint.
}
pathInApex := bootclasspathFragmentInfo.ProfileInstallPathInApex()
if pathInApex != "" && !java.SkipDexpreoptBootJars(ctx) {
if pathInApex != "" {
pathOnHost := bootclasspathFragmentInfo.ProfilePathOnHost()
tempPath := android.PathForModuleOut(ctx, "boot_image_profile", pathInApex)

View file

@ -497,6 +497,26 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
})
})
t.Run("generate boot image profile even if dexpreopt is disabled", func(t *testing.T) {
result := android.GroupFixturePreparers(
commonPreparer,
// Configure some libraries in the art bootclasspath_fragment that match the source
// bootclasspath_fragment's contents property.
java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
addSource("foo", "bar"),
java.FixtureSetBootImageInstallDirOnDevice("art", "system/framework"),
dexpreopt.FixtureDisableDexpreoptBootImages(true),
).RunTest(t)
ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
"etc/boot-image.prof",
"etc/classpaths/bootclasspath.pb",
"javalib/bar.jar",
"javalib/foo.jar",
})
})
t.Run("boot image disable generate profile", func(t *testing.T) {
result := android.GroupFixturePreparers(
commonPreparer,

View file

@ -100,11 +100,19 @@ func GenerateDexpreoptRule(ctx android.BuilderContext, globalSoong *GlobalSoongC
return rule, nil
}
// If dexpreopt is applicable to the module, returns whether dexpreopt is disabled. Otherwise, the
// behavior is undefined.
// When it returns true, dexpreopt artifacts will not be generated, but profile will still be
// generated if profile-guided compilation is requested.
func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *ModuleConfig) bool {
if ctx.Config().UnbundledBuild() {
return true
}
if global.DisablePreopt {
return true
}
if contains(global.DisablePreoptModules, module.Name) {
return true
}

View file

@ -174,3 +174,17 @@ func FixtureDisableGenerateProfile(disable bool) android.FixturePreparer {
dexpreoptConfig.DisableGenerateProfile = disable
})
}
// FixtureDisableDexpreoptBootImages sets the DisablePreoptBootImages property in the global config.
func FixtureDisableDexpreoptBootImages(disable bool) android.FixturePreparer {
return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.DisablePreoptBootImages = disable
})
}
// FixtureDisableDexpreopt sets the DisablePreopt property in the global config.
func FixtureDisableDexpreopt(disable bool) android.FixturePreparer {
return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
dexpreoptConfig.DisablePreopt = disable
})
}

View file

@ -506,10 +506,6 @@ func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorCon
}
}
if SkipDexpreoptBootJars(ctx) {
return
}
// 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)
@ -901,10 +897,6 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC
// produceBootImageFiles builds the boot image files from the source if it is required.
func (b *BootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageOutputs {
if SkipDexpreoptBootJars(ctx) {
return bootImageOutputs{}
}
// Only generate the boot image if the configuration does not skip it.
return b.generateBootImageBuildActions(ctx, imageConfig)
}
@ -932,6 +924,13 @@ func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.
// Build boot image files for the host variants.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
// 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 android variants.
bootImageFiles := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)

View file

@ -23,7 +23,7 @@ import (
)
func TestR8(t *testing.T) {
result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, `
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
srcs: ["foo.java"],
@ -191,7 +191,7 @@ func TestR8TransitiveDeps(t *testing.T) {
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
fixturePreparer := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd
fixturePreparer := PrepareForTestWithJavaDefaultModules
if tc.unbundled {
fixturePreparer = android.GroupFixturePreparers(
fixturePreparer,
@ -258,7 +258,7 @@ func TestR8TransitiveDeps(t *testing.T) {
}
func TestR8Flags(t *testing.T) {
result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, `
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
srcs: ["foo.java"],
@ -287,7 +287,7 @@ func TestR8Flags(t *testing.T) {
}
func TestD8(t *testing.T) {
result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, `
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
java_library {
name: "foo",
srcs: ["foo.java"],
@ -328,7 +328,7 @@ func TestD8(t *testing.T) {
}
func TestProguardFlagsInheritance(t *testing.T) {
result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, `
result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, `
android_app {
name: "app",
static_libs: [

View file

@ -180,6 +180,8 @@ func moduleName(ctx android.BaseModuleContext) string {
return android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
}
// Returns whether dexpreopt is applicable to the module.
// When it returns true, neither profile nor dexpreopt artifacts will be generated.
func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
if !ctx.Device() {
return true
@ -205,14 +207,6 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
global := dexpreopt.GetGlobalConfig(ctx)
if global.DisablePreopt {
return true
}
if inList(moduleName(ctx), global.DisablePreoptModules) {
return true
}
isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
if isApexVariant(ctx) {
// Don't preopt APEX variant module unless the module is an APEX system server jar.

View file

@ -500,9 +500,6 @@ func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContex
// Generate build rules for boot images.
func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) {
if SkipDexpreoptBootJars(ctx) {
return
}
if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil {
// No module has enabled dexpreopting, so we assume there will be no boot image to make.
return
@ -1014,6 +1011,10 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA", image.profileLicenseMetadataFile.String())
}
if SkipDexpreoptBootJars(ctx) {
return
}
global := dexpreopt.GetGlobalConfig(ctx)
dexPaths, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp)
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " "))

View file

@ -438,3 +438,28 @@ func TestAndroidMkEntriesForApex(t *testing.T) {
android.AssertIntEquals(t, "entries count", 0, len(entriesList))
}
func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) {
preparers := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
PrepareForTestWithFakeApexMutator,
dexpreopt.FixtureDisableDexpreopt(true),
)
result := preparers.RunTestWithBp(t, `
java_library {
name: "foo",
installable: true,
dex_preopt: {
profile: "art-profile",
},
srcs: ["a.java"],
}`)
ctx := result.TestContext
dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt")
expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/profile.prof"}
android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs())
}

View file

@ -103,10 +103,6 @@ func (b *platformBootclasspathModule) OutputFiles(tag string) (android.Paths, er
func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
b.hiddenAPIDepsMutator(ctx)
if SkipDexpreoptBootJars(ctx) {
return
}
// 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)
@ -187,11 +183,6 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo
bootDexJarByModule := b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments)
buildRuleForBootJarsPackageCheck(ctx, bootDexJarByModule)
// Nothing to do if skipping the dexpreopt of boot image jars.
if SkipDexpreoptBootJars(ctx) {
return
}
b.generateBootImageBuildActions(ctx, platformModules, apexModules)
}
@ -429,6 +420,12 @@ func (b *platformBootclasspathModule) generateBootImage(ctx android.ModuleContex
// 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)

View file

@ -19,12 +19,14 @@ import (
"testing"
"android/soong/android"
"android/soong/dexpreopt"
"android/soong/java"
)
var prepareForSdkTestWithJava = android.GroupFixturePreparers(
java.PrepareForTestWithJavaBuildComponents,
PrepareForTestWithSdkBuildComponents,
dexpreopt.PrepareForTestWithFakeDex2oatd,
// Ensure that all source paths are provided. This helps ensure that the snapshot generation is
// consistent and all files referenced from the snapshot's Android.bp file have actually been