From f0056cb2ed3fe9d34d89df421922569b095f2e47 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 22 Dec 2017 15:56:08 -0800 Subject: [PATCH] Refactor dexing Move dexing support into java/dex.go, including the rules and logic from builder.go and the function from java.go. Test: no change to build.ninja Change-Id: I098d2a9774e28079ba44791679a0db6f876fe3e6 --- Android.bp | 1 + java/builder.go | 99 ----------------------- java/config/config.go | 10 +-- java/dex.go | 181 ++++++++++++++++++++++++++++++++++++++++++ java/java.go | 95 +--------------------- 5 files changed, 186 insertions(+), 200 deletions(-) create mode 100644 java/dex.go diff --git a/Android.bp b/Android.bp index ba7178955..91e73aab4 100644 --- a/Android.bp +++ b/Android.bp @@ -219,6 +219,7 @@ bootstrap_go_package { "java/app_builder.go", "java/app.go", "java/builder.go", + "java/dex.go", "java/gen.go", "java/genrule.go", "java/jacoco.go", diff --git a/java/builder.go b/java/builder.go index 56c7b3300..dae655d75 100644 --- a/java/builder.go +++ b/java/builder.go @@ -135,46 +135,6 @@ var ( }, "jarArgs") - desugar = pctx.AndroidStaticRule("desugar", - blueprint.RuleParams{ - Command: `rm -rf $dumpDir && mkdir -p $dumpDir && ` + - `${config.JavaCmd} ` + - `-Djdk.internal.lambda.dumpProxyClasses=$$(cd $dumpDir && pwd) ` + - `$javaFlags ` + - `-jar ${config.DesugarJar} $classpathFlags $desugarFlags ` + - `-i $in -o $out`, - CommandDeps: []string{"${config.DesugarJar}", "${config.JavaCmd}"}, - }, - "javaFlags", "classpathFlags", "desugarFlags", "dumpDir") - - dx = pctx.AndroidStaticRule("dx", - blueprint.RuleParams{ - Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + - `${config.DxCmd} --dex --output=$outDir $dxFlags $in && ` + - `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` + - `${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`, - CommandDeps: []string{ - "${config.DxCmd}", - "${config.SoongZipCmd}", - "${config.MergeZipsCmd}", - }, - }, - "outDir", "dxFlags") - - d8 = pctx.AndroidStaticRule("d8", - blueprint.RuleParams{ - Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + - `${config.D8Cmd} --output $outDir $dxFlags $in && ` + - `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` + - `${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`, - CommandDeps: []string{ - "${config.DxCmd}", - "${config.SoongZipCmd}", - "${config.MergeZipsCmd}", - }, - }, - "outDir", "dxFlags") - jarjar = pctx.AndroidStaticRule("jarjar", blueprint.RuleParams{ Command: "${config.JavaCmd} -jar ${config.JarjarCmd} process $rulesFile $in $out", @@ -193,7 +153,6 @@ type javaBuilderFlags struct { bootClasspath classpath classpath classpath systemModules classpath - desugarFlags string aidlFlags string javaVersion string @@ -403,64 +362,6 @@ func TransformJarsToJar(ctx android.ModuleContext, outputFile android.WritablePa }) } -func TransformDesugar(ctx android.ModuleContext, outputFile android.WritablePath, - classesJar android.Path, flags javaBuilderFlags) { - - dumpDir := android.PathForModuleOut(ctx, "desugar", "classes") - - javaFlags := "" - if ctx.Config().UseOpenJDK9() { - javaFlags = "--add-opens java.base/java.lang.invoke=ALL-UNNAMED" - } - - var desugarFlags []string - desugarFlags = append(desugarFlags, flags.bootClasspath.FormDesugarClasspath("--bootclasspath_entry")...) - desugarFlags = append(desugarFlags, flags.classpath.FormDesugarClasspath("--classpath_entry")...) - - var deps android.Paths - deps = append(deps, flags.bootClasspath...) - deps = append(deps, flags.classpath...) - - ctx.Build(pctx, android.BuildParams{ - Rule: desugar, - Description: "desugar", - Output: outputFile, - Input: classesJar, - Implicits: deps, - Args: map[string]string{ - "dumpDir": dumpDir.String(), - "javaFlags": javaFlags, - "classpathFlags": strings.Join(desugarFlags, " "), - "desugarFlags": flags.desugarFlags, - }, - }) -} - -// Converts a classes.jar file to classes*.dex, then combines the dex files with any resources -// in the classes.jar file into a dex jar. -func TransformClassesJarToDexJar(ctx android.ModuleContext, outputFile android.WritablePath, - classesJar android.Path, flags javaBuilderFlags) { - - outDir := android.PathForModuleOut(ctx, "dex") - - rule := dx - desc := "dx" - if ctx.Config().UseD8Desugar() { - rule = d8 - desc = "d8" - } - ctx.Build(pctx, android.BuildParams{ - Rule: rule, - Description: desc, - Output: outputFile, - Input: classesJar, - Args: map[string]string{ - "dxFlags": flags.dxFlags, - "outDir": outDir.String(), - }, - }) -} - func TransformJarJar(ctx android.ModuleContext, outputFile android.WritablePath, classesJar android.Path, rulesFile android.Path) { ctx.Build(pctx, android.BuildParams{ diff --git a/java/config/config.go b/java/config/config.go index c43f9a38a..930e65e42 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -106,13 +106,9 @@ func init() { return path.String(), nil } }) - pctx.VariableFunc("D8Cmd", func(config android.Config) (string, error) { - path, err := pctx.HostBinToolPath(config, "d8") - if err != nil { - return "", err - } - return path.String(), nil - }) + + pctx.HostBinToolVariable("D8Cmd", "d8") + pctx.VariableFunc("TurbineJar", func(config android.Config) (string, error) { turbine := "turbine.jar" if config.UnbundledBuild() { diff --git a/java/dex.go b/java/dex.go new file mode 100644 index 000000000..fa5c2eea2 --- /dev/null +++ b/java/dex.go @@ -0,0 +1,181 @@ +// Copyright 2017 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 ( + "strings" + + "github.com/google/blueprint" + + "android/soong/android" +) + +var desugar = pctx.AndroidStaticRule("desugar", + blueprint.RuleParams{ + Command: `rm -rf $dumpDir && mkdir -p $dumpDir && ` + + `${config.JavaCmd} ` + + `-Djdk.internal.lambda.dumpProxyClasses=$$(cd $dumpDir && pwd) ` + + `$javaFlags ` + + `-jar ${config.DesugarJar} $classpathFlags $desugarFlags ` + + `-i $in -o $out`, + CommandDeps: []string{"${config.DesugarJar}", "${config.JavaCmd}"}, + }, + "javaFlags", "classpathFlags", "desugarFlags", "dumpDir") + +func (j *Module) desugar(ctx android.ModuleContext, flags javaBuilderFlags, + classesJar android.Path, jarName string) android.Path { + + desugarFlags := []string{ + "--min_sdk_version " + j.minSdkVersionNumber(ctx), + "--desugar_try_with_resources_if_needed=false", + "--allow_empty_bootclasspath", + } + + if inList("--core-library", j.deviceProperties.Dxflags) { + desugarFlags = append(desugarFlags, "--core_library") + } + + desugarJar := android.PathForModuleOut(ctx, "desugar", jarName) + dumpDir := android.PathForModuleOut(ctx, "desugar", "classes") + + javaFlags := "" + if ctx.Config().UseOpenJDK9() { + javaFlags = "--add-opens java.base/java.lang.invoke=ALL-UNNAMED" + } + + var classpathFlags []string + classpathFlags = append(classpathFlags, flags.bootClasspath.FormDesugarClasspath("--bootclasspath_entry")...) + classpathFlags = append(classpathFlags, flags.classpath.FormDesugarClasspath("--classpath_entry")...) + + var deps android.Paths + deps = append(deps, flags.bootClasspath...) + deps = append(deps, flags.classpath...) + + ctx.Build(pctx, android.BuildParams{ + Rule: desugar, + Description: "desugar", + Output: desugarJar, + Input: classesJar, + Implicits: deps, + Args: map[string]string{ + "dumpDir": dumpDir.String(), + "javaFlags": javaFlags, + "classpathFlags": strings.Join(classpathFlags, " "), + "desugarFlags": strings.Join(desugarFlags, " "), + }, + }) + + return desugarJar +} + +var dx = pctx.AndroidStaticRule("dx", + blueprint.RuleParams{ + Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + + `${config.DxCmd} --dex --output=$outDir $dxFlags $in && ` + + `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` + + `${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`, + CommandDeps: []string{ + "${config.DxCmd}", + "${config.SoongZipCmd}", + "${config.MergeZipsCmd}", + }, + }, + "outDir", "dxFlags") + +var d8 = pctx.AndroidStaticRule("d8", + blueprint.RuleParams{ + Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + + `${config.D8Cmd} --output $outDir $dxFlags $in && ` + + `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` + + `${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`, + CommandDeps: []string{ + "${config.D8Cmd}", + "${config.SoongZipCmd}", + "${config.MergeZipsCmd}", + }, + }, + "outDir", "dxFlags") + +func (j *Module) dxFlags(ctx android.ModuleContext, fullD8 bool) []string { + flags := j.deviceProperties.Dxflags + if fullD8 { + // Translate all the DX flags to D8 ones until all the build files have been migrated + // to D8 flags. See: b/69377755 + flags = android.RemoveListFromList(flags, + []string{"--core-library", "--dex", "--multi-dex"}) + } + + if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" { + if fullD8 { + flags = append(flags, "--debug") + } else { + flags = append(flags, "--no-optimize") + } + } + + if ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" { + flags = append(flags, + "--debug", + "--verbose") + if !fullD8 { + flags = append(flags, + "--dump-to="+android.PathForModuleOut(ctx, "classes.lst").String(), + "--dump-width=1000") + } + } + + if fullD8 { + flags = append(flags, "--min-api "+j.minSdkVersionNumber(ctx)) + } else { + flags = append(flags, "--min-sdk-version="+j.minSdkVersionNumber(ctx)) + } + return flags +} + +func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, + classesJar android.Path, jarName string) android.Path { + + fullD8 := ctx.Config().UseD8Desugar() + + if !fullD8 { + classesJar = j.desugar(ctx, flags, classesJar, jarName) + } + + dxFlags := j.dxFlags(ctx, fullD8) + + // Compile classes.jar into classes.dex and then javalib.jar + javalibJar := android.PathForModuleOut(ctx, "dex", jarName) + outDir := android.PathForModuleOut(ctx, "dex") + + rule := dx + desc := "dx" + if fullD8 { + rule = d8 + desc = "d8" + } + ctx.Build(pctx, android.BuildParams{ + Rule: rule, + Description: desc, + Output: javalibJar, + Input: classesJar, + Args: map[string]string{ + "dxFlags": strings.Join(dxFlags, " "), + "outDir": outDir.String(), + }, + }) + + j.dexJarFile = javalibJar + return javalibJar +} diff --git a/java/java.go b/java/java.go index 7daa8f2ef..f06d81d7a 100644 --- a/java/java.go +++ b/java/java.go @@ -700,7 +700,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path // Store the list of .java files that was passed to javac j.compiledJavaSrcs = uniqueSrcFiles j.compiledSrcJars = srcJars - fullD8 := ctx.Config().UseD8Desugar() enable_sharding := false if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") { @@ -840,12 +839,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path } if ctx.Device() && j.installable() { - if fullD8 { - outputFile = j.compileDexFullD8(ctx, flags, outputFile, jarName) - } else { - outputFile = j.desugar(ctx, flags, outputFile, jarName) - outputFile = j.compileDex(ctx, flags, outputFile, jarName) - } + outputFile = j.compileDex(ctx, flags, outputFile, jarName) if ctx.Failed() { return } @@ -893,27 +887,6 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars return headerJar } -func (j *Module) desugar(ctx android.ModuleContext, flags javaBuilderFlags, - classesJar android.Path, jarName string) android.Path { - - desugarFlags := []string{ - "--min_sdk_version " + j.minSdkVersionNumber(ctx), - "--desugar_try_with_resources_if_needed=false", - "--allow_empty_bootclasspath", - } - - if inList("--core-library", j.deviceProperties.Dxflags) { - desugarFlags = append(desugarFlags, "--core_library") - } - - flags.desugarFlags = strings.Join(desugarFlags, " ") - - desugarJar := android.PathForModuleOut(ctx, "desugar", jarName) - TransformDesugar(ctx, desugarJar, classesJar, flags) - - return desugarJar -} - func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, classesJar android.Path, jarName string) android.Path { @@ -929,72 +902,6 @@ func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, return instrumentedJar } -func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, - classesJar android.Path, jarName string) android.Path { - - dxFlags := j.deviceProperties.Dxflags - - if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" { - dxFlags = append(dxFlags, "--no-optimize") - } - - if ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" { - dxFlags = append(dxFlags, - "--debug", - "--verbose", - "--dump-to="+android.PathForModuleOut(ctx, "classes.lst").String(), - "--dump-width=1000") - } - - dxFlags = append(dxFlags, "--min-sdk-version="+j.minSdkVersionNumber(ctx)) - - flags.dxFlags = strings.Join(dxFlags, " ") - - // Compile classes.jar into classes.dex and then javalib.jar - javalibJar := android.PathForModuleOut(ctx, "dex", jarName) - TransformClassesJarToDexJar(ctx, javalibJar, classesJar, flags) - - j.dexJarFile = javalibJar - return javalibJar -} - -func (j *Module) compileDexFullD8(ctx android.ModuleContext, flags javaBuilderFlags, - classesJar android.Path, jarName string) android.Path { - - // Translate all the DX flags to D8 ones until all the build files have been migrated - // to D8 flags. See: b/69377755 - var dxFlags []string - for _, x := range j.deviceProperties.Dxflags { - switch x { - case "--core-library", "--dex", "--multi-dex": - continue - default: - dxFlags = append(dxFlags, x) - } - } - - if ctx.AConfig().Getenv("NO_OPTIMIZE_DX") != "" { - dxFlags = append(dxFlags, "--debug") - } - - if ctx.AConfig().Getenv("GENERATE_DEX_DEBUG") != "" { - dxFlags = append(dxFlags, - "--debug", - "--verbose") - } - - dxFlags = append(dxFlags, "--min-api "+j.minSdkVersionNumber(ctx)) - - flags.dxFlags = strings.Join(dxFlags, " ") - - // Compile classes.jar into classes.dex and then javalib.jar - javalibJar := android.PathForModuleOut(ctx, "dex", jarName) - TransformClassesJarToDexJar(ctx, javalibJar, classesJar, flags) - - j.dexJarFile = javalibJar - return javalibJar -} - // Returns a sdk version as a string that is guaranteed to be a parseable as a number. For // modules targeting an unreleased SDK (meaning it does not yet have a number) it returns "10000". func (j *Module) minSdkVersionNumber(ctx android.ModuleContext) string {