summaryrefslogtreecommitdiff
path: root/java/java.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java.go')
-rw-r--r--java/java.go198
1 files changed, 153 insertions, 45 deletions
diff --git a/java/java.go b/java/java.go
index c912368dc..e20b8b3c8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -29,6 +29,7 @@ import (
"android/soong/android"
"android/soong/java/config"
+ "android/soong/tradefed"
)
func init() {
@@ -134,6 +135,15 @@ type CompilerProperties struct {
Javacflags []string
}
+ // When compiling language level 9+ .java code in packages that are part of
+ // a system module, patch_module names the module that your sources and
+ // dependencies should be patched into. The Android runtime currently
+ // doesn't implement the JEP 261 module system so this option is only
+ // supported at compile time. It should only be needed to compile tests in
+ // packages that exist in libcore and which are inconvenient to move
+ // elsewhere.
+ Patch_module *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
@@ -262,13 +272,22 @@ type Module struct {
protoProperties android.ProtoProperties
deviceProperties CompilerDeviceProperties
- // header jar file suitable for inserting into the bootclasspath/classpath of another compile
+ // jar file containing header classes including static library dependencies, 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
+ // jar file containing implementation classes including static library dependencies but no
+ // resources
implementationJarFile android.Path
- // output file containing classes.dex
+ // jar file containing only resources including from static library dependencies
+ resourceJar android.Path
+
+ // jar file containing implementation classes and resources including static library
+ // dependencies
+ implementationAndResourcesJar android.Path
+
+ // output file containing classes.dex and resources
dexJarFile android.Path
// output file containing uninstrumented classes that will be instrumented by jacoco
@@ -277,7 +296,7 @@ type Module struct {
// output file containing mapping of obfuscated names
proguardDictionary android.Path
- // output file suitable for installing or running
+ // output file of the module, which may be a classes jar or a dex jar
outputFile android.Path
exportAidlIncludeDirs android.Paths
@@ -299,7 +318,7 @@ type Module struct {
}
func (j *Module) Srcs() android.Paths {
- return android.Paths{j.implementationJarFile}
+ return android.Paths{j.outputFile}
}
var _ android.SourceFileProducer = (*Module)(nil)
@@ -307,6 +326,8 @@ var _ android.SourceFileProducer = (*Module)(nil)
type Dependency interface {
HeaderJars() android.Paths
ImplementationJars() android.Paths
+ ResourceJars() android.Paths
+ ImplementationAndResourcesJars() android.Paths
AidlIncludeDirs() android.Paths
ExportedSdkLibs() []string
}
@@ -563,10 +584,7 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
}
if ctx.ModuleName() == "android_stubs_current" ||
ctx.ModuleName() == "android_system_stubs_current" ||
- ctx.ModuleName() == "android_test_stubs_current" ||
- ctx.ModuleName() == "metalava_android_stubs_current" ||
- ctx.ModuleName() == "metalava_android_system_stubs_current" ||
- ctx.ModuleName() == "metalava_android_test_stubs_current" {
+ ctx.ModuleName() == "android_test_stubs_current" {
ctx.AddDependency(ctx.Module(), frameworkApkTag, "framework-res")
}
}
@@ -663,7 +681,7 @@ type deps struct {
processorPath classpath
staticJars android.Paths
staticHeaderJars android.Paths
- staticJarResources android.Paths
+ staticResourceJars android.Paths
aidlIncludeDirs android.Paths
srcs android.Paths
srcJars android.Paths
@@ -697,11 +715,11 @@ func getLinkType(m *Module, name string) linkType {
case name == "core.current.stubs" || ver == "core_current" || noStdLibs || name == "stub-annotations" ||
name == "private-stub-annotations-jar":
return javaCore
- case name == "android_system_stubs_current" || strings.HasPrefix(ver, "system_") || name == "metalava_android_system_stubs_current":
+ case name == "android_system_stubs_current" || strings.HasPrefix(ver, "system_"):
return javaSystem
- case name == "android_test_stubs_current" || strings.HasPrefix(ver, "test_") || name == "metalava_android_test_stubs_current":
+ case name == "android_test_stubs_current" || strings.HasPrefix(ver, "test_"):
return javaPlatform
- case name == "android_stubs_current" || ver == "current" || name == "metalava_android_stubs_current":
+ case name == "android_stubs_current" || ver == "current":
return javaSdk
case ver == "":
return javaPlatform
@@ -784,10 +802,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
+ deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
// sdk lib names from dependencies are re-exported
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
case annoTag:
- deps.processorPath = append(deps.processorPath, dep.ImplementationJars()...)
+ deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
case frameworkResTag:
if ctx.ModuleName() == "framework" {
// framework.jar has a one-off dependency on the R.java and Manifest.java files
@@ -797,17 +816,14 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
case frameworkApkTag:
if ctx.ModuleName() == "android_stubs_current" ||
ctx.ModuleName() == "android_system_stubs_current" ||
- ctx.ModuleName() == "android_test_stubs_current" ||
- ctx.ModuleName() == "metalava_android_stubs_current" ||
- ctx.ModuleName() == "metalava_android_system_stubs_current" ||
- ctx.ModuleName() == "metalava_android_test_stubs_current" {
+ ctx.ModuleName() == "android_test_stubs_current" {
// framework stubs.jar need to depend on framework-res.apk, in order to pull the
// resource files out of there for aapt.
//
// Normally the package rule runs aapt, which includes the resource,
// but we're not running that in our package rule so just copy in the
// resource files here.
- deps.staticJarResources = append(deps.staticJarResources, dep.(*AndroidApp).exportPackage)
+ deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage)
}
case kotlinStdlibTag:
deps.kotlinStdlib = dep.HeaderJars()
@@ -898,11 +914,6 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
// disk and memory usage.
javacFlags = append(javacFlags, "-g:source,lines")
}
- if len(javacFlags) > 0 {
- // optimization.
- ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
- flags.javacFlags = "$javacFlags"
- }
if ctx.Config().RunErrorProne() {
if config.ErrorProneClasspath == nil {
@@ -954,6 +965,11 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
}
}
+ if j.properties.Patch_module != nil && ctx.Config().TargetOpenJDK9() {
+ patchClasspath := ".:" + flags.classpath.FormJavaClassPath("")
+ javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchClasspath)
+ }
+
// systemModules
if deps.systemModules != nil {
flags.systemModules = append(flags.systemModules, deps.systemModules)
@@ -967,6 +983,12 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
flags.aidlFlags = "$aidlFlags"
}
+ if len(javacFlags) > 0 {
+ // optimization.
+ ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
+ flags.javacFlags = "$javacFlags"
+ }
+
return flags
}
@@ -1133,16 +1155,27 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
if len(resArgs) > 0 {
resourceJar := android.PathForModuleOut(ctx, "res", jarName)
TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
+ j.resourceJar = resourceJar
if ctx.Failed() {
return
}
+ }
+
+ if len(deps.staticResourceJars) > 0 {
+ var jars android.Paths
+ if j.resourceJar != nil {
+ jars = append(jars, j.resourceJar)
+ }
+ jars = append(jars, deps.staticResourceJars...)
- jars = append(jars, resourceJar)
+ combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
+ TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
+ false, nil, nil)
+ j.resourceJar = combinedJar
}
- // static classpath jars have the resources in them, so the resource jars aren't necessary here
jars = append(jars, deps.staticJars...)
- jars = append(jars, deps.staticJarResources...)
+ jars = append(jars, deps.staticResourceJars...)
var manifest android.OptionalPath
if j.properties.Manifest != nil {
@@ -1151,14 +1184,24 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
// 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.
- var outputFile android.Path
+ var outputFile android.ModuleOutPath
if len(jars) == 1 && !manifest.Valid() {
- // Optimization: skip the combine step if there is nothing to do
- // TODO(ccross): this leaves any module-info.class files, but those should only come from
- // prebuilt dependencies until we support modules in the platform build, so there shouldn't be
- // any if len(jars) == 1.
- outputFile = jars[0]
+ if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok {
+ // Optimization: skip the combine step if there is nothing to do
+ // TODO(ccross): this leaves any module-info.class files, but those should only come from
+ // prebuilt dependencies until we support modules in the platform build, so there shouldn't be
+ // any if len(jars) == 1.
+ outputFile = moduleOutPath
+ } else {
+ combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: jars[0],
+ Output: combinedJar,
+ })
+ outputFile = combinedJar
+ }
} else {
combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
@@ -1177,12 +1220,21 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
}
}
+ // jarjar implementation jar if necessary
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, "jarjar", jarName)
TransformJarJar(ctx, jarjarFile, outputFile, jarjar_rules)
outputFile = jarjarFile
+
+ // jarjar resource jar if necessary
+ if j.resourceJar != nil {
+ resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName)
+ TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, jarjar_rules)
+ j.resourceJar = resourceJarJarFile
+ }
+
if ctx.Failed() {
return
}
@@ -1202,18 +1254,45 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
outputFile = j.instrument(ctx, flags, outputFile, jarName)
}
+ // merge implementation jar with resources if necessary
+ implementationAndResourcesJar := outputFile
+ if j.resourceJar != nil {
+ jars := android.Paths{implementationAndResourcesJar, j.resourceJar}
+ combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
+ TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
+ false, nil, nil)
+ implementationAndResourcesJar = combinedJar
+ }
+
+ j.implementationAndResourcesJar = implementationAndResourcesJar
+
if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
- var dexOutputFile android.Path
+ var dexOutputFile android.ModuleOutPath
dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
if ctx.Failed() {
return
}
- if Bool(j.properties.Installable) {
- outputFile = dexOutputFile
+
+ // merge dex jar with resources if necessary
+ if j.resourceJar != nil {
+ jars := android.Paths{dexOutputFile, j.resourceJar}
+ combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
+ TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
+ false, nil, nil)
+ dexOutputFile = combinedJar
}
+
+ j.dexJarFile = dexOutputFile
+
+ outputFile = dexOutputFile
+ } else {
+ outputFile = implementationAndResourcesJar
}
+
ctx.CheckbuildFile(outputFile)
- j.outputFile = outputFile
+
+ // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
+ j.outputFile = outputFile.WithoutRel()
}
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
@@ -1257,7 +1336,7 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
}
func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
- classesJar android.Path, jarName string) android.Path {
+ classesJar android.Path, jarName string) android.ModuleOutPath {
specs := j.jacocoModuleToZipCommand(ctx)
@@ -1281,6 +1360,17 @@ func (j *Module) ImplementationJars() android.Paths {
return android.Paths{j.implementationJarFile}
}
+func (j *Module) ResourceJars() android.Paths {
+ if j.resourceJar == nil {
+ return nil
+ }
+ return android.Paths{j.resourceJar}
+}
+
+func (j *Module) ImplementationAndResourcesJars() android.Paths {
+ return android.Paths{j.implementationAndResourcesJar}
+}
+
func (j *Module) AidlIncludeDirs() android.Paths {
return j.exportAidlIncludeDirs
}
@@ -1342,13 +1432,10 @@ func LibraryHostFactory() android.Module {
}
//
-// Java Junit Tests
+// Java Tests
//
type testProperties struct {
- // If true, add a static dependency on the platform junit library. Defaults to true.
- Junit *bool
-
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites []string `android:"arch_variant"`
@@ -1356,19 +1443,32 @@ type testProperties struct {
// the name of the test configuration (for example "AndroidTest.xml") that should be
// installed with the module.
Test_config *string `android:"arch_variant"`
+
+ // list of files or filegroup modules that provide data that should be installed alongside
+ // the test
+ Data []string
}
type Test struct {
Library
testProperties testProperties
+
+ testConfig android.Path
+ data android.Paths
+}
+
+func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config)
+ j.data = ctx.ExpandSources(j.testProperties.Data, nil)
+
+ j.Library.GenerateAndroidBuildActions(ctx)
}
func (j *Test) DepsMutator(ctx android.BottomUpMutatorContext) {
j.deps(ctx)
- if BoolDefault(j.testProperties.Junit, true) {
- ctx.AddDependency(ctx.Module(), staticLibTag, "junit")
- }
+ android.ExtractSourceDeps(ctx, j.testProperties.Test_config)
+ android.ExtractSourcesDeps(ctx, j.testProperties.Data)
}
func TestFactory() android.Module {
@@ -1589,6 +1689,14 @@ func (j *Import) ImplementationJars() android.Paths {
return android.Paths{j.combinedClasspathFile}
}
+func (j *Import) ResourceJars() android.Paths {
+ return nil
+}
+
+func (j *Import) ImplementationAndResourcesJars() android.Paths {
+ return android.Paths{j.combinedClasspathFile}
+}
+
func (j *Import) AidlIncludeDirs() android.Paths {
return nil
}