Loading dexpreopt/config.go +2 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ type GlobalConfig struct { OnlyPreoptBootImageAndSystemServer bool // only preopt jars in the boot image or system server PreoptWithUpdatableBcp bool // If updatable boot jars are included in dexpreopt or not. UseArtImage bool // use the art image (use other boot class path dex files without image) HasSystemOther bool // store odex files that match PatternsOnSystemOther on the system_other partition Loading dexpreopt/testing.go +14 −0 Original line number Diff line number Diff line Loading @@ -117,3 +117,17 @@ func FixtureSetBootJars(bootJars ...string) android.FixturePreparer { dexpreoptConfig.BootJars = android.CreateTestConfiguredJarList(bootJars) }) } // FixtureSetUpdatableBootJars sets the UpdatableBootJars property in the global config. func FixtureSetUpdatableBootJars(bootJars ...string) android.FixturePreparer { return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) { dexpreoptConfig.UpdatableBootJars = android.CreateTestConfiguredJarList(bootJars) }) } // FixtureSetPreoptWithUpdatableBcp sets the PreoptWithUpdatableBcp property in the global config. func FixtureSetPreoptWithUpdatableBcp(value bool) android.FixturePreparer { return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) { dexpreoptConfig.PreoptWithUpdatableBcp = value }) } java/app_test.go +61 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import ( "android/soong/android" "android/soong/cc" "android/soong/dexpreopt" "android/soong/genrule" ) Loading Loading @@ -2422,6 +2423,66 @@ func TestUsesLibraries(t *testing.T) { `#PCL[/system/framework/android.test.mock.jar] `) } func TestDexpreoptBcp(t *testing.T) { bp := ` java_sdk_library { name: "foo", srcs: ["a.java"], api_packages: ["foo"], sdk_version: "current", } java_sdk_library { name: "bar", srcs: ["a.java"], api_packages: ["bar"], permitted_packages: ["bar"], sdk_version: "current", } android_app { name: "app", srcs: ["a.java"], sdk_version: "current", } ` testCases := []struct { name string with bool expect string }{ { name: "with updatable bcp", with: true, expect: "/system/framework/foo.jar:/system/framework/bar.jar", }, { name: "without updatable bcp", with: false, expect: "/system/framework/foo.jar", }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { result := android.GroupFixturePreparers( prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("runtime-library", "foo", "bar"), dexpreopt.FixtureSetBootJars("platform:foo"), dexpreopt.FixtureSetUpdatableBootJars("platform:bar"), dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with), ).RunTestWithBp(t, bp) app := result.ModuleForTests("app", "android_common") cmd := app.Rule("dexpreopt").RuleParams.Command bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp) }) } } func TestCodelessApp(t *testing.T) { testCases := []struct { name string Loading java/dexpreopt.go +8 −5 Original line number Diff line number Diff line Loading @@ -160,14 +160,17 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx) isSystemServerJar := inList(ctx.ModuleName(), global.SystemServerJars) bootImage := defaultBootImageConfig(ctx) dexFiles := bootImage.dexPathsDeps.Paths() // The dex locations for all Android variants are identical. dexLocations := bootImage.getAnyAndroidVariant().dexLocationsDeps 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 Loading @@ -176,7 +179,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr targets = append(targets, target) } } if inList(ctx.ModuleName(), global.SystemServerJars) && !d.isSDKLibrary { 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] } Loading Loading @@ -237,7 +240,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr DexPreoptImagesDeps: imagesDeps, DexPreoptImageLocations: imageLocations, PreoptBootClassPathDexFiles: dexFiles, PreoptBootClassPathDexFiles: dexFiles.Paths(), PreoptBootClassPathDexLocations: dexLocations, PreoptExtractedApk: false, Loading java/dexpreopt_bootjars.go +22 −2 Original line number Diff line number Diff line Loading @@ -439,6 +439,8 @@ func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonC // Create boot image for the ART apex (build artifacts are accessed via the global boot image config). d.otherImages = append(d.otherImages, buildBootImage(ctx, artBootImageConfig(ctx))) copyUpdatableBootJars(ctx) dumpOatRules(ctx, d.defaultBootImage) } Loading Loading @@ -630,6 +632,21 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI return image } // Generate commands that will copy updatable boot jars to predefined paths in the global config. func copyUpdatableBootJars(ctx android.SingletonContext) { config := GetUpdatableBootConfig(ctx) getBootJarFunc := func(module android.Module) (int, android.Path) { index, jar, _ := getBootJar(ctx, config.modules, module, "configured in updatable boot jars ") return index, jar } missingDeps := findAndCopyBootJars(ctx, config.modules, config.dexPaths, getBootJarFunc) // Ignoring missing dependencies here. Ideally they should be added to the dexpreopt rule, but // that is not possible as this rule is created after dexpreopt rules (it's in a singleton // context, and they are in a module context). The true fix is to add dependencies from the // dexpreopted modules on updatable boot jars and avoid this copying altogether. _ = missingDeps } // Generate boot image build rules for a specific target. func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant, profile android.Path, missingDeps []string) android.WritablePaths { Loading Loading @@ -997,8 +1014,11 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { image := d.defaultBootImage if image != nil { ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String()) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " ")) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.getAnyAndroidVariant().dexLocationsDeps, " ")) global := dexpreopt.GetGlobalConfig(ctx) dexPaths, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " ")) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(dexLocations, " ")) var imageNames []string // TODO: the primary ART boot image should not be exposed to Make, as it is installed in a Loading Loading
dexpreopt/config.go +2 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,8 @@ type GlobalConfig struct { OnlyPreoptBootImageAndSystemServer bool // only preopt jars in the boot image or system server PreoptWithUpdatableBcp bool // If updatable boot jars are included in dexpreopt or not. UseArtImage bool // use the art image (use other boot class path dex files without image) HasSystemOther bool // store odex files that match PatternsOnSystemOther on the system_other partition Loading
dexpreopt/testing.go +14 −0 Original line number Diff line number Diff line Loading @@ -117,3 +117,17 @@ func FixtureSetBootJars(bootJars ...string) android.FixturePreparer { dexpreoptConfig.BootJars = android.CreateTestConfiguredJarList(bootJars) }) } // FixtureSetUpdatableBootJars sets the UpdatableBootJars property in the global config. func FixtureSetUpdatableBootJars(bootJars ...string) android.FixturePreparer { return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) { dexpreoptConfig.UpdatableBootJars = android.CreateTestConfiguredJarList(bootJars) }) } // FixtureSetPreoptWithUpdatableBcp sets the PreoptWithUpdatableBcp property in the global config. func FixtureSetPreoptWithUpdatableBcp(value bool) android.FixturePreparer { return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) { dexpreoptConfig.PreoptWithUpdatableBcp = value }) }
java/app_test.go +61 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import ( "android/soong/android" "android/soong/cc" "android/soong/dexpreopt" "android/soong/genrule" ) Loading Loading @@ -2422,6 +2423,66 @@ func TestUsesLibraries(t *testing.T) { `#PCL[/system/framework/android.test.mock.jar] `) } func TestDexpreoptBcp(t *testing.T) { bp := ` java_sdk_library { name: "foo", srcs: ["a.java"], api_packages: ["foo"], sdk_version: "current", } java_sdk_library { name: "bar", srcs: ["a.java"], api_packages: ["bar"], permitted_packages: ["bar"], sdk_version: "current", } android_app { name: "app", srcs: ["a.java"], sdk_version: "current", } ` testCases := []struct { name string with bool expect string }{ { name: "with updatable bcp", with: true, expect: "/system/framework/foo.jar:/system/framework/bar.jar", }, { name: "without updatable bcp", with: false, expect: "/system/framework/foo.jar", }, } for _, test := range testCases { t.Run(test.name, func(t *testing.T) { result := android.GroupFixturePreparers( prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("runtime-library", "foo", "bar"), dexpreopt.FixtureSetBootJars("platform:foo"), dexpreopt.FixtureSetUpdatableBootJars("platform:bar"), dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with), ).RunTestWithBp(t, bp) app := result.ModuleForTests("app", "android_common") cmd := app.Rule("dexpreopt").RuleParams.Command bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp) }) } } func TestCodelessApp(t *testing.T) { testCases := []struct { name string Loading
java/dexpreopt.go +8 −5 Original line number Diff line number Diff line Loading @@ -160,14 +160,17 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) global := dexpreopt.GetGlobalConfig(ctx) isSystemServerJar := inList(ctx.ModuleName(), global.SystemServerJars) bootImage := defaultBootImageConfig(ctx) dexFiles := bootImage.dexPathsDeps.Paths() // The dex locations for all Android variants are identical. dexLocations := bootImage.getAnyAndroidVariant().dexLocationsDeps 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 Loading @@ -176,7 +179,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr targets = append(targets, target) } } if inList(ctx.ModuleName(), global.SystemServerJars) && !d.isSDKLibrary { 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] } Loading Loading @@ -237,7 +240,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr DexPreoptImagesDeps: imagesDeps, DexPreoptImageLocations: imageLocations, PreoptBootClassPathDexFiles: dexFiles, PreoptBootClassPathDexFiles: dexFiles.Paths(), PreoptBootClassPathDexLocations: dexLocations, PreoptExtractedApk: false, Loading
java/dexpreopt_bootjars.go +22 −2 Original line number Diff line number Diff line Loading @@ -439,6 +439,8 @@ func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonC // Create boot image for the ART apex (build artifacts are accessed via the global boot image config). d.otherImages = append(d.otherImages, buildBootImage(ctx, artBootImageConfig(ctx))) copyUpdatableBootJars(ctx) dumpOatRules(ctx, d.defaultBootImage) } Loading Loading @@ -630,6 +632,21 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI return image } // Generate commands that will copy updatable boot jars to predefined paths in the global config. func copyUpdatableBootJars(ctx android.SingletonContext) { config := GetUpdatableBootConfig(ctx) getBootJarFunc := func(module android.Module) (int, android.Path) { index, jar, _ := getBootJar(ctx, config.modules, module, "configured in updatable boot jars ") return index, jar } missingDeps := findAndCopyBootJars(ctx, config.modules, config.dexPaths, getBootJarFunc) // Ignoring missing dependencies here. Ideally they should be added to the dexpreopt rule, but // that is not possible as this rule is created after dexpreopt rules (it's in a singleton // context, and they are in a module context). The true fix is to add dependencies from the // dexpreopted modules on updatable boot jars and avoid this copying altogether. _ = missingDeps } // Generate boot image build rules for a specific target. func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant, profile android.Path, missingDeps []string) android.WritablePaths { Loading Loading @@ -997,8 +1014,11 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { image := d.defaultBootImage if image != nil { ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String()) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " ")) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.getAnyAndroidVariant().dexLocationsDeps, " ")) global := dexpreopt.GetGlobalConfig(ctx) dexPaths, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " ")) ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(dexLocations, " ")) var imageNames []string // TODO: the primary ART boot image should not be exposed to Make, as it is installed in a Loading