summaryrefslogtreecommitdiff
path: root/java/java.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java.go')
-rw-r--r--java/java.go168
1 files changed, 140 insertions, 28 deletions
diff --git a/java/java.go b/java/java.go
index ed3dca9e0..8d58a9023 100644
--- a/java/java.go
+++ b/java/java.go
@@ -23,12 +23,14 @@ import (
"path/filepath"
"strconv"
"strings"
+ "sync"
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/java/config"
"android/soong/tradefed"
)
@@ -37,14 +39,7 @@ func init() {
RegisterJavaBuildComponents(android.InitRegistrationContext)
// Register sdk member types.
- android.RegisterSdkMemberType(&headerLibrarySdkMemberType{
- librarySdkMemberType{
- android.SdkMemberTypeBase{
- PropertyName: "java_header_libs",
- SupportsSdk: true,
- },
- },
- })
+ android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
android.RegisterSdkMemberType(&implLibrarySdkMemberType{
librarySdkMemberType{
@@ -59,6 +54,8 @@ func init() {
PropertyName: "java_tests",
},
})
+
+ android.PostDepsMutators(RegisterPostDepsMutators)
}
func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
@@ -79,10 +76,52 @@ func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
ctx.RegisterModuleType("dex_import", DexImportFactory)
+ ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel()
+ })
+
ctx.RegisterSingletonType("logtags", LogtagsSingleton)
ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}
+func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("ordered_system_server_jars", systemServerJarsDepsMutator)
+}
+
+var (
+ dexpreoptedSystemServerJarsKey = android.NewOnceKey("dexpreoptedSystemServerJars")
+ dexpreoptedSystemServerJarsLock sync.Mutex
+)
+
+func DexpreoptedSystemServerJars(config android.Config) *[]string {
+ return config.Once(dexpreoptedSystemServerJarsKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
+// A PostDepsMutator pass that enforces total order on non-updatable system server jars. A total
+// order is neededed because such jars must be dexpreopted together (each jar on the list must have
+// all preceding jars in its class loader context). The total order must be compatible with the
+// partial order imposed by genuine dependencies between system server jars (which is not always
+// respected by the PRODUCT_SYSTEM_SERVER_JARS variable).
+//
+// An earlier mutator pass creates genuine dependencies, and this pass traverses the jars in that
+// order (which is partial and non-deterministic). This pass adds additional dependencies between
+// jars, making the order total and deterministic. It also constructs a global ordered list.
+func systemServerJarsDepsMutator(ctx android.BottomUpMutatorContext) {
+ jars := dexpreopt.NonUpdatableSystemServerJars(ctx, dexpreopt.GetGlobalConfig(ctx))
+ name := ctx.ModuleName()
+ if android.InList(name, jars) {
+ dexpreoptedSystemServerJarsLock.Lock()
+ defer dexpreoptedSystemServerJarsLock.Unlock()
+ jars := DexpreoptedSystemServerJars(ctx.Config())
+ for _, dep := range *jars {
+ ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerDepTag, dep)
+ }
+ *jars = append(*jars, name)
+ }
+}
+
func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
if j.SocSpecific() || j.DeviceSpecific() ||
(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
@@ -666,6 +705,11 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
} else if j.shouldInstrumentStatic(ctx) {
ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
+
+ // services depend on com.android.location.provider, but dependency in not registered in a Blueprint file
+ if ctx.ModuleName() == "services" {
+ ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerForcedDepTag, "com.android.location.provider")
+ }
}
func hasSrcExt(srcs []string, ext string) bool {
@@ -757,9 +801,13 @@ func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer
type linkType int
const (
+ // TODO(jiyong) rename these for better readability. Make the allowed
+ // and disallowed link types explicit
javaCore linkType = iota
javaSdk
javaSystem
+ javaModule
+ javaSystemServer
javaPlatform
)
@@ -789,6 +837,14 @@ func (m *Module) getLinkType(name string) (ret linkType, stubs bool) {
return javaSdk, true
case ver.kind == sdkPublic:
return javaSdk, false
+ case name == "android_module_lib_stubs_current":
+ return javaModule, true
+ case ver.kind == sdkModule:
+ return javaModule, false
+ case name == "services-stubs":
+ return javaSystemServer, true
+ case ver.kind == sdkSystemServer:
+ return javaSystemServer, false
case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform:
return javaPlatform, false
case !ver.valid():
@@ -824,11 +880,23 @@ func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext,
}
break
case javaSystem:
- if otherLinkType == javaPlatform {
+ if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer {
ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
ctx.OtherModuleName(to))
}
break
+ case javaModule:
+ if otherLinkType == javaPlatform || otherLinkType == javaSystemServer {
+ ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage,
+ ctx.OtherModuleName(to))
+ }
+ break
+ case javaSystemServer:
+ if otherLinkType == javaPlatform {
+ ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage,
+ ctx.OtherModuleName(to))
+ }
+ break
case javaPlatform:
// no restriction on link-type
break
@@ -963,18 +1031,16 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
case bootClasspathTag:
// If a system modules dependency has been added to the bootclasspath
// then add its libs to the bootclasspath.
- sm := module.(*SystemModules)
- deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
+ sm := module.(SystemModulesProvider)
+ deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
case systemModulesTag:
if deps.systemModules != nil {
panic("Found two system module dependencies")
}
- sm := module.(*SystemModules)
- if sm.outputDir == nil || len(sm.outputDeps) == 0 {
- panic("Missing directory for system module dependency")
- }
- deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
+ sm := module.(SystemModulesProvider)
+ outputDir, outputDeps := sm.OutputDirAndDeps()
+ deps.systemModules = &systemModules{outputDir, outputDeps}
}
}
})
@@ -1257,6 +1323,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.compiledSrcJars = srcJars
enable_sharding := false
+ var headerJarFileWithoutJarjar android.Path
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.disableTurbine {
if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
enable_sharding = true
@@ -1266,7 +1333,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// allow for the use of annotation processors that do function correctly
// with sharding enabled. See: b/77284273.
}
- j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
+ headerJarFileWithoutJarjar, j.headerJarFile =
+ j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
if ctx.Failed() {
return
}
@@ -1285,7 +1353,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
}
if enable_sharding {
- flags.classpath = append(flags.classpath, j.headerJarFile)
+ flags.classpath = append(flags.classpath, headerJarFileWithoutJarjar)
shardSize := int(*(j.properties.Javac_shard_size))
var shardSrcs []android.Paths
if len(uniqueSrcFiles) > 0 {
@@ -1453,6 +1521,14 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.headerJarFile = j.implementationJarFile
}
+ // Force enable the instrumentation for java code that is built for APEXes ...
+ // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
+ // doesn't make sense)
+ isJacocoAgent := ctx.ModuleName() == "jacocoagent"
+ if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
+ j.properties.Instrument = true
+ }
+
if j.shouldInstrument(ctx) {
outputFile = j.instrument(ctx, flags, outputFile, jarName)
}
@@ -1469,6 +1545,16 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.implementationAndResourcesJar = implementationAndResourcesJar
+ // Enable dex compilation for the APEX variants, unless it is disabled explicitly
+ if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() {
+ if j.deviceProperties.Compile_dex == nil {
+ j.deviceProperties.Compile_dex = proptools.BoolPtr(true)
+ }
+ if j.deviceProperties.Hostdex == nil {
+ j.deviceProperties.Hostdex = proptools.BoolPtr(true)
+ }
+ }
+
if ctx.Device() && j.hasCode(ctx) &&
(Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
// Dex compilation
@@ -1566,7 +1652,8 @@ func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
}
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
- deps deps, flags javaBuilderFlags, jarName string, extraJars android.Paths) android.Path {
+ deps deps, flags javaBuilderFlags, jarName string,
+ extraJars android.Paths) (headerJar, jarjarHeaderJar android.Path) {
var jars android.Paths
if len(srcFiles) > 0 || len(srcJars) > 0 {
@@ -1574,7 +1661,7 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
if ctx.Failed() {
- return nil
+ return nil, nil
}
jars = append(jars, turbineJar)
}
@@ -1583,7 +1670,6 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
// 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...)
// we cannot skip the combine step for now if there is only one jar
@@ -1592,18 +1678,19 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{},
false, nil, []string{"META-INF/TRANSITIVE"})
headerJar = combinedJar
+ jarjarHeaderJar = combinedJar
if j.expandJarjarRules != nil {
// Transform classes.jar into classes-jarjar.jar
jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
TransformJarJar(ctx, jarjarFile, headerJar, j.expandJarjarRules)
- headerJar = jarjarFile
+ jarjarHeaderJar = jarjarFile
if ctx.Failed() {
- return nil
+ return nil, nil
}
}
- return headerJar
+ return headerJar, jarjarHeaderJar
}
func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
@@ -1704,8 +1791,10 @@ func (j *Module) hasCode(ctx android.ModuleContext) bool {
func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
depTag := ctx.OtherModuleDependencyTag(dep)
- // dependencies other than the static linkage are all considered crossing APEX boundary
- return depTag == staticLibTag
+ // Dependencies other than the static linkage are all considered crossing APEX boundary
+ // Also, a dependency to an sdk member is also considered as such. This is required because
+ // sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
+ return depTag == staticLibTag || j.IsInAnySdk()
}
func (j *Module) Stem() string {
@@ -1716,6 +1805,10 @@ func (j *Module) JacocoReportClassesFile() android.Path {
return j.jacocoReportClassesFile
}
+func (j *Module) IsInstallable() bool {
+ return Bool(j.properties.Installable)
+}
+
//
// Java libraries (.jar file)
//
@@ -1753,7 +1846,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.checkSdkVersion(ctx)
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- j.dexpreopter.isInstallable = Bool(j.properties.Installable)
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
j.compile(ctx, nil)
@@ -1834,6 +1926,15 @@ func (mt *librarySdkMemberType) buildSnapshot(
module.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
}
+var javaHeaderLibsSdkMemberType android.SdkMemberType = &headerLibrarySdkMemberType{
+ librarySdkMemberType{
+ android.SdkMemberTypeBase{
+ PropertyName: "java_header_libs",
+ SupportsSdk: true,
+ },
+ },
+}
+
type headerLibrarySdkMemberType struct {
librarySdkMemberType
}
@@ -2393,6 +2494,14 @@ func (j *Import) SrcJarArgs() ([]string, android.Paths) {
return nil, nil
}
+func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+ depTag := ctx.OtherModuleDependencyTag(dep)
+ // dependencies other than the static linkage are all considered crossing APEX boundary
+ // Also, a dependency to an sdk member is also considered as such. This is required because
+ // sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
+ return depTag == staticLibTag || j.IsInAnySdk()
+}
+
// Add compile time check for interface implementation
var _ android.IDEInfo = (*Import)(nil)
var _ android.IDECustomizedModuleName = (*Import)(nil)
@@ -2493,13 +2602,16 @@ func (j *DexImport) Stem() string {
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}
+func (j *DexImport) IsInstallable() bool {
+ return true
+}
+
func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(j.properties.Jars) != 1 {
ctx.PropertyErrorf("jars", "exactly one jar must be provided")
}
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
- j.dexpreopter.isInstallable = true
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")