diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 176 |
1 files changed, 120 insertions, 56 deletions
diff --git a/java/java.go b/java/java.go index b2bd2b0a4..4355200fb 100644 --- a/java/java.go +++ b/java/java.go @@ -41,7 +41,6 @@ func init() { android.RegisterModuleType("java_binary_host", BinaryHostFactory) android.RegisterModuleType("java_import", ImportFactory) android.RegisterModuleType("java_import_host", ImportFactoryHost) - android.RegisterModuleType("android_app", AndroidAppFactory) android.RegisterSingletonType("logtags", LogtagsSingleton) } @@ -51,9 +50,6 @@ func init() { // Renderscript // Post-jar passes: // Proguard -// Jacoco -// Jarjar -// Dex // Rmtypedefs // DroidDoc // Findbugs @@ -127,6 +123,26 @@ type CompilerProperties struct { // List of javac flags that should only be used when passing -source 1.9 Javacflags []string } + + Jacoco struct { + // List of classes to include for instrumentation with jacoco to collect coverage + // information at runtime when building with coverage enabled. If unset defaults to all + // classes. + // Supports '*' as the last character of an entry in the list as a wildcard match. + // If preceded by '.' it matches all classes in the package and subpackages, otherwise + // it matches classes in the package that have the class name as a prefix. + Include_filter []string + + // List of classes to exclude from instrumentation with jacoco to collect coverage + // information at runtime when building with coverage enabled. Overrides classes selected + // by the include_filter property. + // Supports '*' as the last character of an entry in the list as a wildcard match. + // If preceded by '.' it matches all classes in the package and subpackages, otherwise + // it matches classes in the package that have the class name as a prefix. + Exclude_filter []string + } + + Instrument bool `blueprint:"mutated"` } type CompilerDeviceProperties struct { @@ -177,6 +193,9 @@ type Module struct { // output file containing classes.dex dexJarFile android.Path + // output file containing uninstrumented classes that will be instrumented by jacoco + jacocoReportClassesFile android.Path + // output file suitable for installing or running outputFile android.Path @@ -184,12 +203,12 @@ type Module struct { logtagsSrcs android.Paths - // jars containing source files that should be included in the javac command line, - // for example R.java generated by aapt for android apps - ExtraSrcJars android.Paths - // installed file for binary dependency installFile android.Path + + // list of .java files and srcjars that was passed to javac + compiledJavaSrcs android.Paths + compiledSrcJars android.Paths } type Dependency interface { @@ -232,7 +251,7 @@ func sdkStringToNumber(ctx android.BaseContext, v string) int { case "", "current", "system_current", "test_current": return 10000 default: - if i, err := strconv.Atoi(v); err != nil { + if i, err := strconv.Atoi(android.GetNumericSdkVersion(v)); err != nil { ctx.PropertyErrorf("sdk_version", "invalid sdk version") return -1 } else { @@ -255,7 +274,13 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep { jarPath := android.ExistentPathForSource(ctx, "sdkdir", jar) aidlPath := android.ExistentPathForSource(ctx, "sdkdir", aidl) - if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.AConfig().AllowMissingDependencies() { + if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() { + if strings.Contains(v, "system_") { + return sdkDep{ + invalidVersion: true, + module: "vsdk_v" + strings.Replace(v, "system_", "", 1), + } + } return sdkDep{ invalidVersion: true, module: "sdk_v" + v, @@ -287,7 +312,7 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep { // } //} - if ctx.AConfig().UnbundledBuild() && v != "" { + if ctx.Config().UnbundledBuild() && v != "" { return toFile(v) } @@ -315,14 +340,14 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version)) if sdkDep.useDefaultLibs { ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...) - if ctx.AConfig().TargetOpenJDK9() { + if ctx.Config().TargetOpenJDK9() { ctx.AddDependency(ctx.Module(), systemModulesTag, config.DefaultSystemModules) } if !proptools.Bool(j.properties.No_framework_libs) { ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...) } } else if sdkDep.useModule { - if ctx.AConfig().TargetOpenJDK9() { + if ctx.Config().TargetOpenJDK9() { ctx.AddDependency(ctx.Module(), systemModulesTag, sdkDep.systemModules) } ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module) @@ -330,9 +355,12 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } else if j.deviceProperties.System_modules == nil { ctx.PropertyErrorf("no_standard_libs", "system_modules is required to be set when no_standard_libs is true, did you mean no_framework_libs?") - } else if *j.deviceProperties.System_modules != "none" && ctx.AConfig().TargetOpenJDK9() { + } else if *j.deviceProperties.System_modules != "none" && ctx.Config().TargetOpenJDK9() { ctx.AddDependency(ctx.Module(), systemModulesTag, *j.deviceProperties.System_modules) } + if ctx.ModuleName() == "framework" { + ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res") + } } ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...) @@ -467,7 +495,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { if ctx.ModuleName() == "framework" { // framework.jar has a one-off dependency on the R.java and Manifest.java files // generated by framework-res.apk - // TODO(ccross): aapt java files should go in a src jar + deps.srcJars = append(deps.srcJars, dep.(*AndroidApp).aaptSrcJar) } case kotlinStdlibTag: deps.kotlinStdlib = dep.HeaderJars() @@ -487,10 +515,10 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB // javac flags. javacFlags := j.properties.Javacflags - if ctx.AConfig().TargetOpenJDK9() { + if ctx.Config().TargetOpenJDK9() { javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...) } - if ctx.AConfig().MinimizeJavaDebugInfo() { + if ctx.Config().MinimizeJavaDebugInfo() { // Override the -g flag passed globally to remove local variable debug info to reduce // disk and memory usage. javacFlags = append(javacFlags, "-g:source,lines") @@ -507,7 +535,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB flags.javaVersion = *j.properties.Java_version } else if ctx.Device() && sdk <= 23 { flags.javaVersion = "1.7" - } else if ctx.Device() && sdk <= 26 || !ctx.AConfig().TargetOpenJDK9() { + } else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() { flags.javaVersion = "1.8" } else if ctx.Device() && String(j.deviceProperties.Sdk_version) != "" && sdk == 10000 { // TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current" @@ -535,14 +563,14 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB return flags } -func (j *Module) compile(ctx android.ModuleContext) { +func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path) { j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) deps := j.collectDeps(ctx) flags := j.collectBuilderFlags(ctx, deps) - if ctx.AConfig().TargetOpenJDK9() { + if ctx.Config().TargetOpenJDK9() { j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...) } srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs) @@ -554,7 +582,7 @@ func (j *Module) compile(ctx android.ModuleContext) { srcJars := srcFiles.FilterByExt(".srcjar") srcJars = append(srcJars, deps.srcJars...) - srcJars = append(srcJars, j.ExtraSrcJars...) + srcJars = append(srcJars, extraSrcJars...) var jars android.Paths @@ -596,8 +624,12 @@ func (j *Module) compile(ctx android.ModuleContext) { } } + // Store the list of .java files that was passed to javac + j.compiledJavaSrcs = uniqueSrcFiles + j.compiledSrcJars = srcJars + enable_sharding := false - if ctx.Device() && !ctx.AConfig().IsEnvFalse("TURBINE_ENABLED") { + if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") { if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 { enable_sharding = true if len(j.properties.Annotation_processors) != 0 || @@ -618,7 +650,7 @@ func (j *Module) compile(ctx android.ModuleContext) { } if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 { var extraJarDeps android.Paths - if ctx.AConfig().IsEnvTrue("RUN_ERROR_PRONE") { + if ctx.Config().IsEnvTrue("RUN_ERROR_PRONE") { // If error-prone is enabled, add an additional rule to compile the java files into // a separate set of classes (so that they don't overwrite the normal ones and require // a rebuild when error-prone is turned off). @@ -718,6 +750,20 @@ func (j *Module) compile(ctx android.ModuleContext) { } if ctx.Device() && j.installable() { + outputFile = j.desugar(ctx, flags, outputFile, jarName) + } + + if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { + if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { + j.properties.Instrument = true + } + } + + if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") && j.properties.Instrument { + outputFile = j.instrument(ctx, flags, outputFile, jarName) + } + + if ctx.Device() && j.installable() { outputFile = j.compileDex(ctx, flags, outputFile, jarName) if ctx.Failed() { return @@ -766,6 +812,42 @@ 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 { + + specs := j.jacocoStripSpecs(ctx) + + jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco", "jacoco-report-classes.jar") + instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName) + + jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs) + + j.jacocoReportClassesFile = jacocoReportClassesFile + + return instrumentedJar +} + func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, classesJar android.Path, jarName string) android.Path { @@ -780,11 +862,11 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, dxFlags = append(dxFlags, "--no-locals") } - if ctx.AConfig().Getenv("NO_OPTIMIZE_DX") != "" { + if ctx.Config().Getenv("NO_OPTIMIZE_DX") != "" { dxFlags = append(dxFlags, "--no-optimize") } - if ctx.AConfig().Getenv("GENERATE_DEX_DEBUG") != "" { + if ctx.Config().Getenv("GENERATE_DEX_DEBUG") != "" { dxFlags = append(dxFlags, "--debug", "--verbose", @@ -792,47 +874,29 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, "--dump-width=1000") } - var minSdkVersion string - switch String(j.deviceProperties.Sdk_version) { - case "", "current", "test_current", "system_current": - minSdkVersion = strconv.Itoa(ctx.AConfig().DefaultAppTargetSdkInt()) - default: - minSdkVersion = String(j.deviceProperties.Sdk_version) - } - - dxFlags = append(dxFlags, "--min-sdk-version="+minSdkVersion) + dxFlags = append(dxFlags, "--min-sdk-version="+j.minSdkVersionNumber(ctx)) flags.dxFlags = strings.Join(dxFlags, " ") - desugarFlags := []string{ - "--min_sdk_version " + minSdkVersion, - "--desugar_try_with_resources_if_needed=false", - "--allow_empty_bootclasspath", - } - - if inList("--core-library", dxFlags) { - desugarFlags = append(desugarFlags, "--core_library") - } - - 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 - } + 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 { + switch String(j.deviceProperties.Sdk_version) { + case "", "current", "test_current", "system_current": + return strconv.Itoa(ctx.Config().DefaultAppTargetSdkInt()) + default: + return android.GetNumericSdkVersion(String(j.deviceProperties.Sdk_version)) + } +} + func (j *Module) installable() bool { return j.properties.Installable == nil || *j.properties.Installable } |