summaryrefslogtreecommitdiff
path: root/java/java.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java.go')
-rw-r--r--java/java.go1007
1 files changed, 806 insertions, 201 deletions
diff --git a/java/java.go b/java/java.go
index ddfb09a4f..5ed99f7e8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -29,16 +29,19 @@ import (
"android/soong/android"
"android/soong/java/config"
+ "android/soong/tradefed"
)
func init() {
android.RegisterModuleType("java_defaults", defaultsFactory)
- android.RegisterModuleType("java_library", LibraryFactory(true))
- android.RegisterModuleType("java_library_static", LibraryFactory(false))
+ android.RegisterModuleType("java_library", LibraryFactory)
+ android.RegisterModuleType("java_library_static", LibraryFactory)
android.RegisterModuleType("java_library_host", LibraryHostFactory)
android.RegisterModuleType("java_binary", BinaryFactory)
android.RegisterModuleType("java_binary_host", BinaryHostFactory)
+ android.RegisterModuleType("java_test", TestFactory)
+ android.RegisterModuleType("java_test_host", TestHostFactory)
android.RegisterModuleType("java_import", ImportFactory)
android.RegisterModuleType("java_import_host", ImportFactoryHost)
@@ -72,7 +75,7 @@ type CompilerProperties struct {
// list of files to use as Java resources
Java_resources []string `android:"arch_variant"`
- // list of files that should be excluded from java_resources
+ // list of files that should be excluded from java_resources and java_resource_dirs
Exclude_java_resources []string `android:"arch_variant"`
// don't build against the default libraries (bootclasspath, legacy-test, core-junit,
@@ -86,6 +89,9 @@ type CompilerProperties struct {
// list of module-specific flags that will be used for javac compiles
Javacflags []string `android:"arch_variant"`
+ // list of module-specific flags that will be used for kotlinc compiles
+ Kotlincflags []string `android:"arch_variant"`
+
// list of of java libraries that will be in the classpath
Libs []string `android:"arch_variant"`
@@ -101,7 +107,8 @@ type CompilerProperties struct {
// If not blank, set the java version passed to javac as -source and -target
Java_version *string
- // If set to false, don't allow this module to be installed. Defaults to true.
+ // If set to true, allow this module to be dexed and installed on devices. Has no
+ // effect on host modules, which are always considered installable.
Installable *bool
// If set to true, include sources used to compile the module in to the final jar
@@ -127,6 +134,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 `android:"arch_variant"`
+
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
@@ -162,9 +178,21 @@ type CompilerDeviceProperties struct {
// list of module-specific flags that will be used for dex compiles
Dxflags []string `android:"arch_variant"`
- // if not blank, set to the version of the sdk to compile against
+ // if not blank, set to the version of the sdk to compile against. Defaults to compiling against the current
+ // sdk if platform_apis is not set.
Sdk_version *string
+ // if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
+ // Defaults to sdk_version if not set.
+ Min_sdk_version *string
+
+ // if not blank, set the targetSdkVersion in the AndroidManifest.xml.
+ // Defaults to sdk_version if not set.
+ Target_sdk_version *string
+
+ // if true, compile against the platform APIs instead of an SDK.
+ Platform_apis *bool
+
Aidl struct {
// Top level directories to pass to aidl tool
Include_dirs []string
@@ -178,11 +206,17 @@ type CompilerDeviceProperties struct {
// whether to generate traces (for systrace) for this interface
Generate_traces *bool
+
+ // whether to generate Binder#GetTransaction name method.
+ Generate_get_transaction_name *bool
}
// If true, export a copy of the module as a -hostdex module for host testing.
Hostdex *bool
+ // If set to true, compile dex regardless of installable. Defaults to false.
+ Compile_dex *bool
+
Dex_preopt struct {
// If false, prevent dexpreopting and stripping the dex file from the final jar. Defaults to
// true.
@@ -203,8 +237,8 @@ type CompilerDeviceProperties struct {
}
Optimize struct {
- // If false, disable all optimization. Defaults to true for apps, false for
- // libraries and tests.
+ // If false, disable all optimization. Defaults to true for android_app and android_test
+ // modules, false for java_library and java_test modules.
Enabled *bool
// If true, optimize for size by removing unused code. Defaults to true for apps,
@@ -230,6 +264,8 @@ type CompilerDeviceProperties struct {
// When targeting 1.9, override the modules to use with --system
System_modules *string
+
+ UncompressDex bool `blueprint:"mutated"`
}
// Module contains the properties and members used by all java module types
@@ -241,13 +277,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
@@ -256,7 +301,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
@@ -272,10 +317,24 @@ type Module struct {
// list of extra progurad flag files
extraProguardFlagFiles android.Paths
+
+ // manifest file to use instead of properties.Manifest
+ overrideManifest android.OptionalPath
+
+ // list of SDK lib names that this java moudule is exporting
+ exportedSdkLibs []string
+
+ // list of source files, collected from compiledJavaSrcs and compiledSrcJars
+ // filter out Exclude_srcs, will be used by android.IDEInfo struct
+ expandIDEInfoCompiledSrcs []string
}
func (j *Module) Srcs() android.Paths {
- return android.Paths{j.implementationJarFile}
+ return android.Paths{j.outputFile}
+}
+
+func (j *Module) DexJarFile() android.Path {
+ return j.dexJarFile
}
var _ android.SourceFileProducer = (*Module)(nil)
@@ -283,9 +342,32 @@ 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
+}
+
+type SdkLibraryDependency interface {
+ HeaderJars(linkType linkType) android.Paths
+ ImplementationJars(linkType linkType) android.Paths
}
+type SrcDependency interface {
+ CompiledSrcs() android.Paths
+ CompiledSrcJars() android.Paths
+}
+
+func (j *Module) CompiledSrcs() android.Paths {
+ return j.compiledJavaSrcs
+}
+
+func (j *Module) CompiledSrcJars() android.Paths {
+ return j.compiledSrcJars
+}
+
+var _ SrcDependency = (*Module)(nil)
+
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
android.InitAndroidArchModule(module, hod, android.MultilibCommon)
android.InitDefaultableModule(module)
@@ -296,40 +378,41 @@ type dependencyTag struct {
name string
}
+type jniDependencyTag struct {
+ blueprint.BaseDependencyTag
+ target android.Target
+}
+
var (
- staticLibTag = dependencyTag{name: "staticlib"}
- libTag = dependencyTag{name: "javalib"}
- bootClasspathTag = dependencyTag{name: "bootclasspath"}
- systemModulesTag = dependencyTag{name: "system modules"}
- frameworkResTag = dependencyTag{name: "framework-res"}
- kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"}
- proguardRaiseTag = dependencyTag{name: "proguard-raise"}
+ staticLibTag = dependencyTag{name: "staticlib"}
+ libTag = dependencyTag{name: "javalib"}
+ annoTag = dependencyTag{name: "annotation processor"}
+ bootClasspathTag = dependencyTag{name: "bootclasspath"}
+ systemModulesTag = dependencyTag{name: "system modules"}
+ frameworkResTag = dependencyTag{name: "framework-res"}
+ frameworkApkTag = dependencyTag{name: "framework-apk"}
+ kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"}
+ proguardRaiseTag = dependencyTag{name: "proguard-raise"}
+ certificateTag = dependencyTag{name: "certificate"}
+ instrumentationForTag = dependencyTag{name: "instrumentation_for"}
)
type sdkDep struct {
useModule, useFiles, useDefaultLibs, invalidVersion bool
- module string
+ modules []string
systemModules string
frameworkResModule string
- jar android.Path
+ jars android.Paths
aidl android.Path
}
-func sdkStringToNumber(ctx android.BaseContext, v string) int {
- switch v {
- case "", "current", "system_current", "test_current", "core_current":
- return android.FutureApiLevel
- default:
- if i, err := strconv.Atoi(android.GetNumericSdkVersion(v)); err != nil {
- ctx.PropertyErrorf("sdk_version", "invalid sdk version")
- return -1
- } else {
- return i
- }
- }
+type jniLib struct {
+ name string
+ path android.Path
+ target android.Target
}
func (j *Module) shouldInstrument(ctx android.BaseContext) bool {
@@ -342,10 +425,71 @@ func (j *Module) shouldInstrumentStatic(ctx android.BaseContext) bool {
ctx.Config().UnbundledBuild())
}
-func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
- i := sdkStringToNumber(ctx, v)
- if i == -1 {
- // Invalid sdk version, error handled by sdkStringToNumber.
+func (j *Module) sdkVersion() string {
+ return String(j.deviceProperties.Sdk_version)
+}
+
+func (j *Module) minSdkVersion() string {
+ if j.deviceProperties.Min_sdk_version != nil {
+ return *j.deviceProperties.Min_sdk_version
+ }
+ return j.sdkVersion()
+}
+
+func (j *Module) targetSdkVersion() string {
+ if j.deviceProperties.Target_sdk_version != nil {
+ return *j.deviceProperties.Target_sdk_version
+ }
+ return j.sdkVersion()
+}
+
+type sdkContext interface {
+ // sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set.
+ sdkVersion() string
+ // minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set.
+ minSdkVersion() string
+ // targetSdkVersion returns the target_sdk_version property of the current module, or sdkVersion() if it is not set.
+ targetSdkVersion() string
+}
+
+func sdkVersionOrDefault(ctx android.BaseContext, v string) string {
+ switch v {
+ case "", "current", "system_current", "test_current", "core_current":
+ return ctx.Config().DefaultAppTargetSdk()
+ default:
+ return v
+ }
+}
+
+// Returns a sdk version as a number. For modules targeting an unreleased SDK (meaning it does not yet have a number)
+// it returns android.FutureApiLevel (10000).
+func sdkVersionToNumber(ctx android.BaseContext, v string) (int, error) {
+ switch v {
+ case "", "current", "test_current", "system_current", "core_current":
+ return ctx.Config().DefaultAppTargetSdkInt(), nil
+ default:
+ n := android.GetNumericSdkVersion(v)
+ if i, err := strconv.Atoi(n); err != nil {
+ return -1, fmt.Errorf("invalid sdk version %q", n)
+ } else {
+ return i, nil
+ }
+ }
+}
+
+func sdkVersionToNumberAsString(ctx android.BaseContext, v string) (string, error) {
+ n, err := sdkVersionToNumber(ctx, v)
+ if err != nil {
+ return "", err
+ }
+ return strconv.Itoa(n), nil
+}
+
+func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep {
+ v := sdkContext.sdkVersion()
+ i, err := sdkVersionToNumber(ctx, v)
+ if err != nil {
+ ctx.PropertyErrorf("sdk_version", "%s", err)
return sdkDep{}
}
@@ -365,24 +509,30 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
}
}
- toFile := func(v string) sdkDep {
- isCore := strings.HasPrefix(v, "core_")
- if isCore {
- v = strings.TrimPrefix(v, "core_")
+ toPrebuilt := func(sdk string) sdkDep {
+ var api, v string
+ if strings.Contains(sdk, "_") {
+ t := strings.Split(sdk, "_")
+ api = t[0]
+ v = t[1]
+ } else {
+ api = "public"
+ v = sdk
}
- dir := filepath.Join("prebuilts/sdk", v)
+ dir := filepath.Join("prebuilts", "sdk", v, api)
jar := filepath.Join(dir, "android.jar")
- if isCore {
- jar = filepath.Join(dir, "core.jar")
- }
- aidl := filepath.Join(dir, "framework.aidl")
+ // There's no aidl for other SDKs yet.
+ // TODO(77525052): Add aidl files for other SDKs too.
+ public_dir := filepath.Join("prebuilts", "sdk", v, "public")
+ aidl := filepath.Join(public_dir, "framework.aidl")
jarPath := android.ExistentPathForSource(ctx, jar)
aidlPath := android.ExistentPathForSource(ctx, aidl)
+ lambdaStubsPath := android.PathForSource(ctx, config.SdkLambdaStubsPath)
if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
return sdkDep{
invalidVersion: true,
- module: "sdk_v" + v,
+ modules: []string{fmt.Sprintf("sdk_%s_%s_android", api, v)},
}
}
@@ -398,22 +548,28 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
return sdkDep{
useFiles: true,
- jar: jarPath.Path(),
+ jars: android.Paths{jarPath.Path(), lambdaStubsPath},
aidl: aidlPath.Path(),
}
}
- //toModule := func(m string) sdkDep {
- // return sdkDep{
- // useModule: true,
- // module: m,
- // systemModules: m + "_system_modules",
- // frameworkResModule: r,
- // }
- //}
+ toModule := func(m, r string) sdkDep {
+ ret := sdkDep{
+ useModule: true,
+ modules: []string{m, config.DefaultLambdaStubsLibrary},
+ systemModules: m + "_system_modules",
+ frameworkResModule: r,
+ }
+ if m == "core.current.stubs" {
+ ret.systemModules = "core-system-modules"
+ } else if m == "core.platform.api.stubs" {
+ ret.systemModules = "core-platform-api-stubs-system-modules"
+ }
+ return ret
+ }
if ctx.Config().UnbundledBuild() && v != "" {
- return toFile(v)
+ return toPrebuilt(v)
}
switch v {
@@ -422,55 +578,58 @@ func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
useDefaultLibs: true,
frameworkResModule: "framework-res",
}
- // 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", "framework-res")
- //case "system_current":
- // return toModule("android_system_stubs_current", "framework-res")
- //case "test_current":
- // return toModule("android_test_stubs_current", "framework-res")
+ case "current":
+ return toModule("android_stubs_current", "framework-res")
+ case "system_current":
+ return toModule("android_system_stubs_current", "framework-res")
+ case "test_current":
+ return toModule("android_test_stubs_current", "framework-res")
+ case "core_current":
+ return toModule("core.current.stubs", "")
default:
- return toFile(v)
+ return toPrebuilt(v)
}
}
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
- if !proptools.Bool(j.properties.No_standard_libs) {
- sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version))
+ if !Bool(j.properties.No_standard_libs) {
+ sdkDep := decodeSdkDep(ctx, sdkContext(j))
if sdkDep.useDefaultLibs {
- ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
- 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...)
+ ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
+ ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
+ if !Bool(j.properties.No_framework_libs) {
+ ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
}
} else if sdkDep.useModule {
- if ctx.Config().TargetOpenJDK9() {
- ctx.AddDependency(ctx.Module(), systemModulesTag, sdkDep.systemModules)
- }
- ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module)
+ ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
+ ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
if Bool(j.deviceProperties.Optimize.Enabled) {
- ctx.AddDependency(ctx.Module(), proguardRaiseTag, config.DefaultBootclasspathLibraries...)
- ctx.AddDependency(ctx.Module(), proguardRaiseTag, config.DefaultLibraries...)
+ ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...)
+ ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...)
}
}
} 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.Config().TargetOpenJDK9() {
- ctx.AddDependency(ctx.Module(), systemModulesTag, *j.deviceProperties.System_modules)
+ } else if *j.deviceProperties.System_modules != "none" {
+ ctx.AddVariationDependencies(nil, systemModulesTag, *j.deviceProperties.System_modules)
}
- if ctx.ModuleName() == "framework" {
- ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
+ if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
+ ctx.AddVariationDependencies(nil, frameworkResTag, "framework-res")
+ }
+ if ctx.ModuleName() == "android_stubs_current" ||
+ ctx.ModuleName() == "android_system_stubs_current" ||
+ ctx.ModuleName() == "android_test_stubs_current" {
+ ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res")
}
}
- ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
- ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
- ctx.AddDependency(ctx.Module(), libTag, j.properties.Annotation_processors...)
+ ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
+ ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
+ ctx.AddFarVariationDependencies([]blueprint.Variation{
+ {Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant},
+ }, annoTag, j.properties.Annotation_processors...)
android.ExtractSourcesDeps(ctx, j.properties.Srcs)
android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
@@ -484,11 +643,11 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if j.hasSrcExt(".kt") {
// TODO(ccross): move this to a mutator pass that can tell if generated sources contain
// Kotlin files
- ctx.AddDependency(ctx.Module(), kotlinStdlibTag, "kotlin-stdlib")
+ ctx.AddVariationDependencies(nil, kotlinStdlibTag, "kotlin-stdlib")
}
if j.shouldInstrumentStatic(ctx) {
- ctx.AddDependency(ctx.Module(), staticLibTag, "jacocoagent")
+ ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
}
@@ -527,7 +686,8 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt
aidlIncludes = append(aidlIncludes,
android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)
- var flags []string
+ flags := []string{"-b"}
+
if aidlPreprocess.Valid() {
flags = append(flags, "-p"+aidlPreprocess.String())
} else {
@@ -545,16 +705,22 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt
flags = append(flags, "-t")
}
+ if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) {
+ flags = append(flags, "--transaction_names")
+ }
+
return flags
}
type deps struct {
classpath classpath
bootClasspath classpath
+ processorPath classpath
staticJars android.Paths
staticHeaderJars android.Paths
- staticJarResources android.Paths
+ staticResourceJars android.Paths
aidlIncludeDirs android.Paths
+ srcs android.Paths
srcJars android.Paths
systemModules android.Path
aidlPreprocess android.OptionalPath
@@ -570,31 +736,110 @@ func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer
}
}
+type linkType int
+
+const (
+ javaCore linkType = iota
+ javaSdk
+ javaSystem
+ javaPlatform
+)
+
+func getLinkType(m *Module, name string) (ret linkType, stubs bool) {
+ ver := m.sdkVersion()
+ switch {
+ case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
+ name == "stub-annotations" || name == "private-stub-annotations-jar" ||
+ name == "core-lambda-stubs":
+ return javaCore, true
+ case ver == "core_current":
+ return javaCore, false
+ case name == "android_system_stubs_current":
+ return javaSystem, true
+ case strings.HasPrefix(ver, "system_"):
+ return javaSystem, false
+ case name == "android_test_stubs_current":
+ return javaSystem, true
+ case strings.HasPrefix(ver, "test_"):
+ return javaPlatform, false
+ case name == "android_stubs_current":
+ return javaSdk, true
+ case ver == "current":
+ return javaSdk, false
+ case ver == "":
+ return javaPlatform, false
+ default:
+ if _, err := strconv.Atoi(ver); err != nil {
+ panic(fmt.Errorf("expected sdk_version to be a number, got %q", ver))
+ }
+ return javaSdk, false
+ }
+}
+
func checkLinkType(ctx android.ModuleContext, from *Module, to *Library, tag dependencyTag) {
- if strings.HasPrefix(String(from.deviceProperties.Sdk_version), "core_") {
- if !strings.HasPrefix(String(to.deviceProperties.Sdk_version), "core_") {
- ctx.ModuleErrorf("depends on other library %q using non-core Java APIs",
+ if ctx.Host() {
+ return
+ }
+
+ myLinkType, stubs := getLinkType(from, ctx.ModuleName())
+ if stubs {
+ return
+ }
+ otherLinkType, _ := getLinkType(&to.Module, ctx.OtherModuleName(to))
+ commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source."
+
+ switch myLinkType {
+ case javaCore:
+ if otherLinkType != javaCore {
+ ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage,
+ ctx.OtherModuleName(to))
+ }
+ break
+ case javaSdk:
+ if otherLinkType != javaCore && otherLinkType != javaSdk {
+ ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage,
ctx.OtherModuleName(to))
}
+ break
+ case javaSystem:
+ if otherLinkType == javaPlatform {
+ ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
+ ctx.OtherModuleName(to))
+ }
+ break
+ case javaPlatform:
+ // no restriction on link-type
+ break
}
}
func (j *Module) collectDeps(ctx android.ModuleContext) deps {
var deps deps
- sdkDep := decodeSdkDep(ctx, String(j.deviceProperties.Sdk_version))
- 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)
+ if ctx.Device() {
+ sdkDep := decodeSdkDep(ctx, sdkContext(j))
+ if sdkDep.invalidVersion {
+ ctx.AddMissingDependencies(sdkDep.modules)
+ } else if sdkDep.useFiles {
+ // sdkDep.jar is actually equivalent to turbine header.jar.
+ deps.classpath = append(deps.classpath, sdkDep.jars...)
+ deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, sdkDep.aidl)
+ }
}
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
+ if _, ok := tag.(*jniDependencyTag); ok {
+ // Handled by AndroidApp.collectAppDeps
+ return
+ }
+ if tag == certificateTag {
+ // Handled by AndroidApp.collectAppDeps
+ return
+ }
+
if to, ok := module.(*Library); ok {
switch tag {
case bootClasspathTag, libTag, staticLibTag:
@@ -606,25 +851,52 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
switch tag {
case bootClasspathTag:
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
- case libTag:
+ case libTag, instrumentationForTag:
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
+ // sdk lib names from dependencies are re-exported
+ j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
case staticLibTag:
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.ImplementationAndResourcesJars()...)
case frameworkResTag:
- if ctx.ModuleName() == "framework" {
+ if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
// framework.jar has a one-off dependency on the R.java and Manifest.java files
// generated by framework-res.apk
deps.srcJars = append(deps.srcJars, dep.(*AndroidApp).aaptSrcJar)
}
+ case frameworkApkTag:
+ if ctx.ModuleName() == "android_stubs_current" ||
+ ctx.ModuleName() == "android_system_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.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage)
+ }
case kotlinStdlibTag:
deps.kotlinStdlib = dep.HeaderJars()
- default:
- panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
+ case SdkLibraryDependency:
+ switch tag {
+ case libTag:
+ linkType, _ := getLinkType(j, ctx.ModuleName())
+ deps.classpath = append(deps.classpath, dep.HeaderJars(linkType)...)
+ // names of sdk libs that are directly depended are exported
+ j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
+ default:
+ ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
+ }
case android.SourceFileProducer:
switch tag {
case libTag:
@@ -659,16 +931,43 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
})
+ j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
+
return deps
}
+func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string {
+ var ret string
+ sdk, err := sdkVersionToNumber(ctx, sdkContext.sdkVersion())
+ if err != nil {
+ ctx.PropertyErrorf("sdk_version", "%s", err)
+ }
+ if javaVersion != "" {
+ ret = javaVersion
+ } else if ctx.Device() && sdk <= 23 {
+ ret = "1.7"
+ } else if ctx.Device() && sdk <= 28 || !ctx.Config().TargetOpenJDK9() {
+ ret = "1.8"
+ } else if ctx.Device() && sdkContext.sdkVersion() != "" && sdk == android.FutureApiLevel {
+ // TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
+ ret = "1.8"
+ } else {
+ ret = "1.9"
+ }
+
+ return ret
+}
+
func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
var flags javaBuilderFlags
+ // javaVersion flag.
+ flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
+
// javac flags.
javacFlags := j.properties.Javacflags
- if ctx.Config().TargetOpenJDK9() {
+ if flags.javaVersion == "1.9" {
javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
}
if ctx.Config().MinimizeJavaDebugInfo() {
@@ -676,36 +975,29 @@ 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 len(j.properties.Errorprone.Javacflags) > 0 {
- flags.errorProneExtraJavacFlags = strings.Join(j.properties.Errorprone.Javacflags, " ")
- }
+ if ctx.Config().RunErrorProne() {
+ if config.ErrorProneClasspath == nil {
+ ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
+ }
- // javaVersion flag.
- sdk := sdkStringToNumber(ctx, String(j.deviceProperties.Sdk_version))
- if j.properties.Java_version != nil {
- flags.javaVersion = *j.properties.Java_version
- } else if ctx.Device() && sdk <= 23 {
- flags.javaVersion = "1.7"
- } else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() {
- flags.javaVersion = "1.8"
- } else if ctx.Device() && String(j.deviceProperties.Sdk_version) != "" && sdk == android.FutureApiLevel {
- // 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"
+ errorProneFlags := []string{
+ "-Xplugin:ErrorProne",
+ "${config.ErrorProneChecks}",
+ }
+ errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...)
+
+ flags.errorProneExtraJavacFlags = "${config.ErrorProneFlags} " +
+ "'" + strings.Join(errorProneFlags, " ") + "'"
+ flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath))
}
// classpath
flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
flags.classpath = append(flags.classpath, deps.classpath...)
+ flags.processorPath = append(flags.processorPath, deps.processorPath...)
- if len(flags.bootClasspath) == 0 && ctx.Host() && !ctx.Config().TargetOpenJDK9() &&
+ if len(flags.bootClasspath) == 0 && ctx.Host() && flags.javaVersion != "1.9" &&
!Bool(j.properties.No_standard_libs) &&
inList(flags.javaVersion, []string{"1.6", "1.7", "1.8"}) {
// Give host-side tools a version of OpenJDK's standard libraries
@@ -731,6 +1023,11 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
}
}
+ if j.properties.Patch_module != nil && flags.javaVersion == "1.9" {
+ 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)
@@ -744,6 +1041,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
}
@@ -754,7 +1057,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
deps := j.collectDeps(ctx)
flags := j.collectBuilderFlags(ctx, deps)
- if ctx.Config().TargetOpenJDK9() {
+ if flags.javaVersion == "1.9" {
j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
}
srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
@@ -768,7 +1071,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
srcJars = append(srcJars, deps.srcJars...)
srcJars = append(srcJars, extraSrcJars...)
- var jars android.Paths
+ // Collect source files from compiledJavaSrcs, compiledSrcJars and filter out Exclude_srcs
+ // that IDEInfo struct will use
+ j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...)
jarName := ctx.ModuleName() + ".jar"
@@ -782,20 +1087,31 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
}
}
+ var kotlinJars android.Paths
+
if srcFiles.HasExt(".kt") {
+ // user defined kotlin flags.
+ kotlincFlags := j.properties.Kotlincflags
+ CheckKotlincFlags(ctx, kotlincFlags)
+
// 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
// won't emit any classes for them.
-
- flags.kotlincFlags = "-no-stdlib"
+ kotlincFlags = append(kotlincFlags, "-no-stdlib")
if ctx.Device() {
- flags.kotlincFlags += " -no-jdk"
+ kotlincFlags = append(kotlincFlags, "-no-jdk")
+ }
+ if len(kotlincFlags) > 0 {
+ // optimization.
+ ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
+ flags.kotlincFlags += "$kotlincFlags"
}
var kotlinSrcFiles android.Paths
kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
+ flags.kotlincClasspath = append(flags.kotlincClasspath, deps.bootClasspath...)
flags.kotlincClasspath = append(flags.kotlincClasspath, deps.kotlinStdlib...)
flags.kotlincClasspath = append(flags.kotlincClasspath, deps.classpath...)
@@ -808,11 +1124,14 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
// Make javac rule depend on the kotlinc rule
flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
flags.classpath = append(flags.classpath, kotlinJar)
+
// Jar kotlin classes into the final jar after javac
- jars = append(jars, kotlinJar)
- jars = append(jars, deps.kotlinStdlib...)
+ kotlinJars = append(kotlinJars, kotlinJar)
+ kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
}
+ jars := append(android.Paths(nil), kotlinJars...)
+
// Store the list of .java files that was passed to javac
j.compiledJavaSrcs = uniqueSrcFiles
j.compiledSrcJars = srcJars
@@ -828,18 +1147,14 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
j.properties.Javac_shard_size)
}
}
- // 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
- }
+ j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
+ if ctx.Failed() {
+ return
}
}
if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 {
var extraJarDeps android.Paths
- if ctx.Config().IsEnvTrue("RUN_ERROR_PRONE") {
+ if ctx.Config().RunErrorProne() {
// 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).
@@ -877,7 +1192,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
}
}
- dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs, j.properties.Exclude_java_resource_dirs)
+ dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
+ j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
var resArgs []string
@@ -889,7 +1205,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
resArgs = append(resArgs, fileArgs...)
resDeps = append(resDeps, fileDeps...)
- if proptools.Bool(j.properties.Include_srcs) {
+ if Bool(j.properties.Include_srcs) {
srcArgs, srcDeps := SourceFilesToJarArgs(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
resArgs = append(resArgs, srcArgs...)
resDeps = append(resDeps, srcDeps...)
@@ -898,43 +1214,75 @@ 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
}
+ }
- jars = append(jars, resourceJar)
+ if len(deps.staticResourceJars) > 0 {
+ var jars android.Paths
+ if j.resourceJar != nil {
+ jars = append(jars, j.resourceJar)
+ }
+ jars = append(jars, deps.staticResourceJars...)
+
+ 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.staticResourceJars...)
- var manifest android.OptionalPath
- if j.properties.Manifest != nil {
+ manifest := j.overrideManifest
+ if !manifest.Valid() && j.properties.Manifest != nil {
manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "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.
- 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, false, nil)
+ TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
+ false, nil, nil)
outputFile = combinedJar
}
+ // 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
}
@@ -954,18 +1302,74 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
outputFile = j.instrument(ctx, flags, outputFile, jarName)
}
- if ctx.Device() && j.installable() {
- outputFile = j.compileDex(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.ModuleOutPath
+ dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
if ctx.Failed() {
return
}
+
+ // 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()
+}
+
+// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
+// since some of these flags may be used internally.
+func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
+ for _, flag := range flags {
+ flag = strings.TrimSpace(flag)
+
+ if !strings.HasPrefix(flag, "-") {
+ ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
+ } else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
+ ctx.PropertyErrorf("kotlincflags",
+ "Bad flag: `%s`, only use internal compiler for consistency.", flag)
+ } else if inList(flag, config.KotlincIllegalFlags) {
+ ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
+ } else if flag == "-include-runtime" {
+ ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
+ } else {
+ args := strings.Split(flag, " ")
+ if args[0] == "-kotlin-home" {
+ ctx.PropertyErrorf("kotlincflags",
+ "Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
+ }
+ }
+ }
}
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
- deps deps, flags javaBuilderFlags, jarName string) android.Path {
+ deps deps, flags javaBuilderFlags, jarName string, extraJars android.Paths) android.Path {
var jars android.Paths
if len(srcFiles) > 0 || len(srcJars) > 0 {
@@ -978,6 +1382,8 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
jars = append(jars, turbineJar)
}
+ jars = append(jars, extraJars...)
+
// 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
@@ -986,7 +1392,8 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
// 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"})
+ TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{},
+ false, nil, []string{"META-INF"})
headerJar = combinedJar
if j.properties.Jarjar_rules != nil {
@@ -1004,7 +1411,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)
@@ -1018,21 +1425,6 @@ func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
return instrumentedJar
}
-// 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", "core_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
-}
-
var _ Dependency = (*Library)(nil)
func (j *Module) HeaderJars() android.Paths {
@@ -1043,16 +1435,48 @@ 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
}
+func (j *Module) ExportedSdkLibs() []string {
+ return j.exportedSdkLibs
+}
+
var _ logtagsProducer = (*Module)(nil)
func (j *Module) logtags() android.Paths {
return j.logtagsSrcs
}
+// Collect information for opening IDE project files in java/jdeps.go.
+func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
+ dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
+ dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
+ dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
+ if j.properties.Jarjar_rules != nil {
+ dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, *j.properties.Jarjar_rules)
+ }
+}
+
+func (j *Module) CompilerDeps() []string {
+ jdeps := []string{}
+ jdeps = append(jdeps, j.properties.Libs...)
+ jdeps = append(jdeps, j.properties.Static_libs...)
+ return jdeps
+}
+
//
// Java libraries (.jar file)
//
@@ -1064,7 +1488,7 @@ type Library struct {
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.compile(ctx)
- if j.installable() {
+ if Bool(j.properties.Installable) || ctx.Host() {
j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
ctx.ModuleName()+".jar", j.outputFile)
}
@@ -1074,22 +1498,16 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
j.deps(ctx)
}
-func LibraryFactory(installable bool) func() android.Module {
- return func() android.Module {
- module := &Library{}
-
- if !installable {
- module.properties.Installable = proptools.BoolPtr(false)
- }
+func LibraryFactory() android.Module {
+ module := &Library{}
- module.AddProperties(
- &module.Module.properties,
- &module.Module.deviceProperties,
- &module.Module.protoProperties)
+ module.AddProperties(
+ &module.Module.properties,
+ &module.Module.deviceProperties,
+ &module.Module.protoProperties)
- InitJavaModule(module, android.HostAndDeviceSupported)
- return module
- }
+ InitJavaModule(module, android.HostAndDeviceSupported)
+ return module
}
func LibraryHostFactory() android.Module {
@@ -1099,6 +1517,82 @@ func LibraryHostFactory() android.Module {
&module.Module.properties,
&module.Module.protoProperties)
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+
+ InitJavaModule(module, android.HostSupported)
+ return module
+}
+
+//
+// Java Tests
+//
+
+type testProperties struct {
+ // list of compatibility suites (for example "cts", "vts") that the module should be
+ // installed into.
+ Test_suites []string `android:"arch_variant"`
+
+ // the name of the test configuration (for example "AndroidTest.xml") that should be
+ // installed with the module.
+ Test_config *string `android:"arch_variant"`
+
+ // the name of the test configuration template (for example "AndroidTestTemplate.xml") that
+ // should be installed with the module.
+ Test_config_template *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.testProperties.Test_config_template)
+ j.data = ctx.ExpandSources(j.testProperties.Data, nil)
+
+ j.Library.GenerateAndroidBuildActions(ctx)
+}
+
+func (j *Test) DepsMutator(ctx android.BottomUpMutatorContext) {
+ j.deps(ctx)
+ android.ExtractSourceDeps(ctx, j.testProperties.Test_config)
+ android.ExtractSourceDeps(ctx, j.testProperties.Test_config_template)
+ android.ExtractSourcesDeps(ctx, j.testProperties.Data)
+}
+
+func TestFactory() android.Module {
+ module := &Test{}
+
+ module.AddProperties(
+ &module.Module.properties,
+ &module.Module.deviceProperties,
+ &module.Module.protoProperties,
+ &module.testProperties)
+
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+
+ InitJavaModule(module, android.HostAndDeviceSupported)
+ return module
+}
+
+func TestHostFactory() android.Module {
+ module := &Test{}
+
+ module.AddProperties(
+ &module.Module.properties,
+ &module.Module.protoProperties,
+ &module.testProperties)
+
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+
InitJavaModule(module, android.HostSupported)
return module
}
@@ -1110,6 +1604,9 @@ func LibraryHostFactory() android.Module {
type binaryProperties struct {
// installable script to execute the resulting jar
Wrapper *string
+
+ // Name of the class containing main to be inserted into the manifest as Main-Class.
+ Main_class *string
}
type Binary struct {
@@ -1130,6 +1627,15 @@ func (j *Binary) HostToolPath() android.OptionalPath {
func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if ctx.Arch().ArchType == android.Common {
// Compile the jar
+ if j.binaryProperties.Main_class != nil {
+ if j.properties.Manifest != nil {
+ ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set")
+ }
+ manifestFile := android.PathForModuleOut(ctx, "manifest.txt")
+ GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class))
+ j.overrideManifest = android.OptionalPathForPath(manifestFile)
+ }
+
j.Library.GenerateAndroidBuildActions(ctx)
} else {
// Handle the binary wrapper
@@ -1167,6 +1673,8 @@ func BinaryFactory() android.Module {
&module.Module.protoProperties,
&module.binaryProperties)
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
android.InitDefaultableModule(module)
return module
@@ -1177,10 +1685,11 @@ func BinaryHostFactory() android.Module {
module.AddProperties(
&module.Module.properties,
- &module.Module.deviceProperties,
&module.Module.protoProperties,
&module.binaryProperties)
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
android.InitDefaultableModule(module)
return module
@@ -1196,16 +1705,37 @@ type ImportProperties struct {
Sdk_version *string
Installable *bool
+
+ // List of shared java libs that this module has dependencies to
+ Libs []string
+
+ // List of files to remove from the jar file(s)
+ Exclude_files []string
+
+ // List of directories to remove from the jar file(s)
+ Exclude_dirs []string
+
+ // if set to true, run Jetifier against .jar file. Defaults to false.
+ Jetifier_enabled *bool
}
type Import struct {
android.ModuleBase
+ android.DefaultableModuleBase
prebuilt android.Prebuilt
properties ImportProperties
- classpathFiles android.Paths
combinedClasspathFile android.Path
+ exportedSdkLibs []string
+}
+
+func (j *Import) sdkVersion() string {
+ return String(j.properties.Sdk_version)
+}
+
+func (j *Import) minSdkVersion() string {
+ return j.sdkVersion()
}
func (j *Import) Prebuilt() *android.Prebuilt {
@@ -1221,30 +1751,97 @@ func (j *Import) Name() string {
}
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
+ android.ExtractSourcesDeps(ctx, j.properties.Jars)
+ ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
}
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars)
+ jars := ctx.ExpandSources(j.properties.Jars, nil)
- outputFile := android.PathForModuleOut(ctx, "classes.jar")
- TransformJarsToJar(ctx, outputFile, "for prebuilts", j.classpathFiles, android.OptionalPath{}, false, nil)
+ jarName := ctx.ModuleName() + ".jar"
+ outputFile := android.PathForModuleOut(ctx, "combined", jarName)
+ TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
+ false, j.properties.Exclude_files, j.properties.Exclude_dirs)
+ if Bool(j.properties.Jetifier_enabled) {
+ inputFile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "jetifier", jarName)
+ TransformJetifier(ctx, outputFile, inputFile)
+ }
j.combinedClasspathFile = outputFile
+
+ ctx.VisitDirectDeps(func(module android.Module) {
+ otherName := ctx.OtherModuleName(module)
+ tag := ctx.OtherModuleDependencyTag(module)
+
+ switch dep := module.(type) {
+ case Dependency:
+ switch tag {
+ case libTag, staticLibTag:
+ // sdk lib names from dependencies are re-exported
+ j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
+ }
+ case SdkLibraryDependency:
+ switch tag {
+ case libTag:
+ // names of sdk libs that are directly depended are exported
+ j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
+ }
+ }
+ })
+
+ j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
+ if Bool(j.properties.Installable) {
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
+ ctx.ModuleName()+".jar", outputFile)
+ }
}
var _ Dependency = (*Import)(nil)
func (j *Import) HeaderJars() android.Paths {
- return j.classpathFiles
+ return android.Paths{j.combinedClasspathFile}
}
func (j *Import) ImplementationJars() android.Paths {
- return j.classpathFiles
+ 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
}
+func (j *Import) ExportedSdkLibs() []string {
+ return j.exportedSdkLibs
+}
+
+// Collect information for opening IDE project files in java/jdeps.go.
+const (
+ removedPrefix = "prebuilt_"
+)
+
+func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
+ dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
+}
+
+func (j *Import) IDECustomizedModuleName() string {
+ // TODO(b/113562217): Extract the base module name from the Import name, often the Import name
+ // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
+ // solution to get the Import name.
+ name := j.Name()
+ if strings.HasPrefix(name, removedPrefix) {
+ name = strings.TrimPrefix(name, removedPrefix)
+ }
+ return name
+}
+
var _ android.PrebuiltInterface = (*Import)(nil)
func ImportFactory() android.Module {
@@ -1253,7 +1850,7 @@ func ImportFactory() android.Module {
module.AddProperties(&module.properties)
android.InitPrebuiltModule(module, &module.properties.Jars)
- android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+ InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
@@ -1263,7 +1860,7 @@ func ImportFactoryHost() android.Module {
module.AddProperties(&module.properties)
android.InitPrebuiltModule(module, &module.properties.Jars)
- android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+ InitJavaModule(module, android.HostSupported)
return module
}
@@ -1293,6 +1890,13 @@ func DefaultsFactory(props ...interface{}) android.Module {
&CompilerProperties{},
&CompilerDeviceProperties{},
&android.ProtoProperties{},
+ &aaptProperties{},
+ &androidLibraryProperties{},
+ &appProperties{},
+ &appTestProperties{},
+ &ImportProperties{},
+ &AARImportProperties{},
+ &sdkLibraryProperties{},
)
android.InitDefaultsModule(module)
@@ -1301,5 +1905,6 @@ func DefaultsFactory(props ...interface{}) android.Module {
}
var Bool = proptools.Bool
+var BoolDefault = proptools.BoolDefault
var String = proptools.String
var inList = android.InList