summaryrefslogtreecommitdiff
path: root/java/java.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java.go')
-rw-r--r--java/java.go315
1 files changed, 213 insertions, 102 deletions
diff --git a/java/java.go b/java/java.go
index 76e574eba..497b28510 100644
--- a/java/java.go
+++ b/java/java.go
@@ -143,6 +143,10 @@ type CompilerDeviceProperties struct {
// If true, export a copy of the module as a -hostdex module for host testing.
Hostdex *bool
+ // If false, prevent dexpreopting and stripping the dex file from the final jar. Defaults to
+ // true.
+ Dex_preopt *bool
+
// When targeting 1.9, override the modules to use with --system
System_modules *string
}
@@ -156,8 +160,11 @@ type Module struct {
protoProperties android.ProtoProperties
deviceProperties CompilerDeviceProperties
- // output file suitable for inserting into the classpath of another compile
- classpathFile android.Path
+ // header jar file suitable for inserting into the bootclasspath/classpath of another compile
+ headerJarFile android.Path
+
+ // full implementation jar file suitable for static dependency of another module compile
+ implementationJarFile android.Path
// output file containing classes.dex
dexJarFile android.Path
@@ -178,7 +185,8 @@ type Module struct {
}
type Dependency interface {
- ClasspathFiles() android.Paths
+ HeaderJars() android.Paths
+ ImplementationJars() android.Paths
AidlIncludeDirs() android.Paths
}
@@ -263,13 +271,13 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
}
}
- toModule := func(m string) sdkDep {
- return sdkDep{
- useModule: true,
- module: m,
- systemModules: m + "_system_modules",
- }
- }
+ //toModule := func(m string) sdkDep {
+ // return sdkDep{
+ // useModule: true,
+ // module: m,
+ // systemModules: m + "_system_modules",
+ // }
+ //}
if ctx.AConfig().UnbundledBuild() && v != "" {
return toFile(v)
@@ -280,12 +288,14 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
return sdkDep{
useDefaultLibs: true,
}
- case "current":
- return toModule("android_stubs_current")
- case "system_current":
- return toModule("android_system_stubs_current")
- case "test_current":
- return toModule("android_test_stubs_current")
+ // TODO(ccross): re-enable these once we generate stubs, until then
+ // use the stubs in prebuilts/sdk/*current
+ //case "current":
+ // return toModule("android_stubs_current")
+ //case "system_current":
+ // return toModule("android_system_stubs_current")
+ //case "test_current":
+ // return toModule("android_test_stubs_current")
default:
return toFile(v)
}
@@ -375,6 +385,7 @@ type deps struct {
classpath android.Paths
bootClasspath android.Paths
staticJars android.Paths
+ staticHeaderJars android.Paths
staticJarResources android.Paths
aidlIncludeDirs android.Paths
srcJars android.Paths
@@ -390,6 +401,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
if sdkDep.invalidVersion {
ctx.AddMissingDependencies([]string{sdkDep.module})
} else if sdkDep.useFiles {
+ // sdkDep.jar is actually equivalent to turbine header.jar.
deps.classpath = append(deps.classpath, sdkDep.jar)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, sdkDep.aidl)
}
@@ -420,12 +432,13 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
switch tag {
case bootClasspathTag:
- deps.bootClasspath = append(deps.bootClasspath, dep.ClasspathFiles()...)
+ deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
case libTag:
- deps.classpath = append(deps.classpath, dep.ClasspathFiles()...)
+ deps.classpath = append(deps.classpath, dep.HeaderJars()...)
case staticLibTag:
- deps.classpath = append(deps.classpath, dep.ClasspathFiles()...)
- deps.staticJars = append(deps.staticJars, dep.ClasspathFiles()...)
+ deps.classpath = append(deps.classpath, dep.HeaderJars()...)
+ deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
+ deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
case frameworkResTag:
if ctx.ModuleName() == "framework" {
// framework.jar has a one-off dependency on the R.java and Manifest.java files
@@ -433,7 +446,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// TODO(ccross): aapt java files should go in a src jar
}
case kotlinStdlibTag:
- deps.kotlinStdlib = dep.ClasspathFiles()
+ deps.kotlinStdlib = dep.HeaderJars()
default:
panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
@@ -444,20 +457,22 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
return deps
}
-func (j *Module) compile(ctx android.ModuleContext) {
-
- j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Export_aidl_include_dirs)
-
- deps := j.collectDeps(ctx)
+func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
var flags javaBuilderFlags
+ // javac flags.
javacFlags := j.properties.Javacflags
if ctx.AConfig().TargetOpenJDK9() {
javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
- j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
+ }
+ if len(javacFlags) > 0 {
+ // optimization.
+ ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
+ flags.javacFlags = "$javacFlags"
}
+ // javaVersion flag.
sdk := sdkStringToNumber(ctx, j.deviceProperties.Sdk_version)
if j.properties.Java_version != nil {
flags.javaVersion = *j.properties.Java_version
@@ -465,43 +480,56 @@ func (j *Module) compile(ctx android.ModuleContext) {
flags.javaVersion = "1.7"
} else if ctx.Device() && sdk <= 26 || !ctx.AConfig().TargetOpenJDK9() {
flags.javaVersion = "1.8"
+ } else if ctx.Device() && j.deviceProperties.Sdk_version != "" && sdk == 10000 {
+ // TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
+ flags.javaVersion = "1.8"
} else {
flags.javaVersion = "1.9"
}
+ // classpath
flags.bootClasspath.AddPaths(deps.bootClasspath)
flags.classpath.AddPaths(deps.classpath)
-
+ // systemModules
if deps.systemModules != nil {
flags.systemModules = append(flags.systemModules, deps.systemModules)
}
- if len(javacFlags) > 0 {
- ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
- flags.javacFlags = "$javacFlags"
- }
-
+ // aidl flags.
aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
if len(aidlFlags) > 0 {
+ // optimization.
ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
flags.aidlFlags = "$aidlFlags"
}
- srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
+ return flags
+}
+func (j *Module) compile(ctx android.ModuleContext) {
+
+ j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Export_aidl_include_dirs)
+
+ deps := j.collectDeps(ctx)
+ flags := j.collectBuilderFlags(ctx, deps)
+
+ if ctx.AConfig().TargetOpenJDK9() {
+ j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
+ }
+ srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
if hasSrcExt(srcFiles.Strings(), ".proto") {
flags = protoFlags(ctx, &j.protoProperties, flags)
}
var srcJars classpath
srcFiles, srcJars = j.genSources(ctx, srcFiles, flags)
-
srcJars = append(srcJars, deps.srcJars...)
-
srcJars = append(srcJars, j.ExtraSrcJars...)
var jars android.Paths
+ jarName := ctx.ModuleName() + ".jar"
+
if srcFiles.HasExt(".kt") {
// If there are kotlin files, compile them first but pass all the kotlin and java files
// kotlinc will use the java files to resolve types referenced by the kotlin files, but
@@ -515,7 +543,7 @@ func (j *Module) compile(ctx android.ModuleContext) {
flags.kotlincClasspath = append(flags.kotlincClasspath, deps.kotlinStdlib...)
flags.kotlincClasspath = append(flags.kotlincClasspath, deps.classpath...)
- kotlinJar := android.PathForModuleOut(ctx, "classes-kt.jar")
+ kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
TransformKotlinToClasses(ctx, kotlinJar, srcFiles, srcJars, flags)
if ctx.Failed() {
return
@@ -528,7 +556,27 @@ func (j *Module) compile(ctx android.ModuleContext) {
jars = append(jars, deps.kotlinStdlib...)
}
- if javaSrcFiles := srcFiles.FilterByExt(".java"); len(javaSrcFiles) > 0 {
+ javaSrcFiles := srcFiles.FilterByExt(".java")
+ var uniqueSrcFiles android.Paths
+ set := make(map[string]bool)
+ for _, v := range javaSrcFiles {
+ if _, found := set[v.String()]; !found {
+ set[v.String()] = true
+ uniqueSrcFiles = append(uniqueSrcFiles, v)
+ }
+ }
+
+ if ctx.Device() && !ctx.AConfig().IsEnvFalse("TURBINE_ENABLED") {
+ // If sdk jar is java module, then directly return classesJar as header.jar
+ if j.Name() != "android_stubs_current" && j.Name() != "android_system_stubs_current" &&
+ j.Name() != "android_test_stubs_current" {
+ j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName)
+ if ctx.Failed() {
+ return
+ }
+ }
+ }
+ if len(uniqueSrcFiles) > 0 {
var extraJarDeps android.Paths
if ctx.AConfig().IsEnvTrue("RUN_ERROR_PRONE") {
// If error-prone is enabled, add an additional rule to compile the java files into
@@ -536,13 +584,13 @@ func (j *Module) compile(ctx android.ModuleContext) {
// a rebuild when error-prone is turned off).
// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
// enable error-prone without affecting the output class files.
- errorprone := android.PathForModuleOut(ctx, "classes-errorprone.list")
+ errorprone := android.PathForModuleOut(ctx, "errorprone", jarName)
RunErrorProne(ctx, errorprone, javaSrcFiles, srcJars, flags)
extraJarDeps = append(extraJarDeps, errorprone)
}
// Compile java sources into .class files
- classes := android.PathForModuleOut(ctx, "classes-compiled.jar")
+ classes := android.PathForModuleOut(ctx, "javac", jarName)
TransformJavaToClasses(ctx, classes, javaSrcFiles, srcJars, flags, extraJarDeps)
if ctx.Failed() {
return
@@ -570,7 +618,7 @@ func (j *Module) compile(ctx android.ModuleContext) {
}
if len(resArgs) > 0 {
- resourceJar := android.PathForModuleOut(ctx, "res.jar")
+ resourceJar := android.PathForModuleOut(ctx, "res", jarName)
TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
if ctx.Failed() {
return
@@ -585,98 +633,151 @@ func (j *Module) compile(ctx android.ModuleContext) {
manifest := android.OptionalPathForModuleSrc(ctx, j.properties.Manifest)
// Combine the classes built from sources, any manifests, and any static libraries into
- // classes.jar. If there is only one input jar this step will be skipped.
+ // classes.jar. If there is only one input jar this step will be skipped.
var outputFile android.Path
if len(jars) == 1 && !manifest.Valid() {
// Optimization: skip the combine step if there is nothing to do
outputFile = jars[0]
} else {
- combinedJar := android.PathForModuleOut(ctx, "classes.jar")
- TransformJarsToJar(ctx, combinedJar, jars, manifest, false)
+ combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
+ TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest, false, nil)
outputFile = combinedJar
}
if j.properties.Jarjar_rules != nil {
jarjar_rules := android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
// Transform classes.jar into classes-jarjar.jar
- jarjarFile := android.PathForModuleOut(ctx, "classes-jarjar.jar")
+ jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName)
TransformJarJar(ctx, jarjarFile, outputFile, jarjar_rules)
outputFile = jarjarFile
if ctx.Failed() {
return
}
}
-
- j.classpathFile = outputFile
+ j.implementationJarFile = outputFile
+ if j.headerJarFile == nil {
+ j.headerJarFile = j.implementationJarFile
+ }
if ctx.Device() && j.installable() {
- dxFlags := j.deviceProperties.Dxflags
- if false /* emma enabled */ {
- // If you instrument class files that have local variable debug information in
- // them emma does not correctly maintain the local variable table.
- // This will cause an error when you try to convert the class files for Android.
- // The workaround here is to build different dex file here based on emma switch
- // then later copy into classes.dex. When emma is on, dx is run with --no-locals
- // option to remove local variable information
- dxFlags = append(dxFlags, "--no-locals")
+ outputFile = j.compileDex(ctx, flags, outputFile, jarName)
+ if ctx.Failed() {
+ return
}
+ }
+ ctx.CheckbuildFile(outputFile)
+ j.outputFile = outputFile
+}
- if ctx.AConfig().Getenv("NO_OPTIMIZE_DX") != "" {
- dxFlags = append(dxFlags, "--no-optimize")
- }
+func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles android.Paths, srcJars classpath,
+ deps deps, flags javaBuilderFlags, jarName string) android.Path {
- if ctx.AConfig().Getenv("GENERATE_DEX_DEBUG") != "" {
- dxFlags = append(dxFlags,
- "--debug",
- "--verbose",
- "--dump-to="+android.PathForModuleOut(ctx, "classes.lst").String(),
- "--dump-width=1000")
+ var jars android.Paths
+ if len(srcFiles) > 0 {
+ // Compile java sources into turbine.jar.
+ turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
+ TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
+ if ctx.Failed() {
+ return nil
}
+ jars = append(jars, turbineJar)
+ }
- var minSdkVersion string
- switch j.deviceProperties.Sdk_version {
- case "", "current", "test_current", "system_current":
- minSdkVersion = strconv.Itoa(ctx.AConfig().DefaultAppTargetSdkInt())
- default:
- minSdkVersion = j.deviceProperties.Sdk_version
+ // Combine any static header libraries into classes-header.jar. If there is only
+ // one input jar this step will be skipped.
+ var headerJar android.Path
+ jars = append(jars, deps.staticHeaderJars...)
+
+ if len(jars) == 0 {
+ panic("The turbine.jar is empty without any sources and static libs.")
+ } else {
+ // we cannot skip the combine step for now if there is only one jar
+ // since we have to strip META-INF/TRANSITIVE dir from turbine.jar
+ combinedJar := android.PathForModuleOut(ctx, "turbine-combined", jarName)
+ TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{}, false, []string{"META-INF"})
+ headerJar = combinedJar
+ }
+
+ if j.properties.Jarjar_rules != nil {
+ jarjar_rules := android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
+ // Transform classes.jar into classes-jarjar.jar
+ jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
+ TransformJarJar(ctx, jarjarFile, headerJar, jarjar_rules)
+ headerJar = jarjarFile
+ if ctx.Failed() {
+ return nil
}
+ }
+
+ return headerJar
+}
- dxFlags = append(dxFlags, "--min-sdk-version="+minSdkVersion)
+func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
+ classesJar android.Path, jarName string) android.Path {
+
+ dxFlags := j.deviceProperties.Dxflags
+ if false /* emma enabled */ {
+ // If you instrument class files that have local variable debug information in
+ // them emma does not correctly maintain the local variable table.
+ // This will cause an error when you try to convert the class files for Android.
+ // The workaround here is to build different dex file here based on emma switch
+ // then later copy into classes.dex. When emma is on, dx is run with --no-locals
+ // option to remove local variable information
+ dxFlags = append(dxFlags, "--no-locals")
+ }
- flags.dxFlags = strings.Join(dxFlags, " ")
+ if ctx.AConfig().Getenv("NO_OPTIMIZE_DX") != "" {
+ dxFlags = append(dxFlags, "--no-optimize")
+ }
- desugarFlags := []string{
- "--min_sdk_version " + minSdkVersion,
- "--desugar_try_with_resources_if_needed=false",
- "--allow_empty_bootclasspath",
- }
+ if ctx.AConfig().Getenv("GENERATE_DEX_DEBUG") != "" {
+ dxFlags = append(dxFlags,
+ "--debug",
+ "--verbose",
+ "--dump-to="+android.PathForModuleOut(ctx, "classes.lst").String(),
+ "--dump-width=1000")
+ }
- if inList("--core-library", dxFlags) {
- desugarFlags = append(desugarFlags, "--core_library")
- }
+ var minSdkVersion string
+ switch j.deviceProperties.Sdk_version {
+ case "", "current", "test_current", "system_current":
+ minSdkVersion = strconv.Itoa(ctx.AConfig().DefaultAppTargetSdkInt())
+ default:
+ minSdkVersion = j.deviceProperties.Sdk_version
+ }
- flags.desugarFlags = strings.Join(desugarFlags, " ")
+ dxFlags = append(dxFlags, "--min-sdk-version="+minSdkVersion)
- desugarJar := android.PathForModuleOut(ctx, "classes-desugar.jar")
- TransformDesugar(ctx, desugarJar, outputFile, flags)
- outputFile = desugarJar
- if ctx.Failed() {
- return
- }
+ flags.dxFlags = strings.Join(dxFlags, " ")
- // Compile classes.jar into classes.dex and then javalib.jar
- javalibJar := android.PathForModuleOut(ctx, "javalib.jar")
- TransformClassesJarToDexJar(ctx, javalibJar, desugarJar, flags)
- outputFile = javalibJar
- if ctx.Failed() {
- return
- }
+ desugarFlags := []string{
+ "--min_sdk_version " + minSdkVersion,
+ "--desugar_try_with_resources_if_needed=false",
+ "--allow_empty_bootclasspath",
+ }
- j.dexJarFile = outputFile
+ if inList("--core-library", dxFlags) {
+ desugarFlags = append(desugarFlags, "--core_library")
}
- ctx.CheckbuildFile(outputFile)
- j.outputFile = outputFile
+
+ flags.desugarFlags = strings.Join(desugarFlags, " ")
+
+ desugarJar := android.PathForModuleOut(ctx, "desugar", jarName)
+ TransformDesugar(ctx, desugarJar, classesJar, flags)
+ if ctx.Failed() {
+ return nil
+ }
+
+ // Compile classes.jar into classes.dex and then javalib.jar
+ javalibJar := android.PathForModuleOut(ctx, "dex", jarName)
+ TransformClassesJarToDexJar(ctx, javalibJar, desugarJar, flags)
+ if ctx.Failed() {
+ return nil
+ }
+
+ j.dexJarFile = javalibJar
+ return javalibJar
}
func (j *Module) installable() bool {
@@ -685,8 +786,12 @@ func (j *Module) installable() bool {
var _ Dependency = (*Library)(nil)
-func (j *Module) ClasspathFiles() android.Paths {
- return android.Paths{j.classpathFile}
+func (j *Module) HeaderJars() android.Paths {
+ return android.Paths{j.headerJarFile}
+}
+
+func (j *Module) ImplementationJars() android.Paths {
+ return android.Paths{j.implementationJarFile}
}
func (j *Module) AidlIncludeDirs() android.Paths {
@@ -813,6 +918,8 @@ func BinaryHostFactory() android.Module {
type ImportProperties struct {
Jars []string
+
+ Sdk_version string
}
type Import struct {
@@ -844,13 +951,17 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars)
outputFile := android.PathForModuleOut(ctx, "classes.jar")
- TransformJarsToJar(ctx, outputFile, j.classpathFiles, android.OptionalPath{}, false)
+ TransformJarsToJar(ctx, outputFile, "for prebuilts", j.classpathFiles, android.OptionalPath{}, false, nil)
j.combinedClasspathFile = outputFile
}
var _ Dependency = (*Import)(nil)
-func (j *Import) ClasspathFiles() android.Paths {
+func (j *Import) HeaderJars() android.Paths {
+ return j.classpathFiles
+}
+
+func (j *Import) ImplementationJars() android.Paths {
return j.classpathFiles
}