diff options
author | 2025-02-10 16:24:40 -0800 | |
---|---|---|
committer | 2025-02-18 12:51:57 -0800 | |
commit | ed6f2b2921c5b7901f674094a50f18794b9e10c9 (patch) | |
tree | 26355259d8fa4a55a073120c6184bcba129e0c34 | |
parent | 367dac6d541202f3d090e09cf41e5a3fdba4849e (diff) |
Support `use_d8` partial compile flag
Make `use_d8` an opt-out flag (when SOONG_PARTIAL_COMPILE=true).
Bug: b/374975543
Test: manual, TH
Change-Id: Iaef4bb5243957812783c5dbc79a5bf27e1096166
-rw-r--r-- | android/config.go | 19 | ||||
-rw-r--r-- | android/config_test.go | 6 | ||||
-rw-r--r-- | java/dex.go | 179 |
3 files changed, 149 insertions, 55 deletions
diff --git a/android/config.go b/android/config.go index acaad60ad..3867c1197 100644 --- a/android/config.go +++ b/android/config.go @@ -394,6 +394,17 @@ type partialCompileFlags struct { // Add others as needed. } +// These are the flags when `SOONG_PARTIAL_COMPILE` is empty or not set. +var defaultPartialCompileFlags = partialCompileFlags{ + Enabled: false, +} + +// These are the flags when `SOONG_PARTIAL_COMPILE=true`. +var enabledPartialCompileFlags = partialCompileFlags{ + Enabled: true, + Use_d8: true, +} + type deviceConfig struct { config *config OncePer @@ -427,11 +438,6 @@ type jsonConfigurable interface { // To add a new feature to the list, add the field in the struct // `partialCompileFlags` above, and then add the name of the field in the // switch statement below. -var defaultPartialCompileFlags = partialCompileFlags{ - // Set any opt-out flags here. Opt-in flags are off by default. - Enabled: false, -} - func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, error) { if !isEngBuild { return partialCompileFlags{}, nil @@ -472,8 +478,7 @@ func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, } switch tok { case "true": - ret = defaultPartialCompileFlags - ret.Enabled = true + ret = enabledPartialCompileFlags case "false": // Set everything to false. ret = partialCompileFlags{} diff --git a/android/config_test.go b/android/config_test.go index 4bdf05f0e..3d8686041 100644 --- a/android/config_test.go +++ b/android/config_test.go @@ -239,10 +239,10 @@ func TestPartialCompile(t *testing.T) { }{ {"", true, defaultPartialCompileFlags}, {"false", true, partialCompileFlags{}}, - {"true", true, defaultPartialCompileFlags.updateEnabled(true)}, + {"true", true, enabledPartialCompileFlags}, {"true", false, partialCompileFlags{}}, - {"true,use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(true)}, - {"true,-use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(false)}, + {"true,use_d8", true, enabledPartialCompileFlags.updateUseD8(true)}, + {"true,-use_d8", true, enabledPartialCompileFlags.updateUseD8(false)}, {"use_d8,false", true, partialCompileFlags{}}, {"false,+use_d8", true, partialCompileFlags{}.updateUseD8(true)}, } diff --git a/java/dex.go b/java/dex.go index 64465a2de..e5f41ea7d 100644 --- a/java/dex.go +++ b/java/dex.go @@ -170,6 +170,71 @@ var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8", }, }, []string{"outDir", "d8Flags", "zipFlags", "mergeZipsFlags"}, nil) +// Include all of the args for d8r8, so that we can generate the partialcompileclean target's build using the same list. +var d8r8Clean = pctx.AndroidStaticRule("d8r8-partialcompileclean", + blueprint.RuleParams{ + Command: `rm -rf "${outDir}" "${outDict}" "${outConfig}" "${outUsage}" "${outUsageZip}" "${outUsageDir}" ` + + `"${resourcesOutput}" "${outR8ArtProfile}" ${builtOut}`, + }, "outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "builtOut", + "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile", "implicits", +) + +var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8", + blueprint.RuleParams{ + Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + + `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` + + `mkdir -p $$(dirname ${outUsage}) && ` + + `if [ -n "$${SOONG_USE_PARTIAL_COMPILE}" ]; then ` + + ` for f in "${outConfig}" "${outDict}" "${outUsage}" "${resourcesOutput}"; do ` + + ` test -n "$${f}" && test ! -f "$${f}" && mkdir -p "$$(dirname "$${f}")" && touch "$${f}" || true; ` + + ` done && ` + + ` $d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in; ` + + `else ` + + ` $r8Template${config.R8Cmd} ${config.R8Flags} $r8Flags -injars $in --output $outDir ` + + ` --no-data-resources ` + + ` -printmapping ${outDict} ` + + ` -printconfiguration ${outConfig} ` + + ` -printusage ${outUsage} ` + + ` --deps-file ${out}.d && ` + + ` touch "${outDict}" "${outConfig}" "${outUsage}"; ` + + `fi && ` + + `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` + + `rm -rf ${outUsageDir} && ` + + `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + + `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` + + `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `, + CommandDeps: []string{ + "${config.D8Cmd}", + "${config.R8Cmd}", + "${config.SoongZipCmd}", + "${config.MergeZipsCmd}", + }, + }, map[string]*remoteexec.REParams{ + "$d8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "d8"}, + Inputs: []string{"${config.D8Jar}"}, + ExecStrategy: "${config.RED8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$r8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "r8"}, + Inputs: []string{"$implicits", "${config.R8Jar}"}, + OutputFiles: []string{"${outUsage}", "${outConfig}", "${outDict}", "${resourcesOutput}", "${outR8ArtProfile}"}, + ExecStrategy: "${config.RER8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$zipTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "tool", "name": "soong_zip"}, + Inputs: []string{"${config.SoongZipCmd}", "$outDir"}, + OutputFiles: []string{"$outDir/classes.dex.jar"}, + ExecStrategy: "${config.RED8ExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + }, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", + "d8Flags", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"}) + var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + @@ -482,6 +547,7 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam // Compile classes.jar into classes.dex and then javalib.jar javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath + cleanPhonyPath := android.PathForModuleOut(ctx, "dex", dexParams.jarName+"-partialcompileclean").OutputPath outDir := android.PathForModuleOut(ctx, "dex") zipFlags := "--ignore_missing_files" @@ -498,7 +564,20 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam } useR8 := d.effectiveOptimizeEnabled() + useD8 := !useR8 || ctx.Config().PartialCompileFlags().Use_d8 + rbeR8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") + rbeD8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") + var rule blueprint.Rule + var description string var artProfileOutputPath *android.OutputPath + var implicitOutputs android.WritablePaths + var flags []string + var deps android.Paths + args := map[string]string{ + "zipFlags": zipFlags, + "outDir": outDir.String(), + "mergeZipsFlags": mergeZipsFlags, + } if useR8 { proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary") d.proguardDictionary = android.OptionalPathForPath(proguardDictionary) @@ -511,25 +590,17 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip) resourcesOutput := android.PathForModuleOut(ctx, "package-res-shrunken.apk") d.resourcesOutput = android.OptionalPathForPath(resourcesOutput) - implicitOutputs := android.WritablePaths{ + implicitOutputs = append(implicitOutputs, android.WritablePaths{ proguardDictionary, proguardUsageZip, proguardConfiguration, - } + }...) + description = "r8" debugMode := android.InList("--debug", commonFlags) r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode) - rule := r8 - args := map[string]string{ - "r8Flags": strings.Join(append(commonFlags, r8Flags...), " "), - "zipFlags": zipFlags, - "outDict": proguardDictionary.String(), - "outConfig": proguardConfiguration.String(), - "outUsageDir": proguardUsageDir.String(), - "outUsage": proguardUsage.String(), - "outUsageZip": proguardUsageZip.String(), - "outDir": outDir.String(), - "mergeZipsFlags": mergeZipsFlags, - } + flags = append(flags, r8Flags...) + deps = append(deps, r8Deps...) + args["r8Flags"] = strings.Join(append(commonFlags, r8Flags...), " ") if r8ArtProfileOutputPath != nil { artProfileOutputPath = r8ArtProfileOutputPath implicitOutputs = append( @@ -540,27 +611,29 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam // about this implicit output args["outR8ArtProfile"] = artProfileOutputPath.String() } - - if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") { - rule = r8RE - args["implicits"] = strings.Join(r8Deps.Strings(), ",") - } + args["outDict"] = proguardDictionary.String() + args["outConfig"] = proguardConfiguration.String() + args["outUsageDir"] = proguardUsageDir.String() + args["outUsage"] = proguardUsage.String() + args["outUsageZip"] = proguardUsageZip.String() if d.resourcesInput.Valid() { implicitOutputs = append(implicitOutputs, resourcesOutput) args["resourcesOutput"] = resourcesOutput.String() } - ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: "r8", - Output: javalibJar, - ImplicitOutputs: implicitOutputs, - Input: dexParams.classesJar, - Implicits: r8Deps, - Args: args, - }) - } else { - implicitOutputs := android.WritablePaths{} + + rule = r8 + if rbeR8 { + rule = r8RE + args["implicits"] = strings.Join(deps.Strings(), ",") + } + } + if useD8 { + description = "d8" d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams) + flags = append(flags, d8Flags...) + deps = append(deps, d8Deps...) + deps = append(deps, commonDeps...) + args["d8Flags"] = strings.Join(append(commonFlags, d8Flags...), " ") if d8ArtProfileOutputPath != nil { artProfileOutputPath = d8ArtProfileOutputPath implicitOutputs = append( @@ -568,26 +641,42 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam artProfileOutputPath, ) } - d8Deps = append(d8Deps, commonDeps...) - rule := d8 - if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") { + // If we are generating both d8 and r8, only use RBE when both are enabled. + switch { + case useR8 && rule == r8: + rule = d8r8 + description = "d8r8" + case useR8 && rule == r8RE && rbeD8: + rule = d8r8RE + description = "d8r8" + case rbeD8: rule = d8RE + default: + rule = d8 } + } + ctx.Build(pctx, android.BuildParams{ + Rule: rule, + Description: description, + Output: javalibJar, + ImplicitOutputs: implicitOutputs, + Input: dexParams.classesJar, + Implicits: deps, + Args: args, + }) + if useR8 && useD8 { + // Generate the rule for partial compile clean. + args["builtOut"] = javalibJar.String() ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: "d8", - Output: javalibJar, - Input: dexParams.classesJar, - ImplicitOutputs: implicitOutputs, - Implicits: d8Deps, - Args: map[string]string{ - "d8Flags": strings.Join(append(commonFlags, d8Flags...), " "), - "zipFlags": zipFlags, - "outDir": outDir.String(), - "mergeZipsFlags": mergeZipsFlags, - }, + Rule: d8r8Clean, + Description: "d8r8Clean", + Output: cleanPhonyPath, + Args: args, + PhonyOutput: true, }) + ctx.Phony("partialcompileclean", cleanPhonyPath) } + if proptools.Bool(d.dexProperties.Uncompress_dex) { alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath TransformZipAlign(ctx, alignedJavalibJar, javalibJar, nil) |