aboutsummaryrefslogtreecommitdiff
path: root/java/dex.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/dex.go')
-rw-r--r--java/dex.go358
1 files changed, 321 insertions, 37 deletions
diff --git a/java/dex.go b/java/dex.go
index e3058e9bf..fa38d6131 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -15,6 +15,8 @@
package java
import (
+ "fmt"
+ "path/filepath"
"strconv"
"strings"
@@ -25,6 +27,10 @@ import (
"android/soong/remoteexec"
)
+func init() {
+ pctx.HostBinToolVariable("symbols_map", "symbols_map")
+}
+
type DexProperties struct {
// If set to true, compile dex regardless of installable. Defaults to false.
Compile_dex *bool
@@ -80,9 +86,10 @@ type DexProperties struct {
Shrink *bool
// If true, optimize bytecode. Defaults to false.
- Optimize *bool
+ Optimize proptools.Configurable[bool] `android:"replace_instead_of_append"`
- // If true, obfuscate bytecode. Defaults to false.
+ // If true, obfuscate bytecode by renaming packages, classes, and members.
+ // Defaults to false.
Obfuscate *bool
// If true, do not use the flag files generated by aapt that automatically keep
@@ -135,6 +142,11 @@ type DexProperties struct {
// TODO(b/212737576): Handle this implicitly using bottom-up deps mutation and implicit
// creation of a proxy `.impl` library.
Trace_references_from proptools.Configurable[[]string] `android:"arch_variant"`
+
+ // Add libraries using `--classpath` instead of `--libs`, to allow overrides. This
+ // should normally not be used, but can be necessary when running R8 on the boot
+ // classpath itself.
+ Import_libraries_as_classpath *bool
}
// Keep the data uncompressed. We always need uncompressed dex for execution,
@@ -182,10 +194,125 @@ func (d *DexProperties) optimizedResourceShrinkingEnabled(ctx android.ModuleCont
return d.resourceShrinkingEnabled(ctx) && BoolDefault(d.Optimize.Optimized_shrink_resources, ctx.Config().UseOptimizedResourceShrinkingByDefault())
}
-func (d *dexer) optimizeOrObfuscateEnabled(ctx android.EarlyModuleContext) bool {
- return d.effectiveOptimizeEnabled(ctx) && (proptools.Bool(d.dexProperties.Optimize.Optimize) || proptools.Bool(d.dexProperties.Optimize.Obfuscate))
+func (d *dexer) optimizeOrObfuscateEnabled(ctx android.ModuleContext) bool {
+ return d.effectiveOptimizeEnabled(ctx) && (d.dexProperties.Optimize.Optimize.GetOrDefault(ctx, false) || proptools.Bool(d.dexProperties.Optimize.Obfuscate))
}
+// Removes all outputs of d8Inc rule
+var d8IncClean = pctx.AndroidStaticRule("d8Inc-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "${outDir}" "${builtOut}" "${d8Deps}"`,
+ }, "outDir", "d8Flags", "d8Deps", "zipFlags", "mergeZipsFlags", "builtOut",
+)
+
+var d8Inc, d8IncRE = pctx.MultiCommandRemoteStaticRules("d8Inc",
+ blueprint.RuleParams{
+ Command: `mkdir -p "$outDir" "$outDir/packages" && ` +
+ `${config.IncrementalDexInputCmd} ` +
+ `--classesJar $in --dexTarget $out --deps $d8Deps --outputDir $outDir --packageOutputDir $outDir/packages && ` +
+ `$d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in --packages $out.rsp --mod-packages $out.inc.rsp --package-output $outDir/packages && ` +
+ `$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 && ` +
+ `if [ -f "$out.input.pc_state.new" ]; then mv "$out.input.pc_state.new" "$out.input.pc_state" && ` +
+ `rm -rf $out.input.pc_state.new; fi && ` +
+ `if [ -f "$out.deps.pc_state.new" ]; then mv "$out.deps.pc_state.new" "$out.deps.pc_state" && ` +
+ `rm -rf $out.deps.pc_state.new; fi && ` +
+ `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar"`,
+ CommandDeps: []string{
+ "${config.IncrementalDexInputCmd}",
+ "${config.D8Cmd}",
+ "${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}"},
+ },
+ "$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", "d8Flags", "zipFlags", "mergeZipsFlags", "d8Deps"}, nil)
+
+// Include all of the args for d8IncR8, so that we can generate the partialcompileclean target's build using the same list.
+var d8IncR8Clean = pctx.AndroidStaticRule("d8Incr8-partialcompileclean",
+ blueprint.RuleParams{
+ Command: `rm -rf "${outDir}" "${outDict}" "${outConfig}" "${outUsage}" "${outUsageZip}" "${outUsageDir}" ` +
+ `"${resourcesOutput}" "${outR8ArtProfile}" ${builtOut} ${d8Deps}`,
+ }, "outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "builtOut",
+ "d8Flags", "d8Deps", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile", "implicits",
+)
+
+var d8IncR8, d8IncR8RE = pctx.MultiCommandRemoteStaticRules("d8Incr8",
+ blueprint.RuleParams{
+ Command: `mkdir -p "$outDir" "$outDir/packages" && ` +
+ `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 && ` +
+ ` ${config.IncrementalDexInputCmd} --classesJar $in --dexTarget $out --deps $d8Deps --outputDir $outDir --packageOutputDir $outDir/packages && ` +
+ ` $d8Template${config.D8Cmd} ${config.D8Flags} $d8Flags --output $outDir --no-dex-input-jar $in --packages $out.rsp --mod-packages $out.inc.rsp --package-output $outDir/packages; ` +
+ `else ` +
+ ` rm -rf "$outDir" && mkdir -p "$outDir" && ` +
+ ` $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 && ` +
+ `if [ -f "$out.input.pc_state.new" ]; then mv "$out.input.pc_state.new" "$out.input.pc_state" && ` +
+ `rm -rf $out.input.pc_state.new; fi && ` +
+ `if [ -f "$out.deps.pc_state.new" ]; then mv "$out.deps.pc_state.new" "$out.deps.pc_state" && ` +
+ `rm -rf $out.deps.pc_state.new; fi && ` +
+ `rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `,
+ CommandDeps: []string{
+ "${config.IncrementalDexInputCmd}",
+ "${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", "d8Deps", "r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"})
+
var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -195,6 +322,7 @@ var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8",
`rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar"`,
CommandDeps: []string{
"${config.D8Cmd}",
+ "${config.D8Jar}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
@@ -250,7 +378,9 @@ var d8r8, d8r8RE = pctx.MultiCommandRemoteStaticRules("d8r8",
`rm -f "$outDir"/classes*.dex "$outDir/classes.dex.jar" `,
CommandDeps: []string{
"${config.D8Cmd}",
+ "${config.D8Jar}",
"${config.R8Cmd}",
+ "${config.R8Jar}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
@@ -301,6 +431,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
Deps: blueprint.DepsGCC,
CommandDeps: []string{
"${config.R8Cmd}",
+ "${config.R8Jar}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
@@ -330,8 +461,14 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8",
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
"r8Flags", "zipFlags", "mergeZipsFlags", "resourcesOutput", "outR8ArtProfile"}, []string{"implicits"})
+var proguardDictToProto = pctx.AndroidStaticRule("proguard_dict_to_proto", blueprint.RuleParams{
+ Command: `${symbols_map} -r8 $in -location $location -write_if_changed $out`,
+ Restat: true,
+ CommandDeps: []string{"${symbols_map}"},
+}, "location")
+
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
- dexParams *compileDexParams) (flags []string, deps android.Paths) {
+ dexParams *compileDexParams) (flags []string, deps android.Paths, incD8Compatible bool) {
flags = d.dexProperties.Dxflags
// Translate all the DX flags to D8 ones until all the build files have been migrated
@@ -401,36 +538,41 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
}
flags = append(flags, "--min-api "+strconv.Itoa(minApiFlagValue))
+ incD8Compatible = false
+ // Incremental d8 does not have libraries passed to it for speed, so any
+ // desugaring with library classes is not possible.
+ // To cater for this we only enable incD8 when platform build flag is passed
+ // as it automatically disables desugaring.
if addAndroidPlatformBuildFlag {
flags = append(flags, "--android-platform-build")
+ incD8Compatible = true
}
- return flags, deps
+ return flags, deps, incD8Compatible
}
-func (d *dexer) d8Flags(ctx android.ModuleContext, dexParams *compileDexParams) (d8Flags []string, d8Deps android.Paths, artProfileOutput *android.OutputPath) {
+func (d *dexer) d8Flags(ctx android.ModuleContext, dexParams *compileDexParams, useD8Inc bool) (d8Flags []string, d8Deps android.Paths, artProfileOutput *android.OutputPath) {
flags := dexParams.flags
d8Flags = append(d8Flags, flags.bootClasspath.FormRepeatedClassPath("--lib ")...)
d8Flags = append(d8Flags, flags.dexClasspath.FormRepeatedClassPath("--lib ")...)
-
d8Deps = append(d8Deps, flags.bootClasspath...)
d8Deps = append(d8Deps, flags.dexClasspath...)
-
- if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
- d8Flags = append(d8Flags, flags...)
- d8Deps = append(d8Deps, deps...)
- artProfileOutput = profileOutput
+ if !useD8Inc {
+ if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
+ d8Flags = append(d8Flags, flags...)
+ d8Deps = append(d8Deps, deps...)
+ artProfileOutput = profileOutput
+ }
}
return d8Flags, d8Deps, artProfileOutput
}
-func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, debugMode bool) (r8Flags []string, r8Deps android.Paths, artProfileOutput *android.OutputPath) {
- flags := dexParams.flags
- opt := d.dexProperties.Optimize
+func (d *dexer) r8DepLibFlags(ctx android.ModuleContext, dexParams *compileDexParams) (r8Flags []string, r8Deps android.Paths) {
+ var depLibs classpath
// When an app contains references to APIs that are not in the SDK specified by
// its LOCAL_SDK_VERSION for example added by support library or by runtime
- // classes added by desugaring, we artifically raise the "SDK version" "linked" by
+ // classes added by desugaring, we artificially raise the "SDK version" "linked" by
// ProGuard, to
// - suppress ProGuard warnings of referencing symbols unknown to the lower SDK version.
// - prevent ProGuard stripping subclass in the support library that extends class added in the higher SDK version.
@@ -443,14 +585,11 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
proguardRaiseDeps = append(proguardRaiseDeps, dep.RepackagedHeaderJars...)
}
})
- r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, proguardRaiseDeps...)
+ depLibs = append(depLibs, proguardRaiseDeps...)
}
- r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, flags.bootClasspath...)
- r8Flags = append(r8Flags, flags.dexClasspath.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, flags.dexClasspath...)
+ depLibs = append(depLibs, dexParams.flags.bootClasspath...)
+ depLibs = append(depLibs, dexParams.flags.dexClasspath...)
transitiveStaticLibsLookupMap := map[android.Path]bool{}
for _, jar := range d.transitiveStaticLibsHeaderJarsForR8.ToList() {
@@ -465,8 +604,27 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
transitiveHeaderJars = append(transitiveHeaderJars, jar)
}
transitiveClasspath := classpath(transitiveHeaderJars)
- r8Flags = append(r8Flags, transitiveClasspath.FormJavaClassPath("-libraryjars"))
- r8Deps = append(r8Deps, transitiveClasspath...)
+ depLibs = append(depLibs, transitiveClasspath...)
+
+ depLibs = depLibs.FirstUniquePaths()
+ r8Deps = append(r8Deps, depLibs...)
+
+ var libraryDepArg string
+ if Bool(d.dexProperties.Optimize.Import_libraries_as_classpath) {
+ libraryDepArg = "--classpath "
+ } else {
+ libraryDepArg = "--lib "
+ }
+ r8Flags = append(r8Flags, depLibs.FormRepeatedClassPath(libraryDepArg)...)
+
+ return r8Flags, r8Deps
+}
+
+func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, debugMode, useD8Inc bool) (r8Flags []string, r8Deps android.Paths, artProfileOutput *android.OutputPath) {
+ r8Flags, r8Deps = d.r8DepLibFlags(ctx, dexParams)
+
+ flags := dexParams.flags
+ opt := d.dexProperties.Optimize
flagFiles := android.Paths{
android.PathForSource(ctx, "build/make/core/proguard.flags"),
@@ -525,7 +683,8 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
// Avoid unnecessary stack frame noise by only injecting source map ids for non-debug
// optimized or obfuscated targets.
- if (Bool(opt.Optimize) || Bool(opt.Obfuscate)) && !debugMode {
+ optimize := opt.Optimize.GetOrDefault(ctx, false)
+ if (optimize || Bool(opt.Obfuscate)) && !debugMode {
// TODO(b/213833843): Allow configuration of the prefix via a build variable.
var sourceFilePrefix = "go/retraceme "
var sourceFileTemplate = "\"" + sourceFilePrefix + "%MAP_ID\""
@@ -538,7 +697,7 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
r8Flags = append(r8Flags, "-dontshrink")
}
- if !Bool(opt.Optimize) {
+ if !optimize {
r8Flags = append(r8Flags, "-dontoptimize")
}
@@ -569,10 +728,12 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams,
}
}
- if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
- r8Flags = append(r8Flags, flags...)
- r8Deps = append(r8Deps, deps...)
- artProfileOutput = profileOutput
+ if !useD8Inc {
+ if flags, deps, profileOutput := d.addArtProfile(ctx, dexParams); profileOutput != nil {
+ r8Flags = append(r8Flags, flags...)
+ r8Deps = append(r8Deps, deps...)
+ artProfileOutput = profileOutput
+ }
}
if ctx.Config().UseR8StoreStoreFenceConstructorInlining() {
@@ -623,21 +784,23 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
cleanPhonyPath := android.PathForModuleOut(ctx, "dex", dexParams.jarName+"-partialcompileclean").OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
- zipFlags := "--ignore_missing_files"
+ zipFlags := "--ignore_missing_files --quiet"
if proptools.Bool(d.dexProperties.Uncompress_dex) {
zipFlags += " -L 0"
}
- commonFlags, commonDeps := d.dexCommonFlags(ctx, dexParams)
+ commonFlags, commonDeps, incD8Compatible := d.dexCommonFlags(ctx, dexParams)
// Exclude kotlinc generated files when "exclude_kotlinc_generated_files" is set to true.
mergeZipsFlags := ""
if proptools.BoolDefault(d.dexProperties.Exclude_kotlinc_generated_files, false) {
- mergeZipsFlags = "-stripFile META-INF/*.kotlin_module -stripFile **/*.kotlin_builtins"
+ mergeZipsFlags = "-stripFile META-INF/**/*.kotlin_module -stripFile **/*.kotlin_builtins"
}
useR8 := d.effectiveOptimizeEnabled(ctx)
useD8 := !useR8 || ctx.Config().PartialCompileFlags().Use_d8
+ // d8Inc is applicable only when d8 is allowed.
+ useD8Inc := useD8 && ctx.Config().PartialCompileFlags().Enable_inc_d8 && incD8Compatible
rbeR8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8")
rbeD8 := ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8")
var rule blueprint.Rule
@@ -669,7 +832,7 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
}...)
description = "r8"
debugMode := android.InList("--debug", commonFlags)
- r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode)
+ r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode, useD8Inc)
deps = append(deps, r8Deps...)
args["r8Flags"] = strings.Join(append(commonFlags, r8Flags...), " ")
if r8ArtProfileOutputPath != nil {
@@ -694,25 +857,61 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
args["implicits"] = strings.Join(deps.Strings(), ",")
}
}
+ cleanupD8R8, cleanupD8IncR8, cleanupD8Inc := false, false, false
if useD8 {
description = "d8"
- d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams)
+ d8Flags, d8Deps, d8ArtProfileOutputPath := d.d8Flags(ctx, dexParams, useD8Inc)
deps = append(deps, d8Deps...)
deps = append(deps, commonDeps...)
args["d8Flags"] = strings.Join(append(commonFlags, d8Flags...), " ")
if d8ArtProfileOutputPath != nil {
artProfileOutputPath = d8ArtProfileOutputPath
}
+ // The file containing dependencies of the current module
+ // Any change in them may warrant changes in the incremental dex compilation
+ // source set.
+ if useD8Inc {
+ d8DepsFile := android.PathForModuleOut(ctx, dexParams.jarName+".dex.deps.rsp")
+ android.WriteFileRule(ctx, d8DepsFile, strings.Join(deps.Strings(), "\n"))
+ deps = append(deps, d8DepsFile)
+ args["d8Deps"] = d8DepsFile.String()
+ }
// If we are generating both d8 and r8, only use RBE when both are enabled.
switch {
+ // r8 is the selected rule, useD8Inc is the override
+ case useR8 && rule == r8 && useD8Inc:
+ rule = d8IncR8
+ cleanupD8IncR8 = true
+ description = "d8IncR8"
+ // r8 is the selected rule, useD8 is the override
case useR8 && rule == r8:
rule = d8r8
+ cleanupD8R8 = true
description = "d8r8"
+ // rbeR8 is the selected rule, useD8Inc is the override
+ case useR8 && rule == r8RE && useD8Inc:
+ rule = d8IncR8RE
+ cleanupD8IncR8 = true
+ description = "d8IncR8"
+ // rbeR8 is the selected rule, useD8 is the override
case useR8 && rule == r8RE && rbeD8:
rule = d8r8RE
+ cleanupD8R8 = true
description = "d8r8"
+ // rbeD8 is the selected rule, useD8Inc is the override
+ case rbeD8 && useD8Inc:
+ rule = d8IncRE
+ cleanupD8Inc = true
+ description = "d8Inc"
+ // rbeD8 is the selected rule
case rbeD8:
rule = d8RE
+ // D8 is the selected rule, useD8Inc is the override
+ case useD8Inc:
+ rule = d8Inc
+ cleanupD8Inc = true
+ description = "d8Inc"
+ // D8 is the selected rule
default:
rule = d8
}
@@ -732,7 +931,8 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
Implicits: deps,
Args: args,
})
- if useR8 && useD8 {
+ // Run cleanup when d8r8 was used
+ if cleanupD8R8 {
// Generate the rule for partial compile clean.
args["builtOut"] = javalibJar.String()
ctx.Build(pctx, android.BuildParams{
@@ -744,6 +944,32 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
})
ctx.Phony("partialcompileclean", cleanPhonyPath)
}
+ // Run cleanup when d8IncR8 was used
+ if cleanupD8IncR8 {
+ // Generate the rule for partial compile clean.
+ args["builtOut"] = javalibJar.String()
+ ctx.Build(pctx, android.BuildParams{
+ Rule: d8IncR8Clean,
+ Description: "d8IncR8Clean",
+ Output: cleanPhonyPath,
+ Args: args,
+ PhonyOutput: true,
+ })
+ ctx.Phony("partialcompileclean", cleanPhonyPath)
+ }
+ // Run cleanup when d8Inc was used
+ if cleanupD8Inc {
+ // Generate the rule for partial compile clean.
+ args["builtOut"] = javalibJar.String()
+ ctx.Build(pctx, android.BuildParams{
+ Rule: d8IncClean,
+ Description: "d8IncClean",
+ 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
@@ -754,6 +980,64 @@ func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParam
return javalibJar, artProfileOutputPath
}
+type ProguardZips struct {
+ DictZip android.Path
+ DictMapping android.Path
+ UsageZip android.Path
+}
+
+func BuildProguardZips(ctx android.ModuleContext, modules []android.ModuleOrProxy) ProguardZips {
+ dictZip := android.PathForModuleOut(ctx, "proguard-dict.zip")
+ dictZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ dictZipCmd := dictZipBuilder.Command().BuiltTool("soong_zip").Flag("-d").FlagWithOutput("-o ", dictZip)
+
+ dictMapping := android.PathForModuleOut(ctx, "proguard-dict-mapping.textproto")
+ dictMappingBuilder := android.NewRuleBuilder(pctx, ctx)
+ dictMappingCmd := dictMappingBuilder.Command().BuiltTool("symbols_map").Flag("-merge").Output(dictMapping)
+
+ protosDir := android.PathForModuleOut(ctx, "proguard_mapping_protos")
+
+ usageZip := android.PathForModuleOut(ctx, "proguard-usage.zip")
+ usageZipBuilder := android.NewRuleBuilder(pctx, ctx)
+ usageZipCmd := usageZipBuilder.Command().BuiltTool("merge_zips").Output(usageZip)
+
+ for _, mod := range modules {
+ if proguardInfo, ok := android.OtherModuleProvider(ctx, mod, ProguardProvider); ok {
+ // Maintain these out/target/common paths for backwards compatibility. They may be able
+ // to be changed if tools look up file locations from the protobuf, but I'm not
+ // exactly sure how that works.
+ dictionaryFakePath := fmt.Sprintf("out/target/common/obj/%s/%s_intermediates/proguard_dictionary", proguardInfo.Class, proguardInfo.ModuleName)
+ dictZipCmd.FlagWithArg("-e ", dictionaryFakePath)
+ dictZipCmd.FlagWithInput("-f ", proguardInfo.ProguardDictionary)
+ dictZipCmd.Textf("-e out/target/common/obj/%s/%s_intermediates/classes.jar", proguardInfo.Class, proguardInfo.ModuleName)
+ dictZipCmd.FlagWithInput("-f ", proguardInfo.ClassesJar)
+
+ protoFile := protosDir.Join(ctx, filepath.Dir(dictionaryFakePath), "proguard_dictionary.textproto")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: proguardDictToProto,
+ Input: proguardInfo.ProguardDictionary,
+ Output: protoFile,
+ Args: map[string]string{
+ "location": dictionaryFakePath,
+ },
+ })
+ dictMappingCmd.Input(protoFile)
+
+ usageZipCmd.Input(proguardInfo.ProguardUsageZip)
+ }
+ }
+
+ dictZipBuilder.Build("proguard_dict_zip", "Building proguard dictionary zip")
+ dictMappingBuilder.Build("proguard_dict_mapping_proto", "Building proguard mapping proto")
+ usageZipBuilder.Build("proguard_usage_zip", "Building proguard usage zip")
+
+ return ProguardZips{
+ DictZip: dictZip,
+ DictMapping: dictMapping,
+ UsageZip: usageZip,
+ }
+}
+
type ProguardInfo struct {
ModuleName string
Class string