summaryrefslogtreecommitdiff
path: root/java/java.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java.go')
-rw-r--r--java/java.go1407
1 files changed, 1084 insertions, 323 deletions
diff --git a/java/java.go b/java/java.go
index 9ac38c92c..69826eec3 100644
--- a/java/java.go
+++ b/java/java.go
@@ -25,6 +25,7 @@ import (
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -33,23 +34,100 @@ import (
)
func init() {
- android.RegisterModuleType("java_defaults", defaultsFactory)
+ RegisterJavaBuildComponents(android.InitRegistrationContext)
+
+ // Register sdk member types.
+ android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
+
+ android.RegisterSdkMemberType(&librarySdkMemberType{
+ android.SdkMemberTypeBase{
+ PropertyName: "java_libs",
+ },
+ func(j *Library) android.Path {
+ implementationJars := j.ImplementationJars()
+ if len(implementationJars) != 1 {
+ panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name()))
+ }
+
+ return implementationJars[0]
+ },
+ })
+
+ android.RegisterSdkMemberType(&testSdkMemberType{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
+ PropertyName: "java_tests",
+ },
+ })
+}
+
+func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("java_defaults", DefaultsFactory)
+
+ ctx.RegisterModuleType("java_library", LibraryFactory)
+ ctx.RegisterModuleType("java_library_static", LibraryStaticFactory)
+ ctx.RegisterModuleType("java_library_host", LibraryHostFactory)
+ ctx.RegisterModuleType("java_binary", BinaryFactory)
+ ctx.RegisterModuleType("java_binary_host", BinaryHostFactory)
+ ctx.RegisterModuleType("java_test", TestFactory)
+ ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory)
+ ctx.RegisterModuleType("java_test_host", TestHostFactory)
+ ctx.RegisterModuleType("java_test_import", JavaTestImportFactory)
+ ctx.RegisterModuleType("java_import", ImportFactory)
+ ctx.RegisterModuleType("java_import_host", ImportFactoryHost)
+ ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
+ 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 (j *Module) CheckStableSdkVersion() error {
+ sdkVersion := j.sdkVersion()
+ if sdkVersion.stable() {
+ return nil
+ }
+ return fmt.Errorf("non stable SDK %v", sdkVersion)
+}
+
+func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
+ if j.RequiresStableAPIs(ctx) {
+ if sc, ok := ctx.Module().(sdkContext); ok {
+ if !sc.sdkVersion().specified() {
+ ctx.PropertyErrorf("sdk_version",
+ "sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).")
+ }
+ }
+ }
+
+ ctx.VisitDirectDeps(func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
+ switch module.(type) {
+ // TODO(satayev): cover other types as well, e.g. imports
+ case *Library, *AndroidLibrary:
+ switch tag {
+ case bootClasspathTag, libTag, staticLibTag, java9LibTag:
+ checkLinkType(ctx, j, module.(linkTypeContext), tag.(dependencyTag))
+ }
+ }
+ })
+}
- android.RegisterModuleType("java_library", LibraryFactory)
- android.RegisterModuleType("java_library_static", LibraryStaticFactory)
- 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_helper_library", TestHelperLibraryFactory)
- android.RegisterModuleType("java_test_host", TestHostFactory)
- android.RegisterModuleType("java_import", ImportFactory)
- android.RegisterModuleType("java_import_host", ImportFactoryHost)
- android.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
- android.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
- android.RegisterModuleType("dex_import", DexImportFactory)
+func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
+ if sc, ok := ctx.Module().(sdkContext); ok {
+ usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
+ sdkVersionSpecified := sc.sdkVersion().specified()
+ if usePlatformAPI && sdkVersionSpecified {
+ ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.")
+ } else if !usePlatformAPI && !sdkVersionSpecified {
+ ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.")
+ }
- android.RegisterSingletonType("logtags", LogtagsSingleton)
+ }
}
// TODO:
@@ -82,13 +160,6 @@ type CompilerProperties struct {
// list of files that should be excluded from java_resources and java_resource_dirs
Exclude_java_resources []string `android:"path,arch_variant"`
- // don't build against the default libraries (bootclasspath, ext, and framework for device
- // targets)
- No_standard_libs *bool
-
- // don't build against the framework libraries (ext, and framework for device targets)
- No_framework_libs *bool
-
// list of module-specific flags that will be used for javac compiles
Javacflags []string `android:"arch_variant"`
@@ -124,6 +195,9 @@ type CompilerProperties struct {
// List of modules to use as annotation processors
Plugins []string
+ // List of modules to export to libraries that directly depend on this library as annotation processors
+ Exported_plugins []string
+
// The number of Java source entries each Javac instance can process
Javac_shard_size *int64
@@ -131,10 +205,10 @@ type CompilerProperties struct {
Use_tools_jar *bool
Openjdk9 struct {
- // List of source files that should only be used when passing -source 1.9
+ // List of source files that should only be used when passing -source 1.9 or higher
Srcs []string `android:"path"`
- // List of javac flags that should only be used when passing -source 1.9
+ // List of javac flags that should only be used when passing -source 1.9 or higher
Javacflags []string
}
@@ -179,14 +253,17 @@ type CompilerProperties struct {
// List of files to include in the META-INF/services folder of the resulting jar.
Services []string `android:"path,arch_variant"`
+
+ // If true, package the kotlin stdlib into the jar. Defaults to true.
+ Static_kotlin_stdlib *bool `android:"arch_variant"`
}
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. Defaults to compiling against the current
- // sdk if platform_apis is not set.
+ // if not blank, set to the version of the sdk to compile against.
+ // Defaults to compiling against the current platform.
Sdk_version *string
// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
@@ -197,7 +274,9 @@ type CompilerDeviceProperties struct {
// Defaults to sdk_version if not set.
Target_sdk_version *string
- // if true, compile against the platform APIs instead of an SDK.
+ // Whether to compile against the platform APIs instead of an SDK.
+ // If true, then sdk_version must be empty. The value of this field
+ // is ignored when module's type isn't android_app.
Platform_apis *bool
Aidl struct {
@@ -259,21 +338,71 @@ type CompilerDeviceProperties struct {
Proguard_flags_files []string `android:"path"`
}
- // When targeting 1.9, override the modules to use with --system
+ // When targeting 1.9 and above, override the modules to use with --system,
+ // otherwise provides defaults libraries to add to the bootclasspath.
System_modules *string
- UncompressDex bool `blueprint:"mutated"`
- IsSDKLibrary bool `blueprint:"mutated"`
+ // The name of the module as used in build configuration.
+ //
+ // Allows a library to separate its actual name from the name used in
+ // build configuration, e.g.ctx.Config().BootJars().
+ ConfigurationName *string `blueprint:"mutated"`
+
+ // set the name of the output
+ Stem *string
+
+ // Keep the data uncompressed. We always need uncompressed dex for execution,
+ // so this might actually save space by avoiding storing the same data twice.
+ // This defaults to reasonable value based on module and should not be set.
+ // It exists only to support ART tests.
+ Uncompress_dex *bool
+
+ IsSDKLibrary bool `blueprint:"mutated"`
+
+ // If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
+ // Defaults to false.
+ V4_signature *bool
}
func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
return BoolDefault(me.Optimize.Enabled, me.Optimize.EnabledByDefault)
}
+// Functionality common to Module and Import
+//
+// It is embedded in Module so its functionality can be used by methods in Module
+// but it is currently only initialized by Import and Library.
+type embeddableInModuleAndImport struct {
+
+ // Functionality related to this being used as a component of a java_sdk_library.
+ EmbeddableSdkLibraryComponent
+}
+
+func (e *embeddableInModuleAndImport) initModuleAndImport(moduleBase *android.ModuleBase) {
+ e.initSdkLibraryComponent(moduleBase)
+}
+
+// Module/Import's DepIsInSameApex(...) delegates to this method.
+//
+// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with
+// the one provided by ApexModuleBase.
+func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+ // dependencies other than the static linkage are all considered crossing APEX boundary
+ if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
+ return true
+ }
+ return false
+}
+
// Module contains the properties and members used by all java module types
type Module struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.ApexModuleBase
+ android.SdkBase
+
+ // Functionality common to Module and Import.
+ embeddableInModuleAndImport
properties CompilerProperties
protoProperties android.ProtoProperties
@@ -290,6 +419,10 @@ type Module struct {
// jar file containing only resources including from static library dependencies
resourceJar android.Path
+ // args and dependencies to package source files into a srcjar
+ srcJarArgs []string
+ srcJarDeps android.Paths
+
// jar file containing implementation classes and resources including static library
// dependencies
implementationAndResourcesJar android.Path
@@ -327,11 +460,17 @@ type Module struct {
// manifest file to use instead of properties.Manifest
overrideManifest android.OptionalPath
- // list of SDK lib names that this java moudule is exporting
+ // list of SDK lib names that this java module is exporting
exportedSdkLibs []string
- // list of source files, collected from compiledJavaSrcs and compiledSrcJars
- // filter out Exclude_srcs, will be used by android.IDEInfo struct
+ // list of plugins that this java module is exporting
+ exportedPluginJars android.Paths
+
+ // list of plugins that this java module is exporting
+ exportedPluginClasses []string
+
+ // list of source files, collected from srcFiles with unique java and all kt files,
+ // will be used by android.IDEInfo struct
expandIDEInfoCompiledSrcs []string
// expanded Jarjar_rules
@@ -340,50 +479,77 @@ type Module struct {
// list of additional targets for checkbuild
additionalCheckedModules android.Paths
+ // Extra files generated by the module type to be added as java resources.
+ extraResources android.Paths
+
hiddenAPI
dexpreopter
+ linter
+
+ // list of the xref extraction files
+ kytheFiles android.Paths
+
+ distFile android.Path
}
-func (j *Module) Srcs() android.Paths {
- return append(android.Paths{j.outputFile}, j.extraOutputFiles...)
+func (j *Module) addHostProperties() {
+ j.AddProperties(
+ &j.properties,
+ &j.protoProperties,
+ )
}
-func (j *Module) DexJarFile() android.Path {
- return j.dexJarFile
+func (j *Module) addHostAndDeviceProperties() {
+ j.addHostProperties()
+ j.AddProperties(
+ &j.deviceProperties,
+ &j.dexpreoptProperties,
+ &j.linter.properties,
+ )
+}
+
+func (j *Module) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
+ case ".jar":
+ return android.Paths{j.implementationAndResourcesJar}, nil
+ case ".proguard_map":
+ return android.Paths{j.proguardDictionary}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
}
-var _ android.SourceFileProducer = (*Module)(nil)
+var _ android.OutputFileProducer = (*Module)(nil)
-type Dependency interface {
+// Methods that need to be implemented for a module that is added to apex java_libs property.
+type ApexDependency interface {
HeaderJars() android.Paths
+ ImplementationAndResourcesJars() android.Paths
+}
+
+type Dependency interface {
+ ApexDependency
ImplementationJars() android.Paths
ResourceJars() android.Paths
- ImplementationAndResourcesJars() android.Paths
DexJar() android.Path
AidlIncludeDirs() android.Paths
ExportedSdkLibs() []string
+ ExportedPlugins() (android.Paths, []string)
+ SrcJarArgs() ([]string, android.Paths)
+ BaseModuleName() string
+ JacocoReportClassesFile() android.Path
}
-type SdkLibraryDependency interface {
- SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths
- SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths
-}
-
-type SrcDependency interface {
- CompiledSrcs() android.Paths
- CompiledSrcJars() android.Paths
-}
-
-func (j *Module) CompiledSrcs() android.Paths {
- return j.compiledJavaSrcs
+type xref interface {
+ XrefJavaFiles() android.Paths
}
-func (j *Module) CompiledSrcJars() android.Paths {
- return j.compiledSrcJars
+func (j *Module) XrefJavaFiles() android.Paths {
+ return j.kytheFiles
}
-var _ SrcDependency = (*Module)(nil)
-
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
android.InitAndroidArchModule(module, hod, android.MultilibCommon)
android.InitDefaultableModule(module)
@@ -396,110 +562,178 @@ type dependencyTag struct {
type jniDependencyTag struct {
blueprint.BaseDependencyTag
- target android.Target
+}
+
+func IsJniDepTag(depTag blueprint.DependencyTag) bool {
+ _, ok := depTag.(*jniDependencyTag)
+ return ok
}
var (
staticLibTag = dependencyTag{name: "staticlib"}
libTag = dependencyTag{name: "javalib"}
+ java9LibTag = dependencyTag{name: "java9lib"}
pluginTag = dependencyTag{name: "plugin"}
+ exportedPluginTag = dependencyTag{name: "exported-plugin"}
bootClasspathTag = dependencyTag{name: "bootclasspath"}
systemModulesTag = dependencyTag{name: "system modules"}
frameworkResTag = dependencyTag{name: "framework-res"}
- frameworkApkTag = dependencyTag{name: "framework-apk"}
kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"}
kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations"}
proguardRaiseTag = dependencyTag{name: "proguard-raise"}
certificateTag = dependencyTag{name: "certificate"}
instrumentationForTag = dependencyTag{name: "instrumentation_for"}
+ usesLibTag = dependencyTag{name: "uses-library"}
+ extraLintCheckTag = dependencyTag{name: "extra-lint-check"}
)
+func IsLibDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == libTag
+}
+
+func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == staticLibTag
+}
+
type sdkDep struct {
useModule, useFiles, useDefaultLibs, invalidVersion bool
- modules []string
+ // The modules that will be added to the bootclasspath when targeting 1.8 or lower
+ bootclasspath []string
+
+ // The default system modules to use. Will be an empty string if no system
+ // modules are to be used.
systemModules string
+ // The modules that will be added ot the classpath when targeting 1.9 or higher
+ java9Classpath []string
+
frameworkResModule string
jars android.Paths
aidl android.OptionalPath
+
+ noStandardLibs, noFrameworksLibs bool
+}
+
+func (s sdkDep) hasStandardLibs() bool {
+ return !s.noStandardLibs
+}
+
+func (s sdkDep) hasFrameworkLibs() bool {
+ return !s.noStandardLibs && !s.noFrameworksLibs
}
type jniLib struct {
- name string
- path android.Path
- target android.Target
+ name string
+ path android.Path
+ target android.Target
+ coverageFile android.OptionalPath
+ unstrippedFile android.Path
}
-func (j *Module) shouldInstrument(ctx android.BaseContext) bool {
- return j.properties.Instrument && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
+func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
+ return j.properties.Instrument &&
+ ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
+ ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
}
-func (j *Module) shouldInstrumentStatic(ctx android.BaseContext) bool {
+func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
return j.shouldInstrument(ctx) &&
(ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") ||
ctx.Config().UnbundledBuild())
}
-func (j *Module) sdkVersion() string {
- return String(j.deviceProperties.Sdk_version)
+func (j *Module) sdkVersion() sdkSpec {
+ return sdkSpecFrom(String(j.deviceProperties.Sdk_version))
+}
+
+func (j *Module) systemModules() string {
+ return proptools.String(j.deviceProperties.System_modules)
}
-func (j *Module) minSdkVersion() string {
+func (j *Module) minSdkVersion() sdkSpec {
if j.deviceProperties.Min_sdk_version != nil {
- return *j.deviceProperties.Min_sdk_version
+ return sdkSpecFrom(*j.deviceProperties.Min_sdk_version)
}
return j.sdkVersion()
}
-func (j *Module) targetSdkVersion() string {
+func (j *Module) targetSdkVersion() sdkSpec {
if j.deviceProperties.Target_sdk_version != nil {
- return *j.deviceProperties.Target_sdk_version
+ return sdkSpecFrom(*j.deviceProperties.Target_sdk_version)
}
return j.sdkVersion()
}
+func (j *Module) MinSdkVersion() string {
+ return j.minSdkVersion().version.String()
+}
+
+func (j *Module) AvailableFor(what string) bool {
+ if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) {
+ // Exception: for hostdex: true libraries, the platform variant is created
+ // even if it's not marked as available to platform. In that case, the platform
+ // variant is used only for the hostdex and not installed to the device.
+ return true
+ }
+ return j.ApexModuleBase.AvailableFor(what)
+}
+
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
- if !Bool(j.properties.No_standard_libs) {
- sdkDep := decodeSdkDep(ctx, sdkContext(j))
- if sdkDep.useDefaultLibs {
- 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 {
- ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
- ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
- if j.deviceProperties.EffectiveOptimizeEnabled() {
- ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...)
- ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...)
- }
+ j.linter.deps(ctx)
+
+ sdkDep := decodeSdkDep(ctx, sdkContext(j))
+ if sdkDep.useDefaultLibs {
+ ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
+ ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
+ if sdkDep.hasFrameworkLibs() {
+ ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
+ }
+ } else if sdkDep.useModule {
+ ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
+ ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
+ if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasStandardLibs() {
+ 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.AddVariationDependencies(nil, systemModulesTag, *j.deviceProperties.System_modules)
}
- if (ctx.ModuleName() == "framework") || (ctx.ModuleName() == "framework-annotation-proc") {
- ctx.AddVariationDependencies(nil, frameworkResTag, "framework-res")
+ if sdkDep.systemModules != "" {
+ ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
}
- if ctx.ModuleName() == "android_stubs_current" ||
- ctx.ModuleName() == "android_system_stubs_current" ||
- ctx.ModuleName() == "android_test_stubs_current" {
- ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res")
+ }
+
+ syspropPublicStubs := syspropPublicStubs(ctx.Config())
+
+ // rewriteSyspropLibs validates if a java module can link against platform's sysprop_library,
+ // and redirects dependency to public stub depending on the link type.
+ rewriteSyspropLibs := func(libs []string, prop string) []string {
+ // make a copy
+ ret := android.CopyOf(libs)
+
+ for idx, lib := range libs {
+ stub, ok := syspropPublicStubs[lib]
+
+ if !ok {
+ continue
+ }
+
+ linkType, _ := j.getLinkType(ctx.ModuleName())
+ // only platform modules can use internal props
+ if linkType != javaPlatform {
+ ret[idx] = stub
+ }
}
+
+ return ret
}
- ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
- ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...)
+ ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...)
+ ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...)
- ctx.AddFarVariationDependencies([]blueprint.Variation{
- {Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant},
- }, pluginTag, j.properties.Plugins...)
+ ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
+ ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
android.ProtoDeps(ctx, &j.protoProperties)
if j.hasSrcExt(".proto") {
@@ -509,13 +743,21 @@ 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.AddVariationDependencies(nil, kotlinStdlibTag, "kotlin-stdlib")
+ ctx.AddVariationDependencies(nil, kotlinStdlibTag,
+ "kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8")
if len(j.properties.Plugins) > 0 {
ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations")
}
}
- if j.shouldInstrumentStatic(ctx) {
+ // Framework libraries need special handling in static coverage builds: they should not have
+ // static dependency on jacoco, otherwise there would be multiple conflicting definitions of
+ // the same jacoco classes coming from different bootclasspath jars.
+ if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
+ if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ j.properties.Instrument = true
+ }
+ } else if j.shouldInstrumentStatic(ctx) {
ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
}
@@ -579,6 +821,7 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt
type deps struct {
classpath classpath
+ java9Classpath classpath
bootClasspath classpath
processorPath classpath
processorClasses []string
@@ -588,7 +831,7 @@ type deps struct {
aidlIncludeDirs android.Paths
srcs android.Paths
srcJars android.Paths
- systemModules android.Path
+ systemModules *systemModules
aidlPreprocess android.OptionalPath
kotlinStdlib android.Paths
kotlinAnnotations android.Paths
@@ -608,53 +851,74 @@ 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
)
-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":
+type linkTypeContext interface {
+ android.Module
+ getLinkType(name string) (ret linkType, stubs bool)
+}
+
+func (m *Module) getLinkType(name string) (ret linkType, stubs bool) {
+ switch name {
+ case "core.current.stubs", "core.platform.api.stubs", "stub-annotations",
+ "private-stub-annotations-jar", "core-lambda-stubs", "core-generated-annotation-stubs":
return javaCore, true
- case ver == "core_current":
- return javaCore, false
- case name == "android_system_stubs_current":
+ case "android_stubs_current":
+ return javaSdk, true
+ case "android_system_stubs_current":
return javaSystem, true
- case strings.HasPrefix(ver, "system_"):
- return javaSystem, false
- case name == "android_test_stubs_current":
+ case "android_module_lib_stubs_current":
+ return javaModule, true
+ case "android_system_server_stubs_current":
+ return javaSystemServer, true
+ case "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":
+ }
+
+ if stub, linkType := moduleStubLinkType(name); stub {
+ return linkType, true
+ }
+
+ ver := m.sdkVersion()
+ switch ver.kind {
+ case sdkCore:
+ return javaCore, false
+ case sdkSystem:
+ return javaSystem, false
+ case sdkPublic:
return javaSdk, false
- case ver == "":
+ case sdkModule:
+ return javaModule, false
+ case sdkSystemServer:
+ return javaSystemServer, false
+ case sdkPrivate, sdkNone, sdkCorePlatform, sdkTest:
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
}
+
+ if !ver.valid() {
+ panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
+ }
+ return javaSdk, false
}
-func checkLinkType(ctx android.ModuleContext, from *Module, to *Library, tag dependencyTag) {
+func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, tag dependencyTag) {
if ctx.Host() {
return
}
- myLinkType, stubs := getLinkType(from, ctx.ModuleName())
+ myLinkType, stubs := from.getLinkType(ctx.ModuleName())
if stubs {
return
}
- otherLinkType, _ := getLinkType(&to.Module, ctx.OtherModuleName(to))
+ otherLinkType, _ := to.getLinkType(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 {
@@ -671,11 +935,23 @@ func checkLinkType(ctx android.ModuleContext, from *Module, to *Library, tag dep
}
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
@@ -688,7 +964,8 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, sdkContext(j))
if sdkDep.invalidVersion {
- ctx.AddMissingDependencies(sdkDep.modules)
+ ctx.AddMissingDependencies(sdkDep.bootclasspath)
+ ctx.AddMissingDependencies(sdkDep.java9Classpath)
} else if sdkDep.useFiles {
// sdkDep.jar is actually equivalent to turbine header.jar.
deps.classpath = append(deps.classpath, sdkDep.jars...)
@@ -698,6 +975,12 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
}
+ // If this is a component library (stubs, etc.) for a java_sdk_library then
+ // add the name of that java_sdk_library to the exported sdk libs to make sure
+ // that, if necessary, a <uses-library> element for that java_sdk_library is
+ // added to the Android manifest.
+ j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
+
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -711,20 +994,14 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
return
}
- if to, ok := module.(*Library); ok {
- switch tag {
- case bootClasspathTag, libTag, staticLibTag:
- checkLinkType(ctx, j, to, tag.(dependencyTag))
- }
- }
switch dep := module.(type) {
case SdkLibraryDependency:
switch tag {
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
- j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
- default:
+ j.exportedSdkLibs = append(j.exportedSdkLibs, dep.OptionalImplicitSdkLibrary()...)
+ case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
}
case Dependency:
@@ -736,6 +1013,10 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// sdk lib names from dependencies are re-exported
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
+ pluginJars, pluginClasses := dep.ExportedPlugins()
+ addPlugins(&deps, pluginJars, pluginClasses...)
+ case java9LibTag:
+ deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
case staticLibTag:
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
@@ -744,36 +1025,33 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// sdk lib names from dependencies are re-exported
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
+ pluginJars, pluginClasses := dep.ExportedPlugins()
+ addPlugins(&deps, pluginJars, pluginClasses...)
case pluginTag:
if plugin, ok := dep.(*Plugin); ok {
- deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
if plugin.pluginProperties.Processor_class != nil {
- deps.processorClasses = append(deps.processorClasses, *plugin.pluginProperties.Processor_class)
+ addPlugins(&deps, plugin.ImplementationAndResourcesJars(), *plugin.pluginProperties.Processor_class)
+ } else {
+ addPlugins(&deps, plugin.ImplementationAndResourcesJars())
}
deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api)
} else {
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
- case frameworkResTag:
- 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 exportedPluginTag:
+ if plugin, ok := dep.(*Plugin); ok {
+ if plugin.pluginProperties.Generates_api != nil && *plugin.pluginProperties.Generates_api {
+ ctx.PropertyErrorf("exported_plugins", "Cannot export plugins with generates_api = true, found %v", otherName)
+ }
+ j.exportedPluginJars = append(j.exportedPluginJars, plugin.ImplementationAndResourcesJars()...)
+ if plugin.pluginProperties.Processor_class != nil {
+ j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
+ }
+ } else {
+ ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
}
case kotlinStdlibTag:
- deps.kotlinStdlib = dep.HeaderJars()
+ deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...)
case kotlinAnnotationsTag:
deps.kotlinAnnotations = dep.HeaderJars()
}
@@ -791,19 +1069,19 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
default:
switch tag {
- case android.DefaultsDepTag, android.SourceDepTag:
- // Nothing to do
+ case bootClasspathTag:
+ // If a system modules dependency has been added to the bootclasspath
+ // then add its libs to the bootclasspath.
+ 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.outputFile == nil {
- panic("Missing directory for system module dependency")
- }
- deps.systemModules = sm.outputFile
- default:
- ctx.ModuleErrorf("depends on non-java module %q", otherName)
+ sm := module.(SystemModulesProvider)
+ outputDir, outputDeps := sm.OutputDirAndDeps()
+ deps.systemModules = &systemModules{outputDir, outputDeps}
}
}
})
@@ -813,37 +1091,68 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
return deps
}
-func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string {
- var ret string
- v := sdkContext.sdkVersion()
- // For PDK builds, use the latest SDK version instead of "current"
- if ctx.Config().IsPdkBuild() && (v == "" || v == "current") {
- sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
- latestSdkVersion := 0
- if len(sdkVersions) > 0 {
- latestSdkVersion = sdkVersions[len(sdkVersions)-1]
- }
- v = strconv.Itoa(latestSdkVersion)
- }
+func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
+ deps.processorPath = append(deps.processorPath, pluginJars...)
+ deps.processorClasses = append(deps.processorClasses, pluginClasses...)
+}
- sdk, err := sdkVersionToNumber(ctx, v)
- if err != nil {
- ctx.PropertyErrorf("sdk_version", "%s", err)
- }
+func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion {
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"
+ return normalizeJavaVersion(ctx, javaVersion)
+ } else if ctx.Device() {
+ return sdkContext.sdkVersion().defaultJavaLanguageVersion(ctx)
} else {
- ret = "1.9"
+ return JAVA_VERSION_9
}
+}
+
+type javaVersion int
+
+const (
+ JAVA_VERSION_UNSUPPORTED = 0
+ JAVA_VERSION_6 = 6
+ JAVA_VERSION_7 = 7
+ JAVA_VERSION_8 = 8
+ JAVA_VERSION_9 = 9
+)
- return ret
+func (v javaVersion) String() string {
+ switch v {
+ case JAVA_VERSION_6:
+ return "1.6"
+ case JAVA_VERSION_7:
+ return "1.7"
+ case JAVA_VERSION_8:
+ return "1.8"
+ case JAVA_VERSION_9:
+ return "1.9"
+ default:
+ return "unsupported"
+ }
+}
+
+// Returns true if javac targeting this version uses system modules instead of a bootclasspath.
+func (v javaVersion) usesJavaModules() bool {
+ return v >= 9
+}
+
+func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion {
+ switch javaVersion {
+ case "1.6", "6":
+ return JAVA_VERSION_6
+ case "1.7", "7":
+ return JAVA_VERSION_7
+ case "1.8", "8":
+ return JAVA_VERSION_8
+ case "1.9", "9":
+ return JAVA_VERSION_9
+ case "10", "11":
+ ctx.PropertyErrorf("java_version", "Java language levels above 9 are not supported")
+ return JAVA_VERSION_UNSUPPORTED
+ default:
+ ctx.PropertyErrorf("java_version", "Unrecognized Java language level")
+ return JAVA_VERSION_UNSUPPORTED
+ }
}
func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
@@ -855,7 +1164,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
// javac flags.
javacFlags := j.properties.Javacflags
- if flags.javaVersion == "1.9" {
+ if flags.javaVersion.usesJavaModules() {
javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
}
if ctx.Config().MinimizeJavaDebugInfo() {
@@ -863,6 +1172,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
// disk and memory usage.
javacFlags = append(javacFlags, "-g:source,lines")
}
+ javacFlags = append(javacFlags, "-Xlint:-dep-ann")
if ctx.Config().RunErrorProne() {
if config.ErrorProneClasspath == nil {
@@ -883,13 +1193,14 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
// classpath
flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)
flags.classpath = append(flags.classpath, deps.classpath...)
+ flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...)
flags.processorPath = append(flags.processorPath, deps.processorPath...)
- flags.processor = strings.Join(deps.processorClasses, ",")
+ flags.processors = append(flags.processors, deps.processorClasses...)
+ flags.processors = android.FirstUniqueStrings(flags.processors)
- 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"}) {
+ if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() &&
+ decodeSdkDep(ctx, sdkContext(j)).hasStandardLibs() {
// Give host-side tools a version of OpenJDK's standard libraries
// close to what they're targeting. As of Dec 2017, AOSP is only
// bundling OpenJDK 8 and 9, so nothing < 8 is available.
@@ -913,7 +1224,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
}
}
- if j.properties.Patch_module != nil && flags.javaVersion == "1.9" {
+ if j.properties.Patch_module != nil && flags.javaVersion.usesJavaModules() {
// Manually specify build directory in case it is not under the repo root.
// (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so
// just adding a symlink under the root doesn't help.)
@@ -926,9 +1237,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
}
// systemModules
- if deps.systemModules != nil {
- flags.systemModules = append(flags.systemModules, deps.systemModules)
- }
+ flags.systemModules = deps.systemModules
// aidl flags.
flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
@@ -942,14 +1251,13 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB
return flags
}
-func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path) {
-
+func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
deps := j.collectDeps(ctx)
flags := j.collectBuilderFlags(ctx, deps)
- if flags.javaVersion == "1.9" {
+ if flags.javaVersion.usesJavaModules() {
j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
}
srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
@@ -961,11 +1269,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
srcJars := srcFiles.FilterByExt(".srcjar")
srcJars = append(srcJars, deps.srcJars...)
- srcJars = append(srcJars, extraSrcJars...)
-
- // Collect source files from compiledJavaSrcs, compiledSrcJars and filter out Exclude_srcs
- // that IDEInfo struct will use
- j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...)
+ if aaptSrcJar != nil {
+ srcJars = append(srcJars, aaptSrcJar)
+ }
if j.properties.Jarjar_rules != nil {
j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
@@ -983,6 +1289,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
}
}
+ // Collect .java files for AIDEGen
+ j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
+
var kotlinJars android.Paths
if srcFiles.HasExt(".kt") {
@@ -1007,6 +1316,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...)
kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...)
+ // Collect .kt files for AIDEGen
+ j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...)
+
flags.classpath = append(flags.classpath, deps.kotlinStdlib...)
flags.classpath = append(flags.classpath, deps.kotlinAnnotations...)
@@ -1016,11 +1328,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
if len(flags.processorPath) > 0 {
// Use kapt for annotation processing
kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar")
- kotlinKapt(ctx, kaptSrcJar, kotlinSrcFiles, srcJars, flags)
+ kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
+ kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, srcJars, flags)
srcJars = append(srcJars, kaptSrcJar)
+ kotlinJars = append(kotlinJars, kaptResJar)
// Disable annotation processing in javac, it's already been handled by kapt
flags.processorPath = nil
- flags.processor = ""
+ flags.processors = nil
}
kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
@@ -1032,9 +1346,11 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
// Make javac rule depend on the kotlinc rule
flags.classpath = append(flags.classpath, kotlinJar)
- // Jar kotlin classes into the final jar after javac
kotlinJars = append(kotlinJars, kotlinJar)
- kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
+ // Jar kotlin classes into the final jar after javac
+ if BoolDefault(j.properties.Static_kotlin_stdlib, true) {
+ kotlinJars = append(kotlinJars, deps.kotlinStdlib...)
+ }
}
jars := append(android.Paths(nil), kotlinJars...)
@@ -1044,6 +1360,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...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
@@ -1053,7 +1370,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...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
}
@@ -1072,25 +1390,24 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...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 {
shardSrcs = android.ShardPaths(uniqueSrcFiles, shardSize)
for idx, shardSrc := range shardSrcs {
- classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(idx))
- TransformJavaToClasses(ctx, classes, idx, shardSrc, nil, flags, extraJarDeps)
+ classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
+ nil, flags, extraJarDeps)
jars = append(jars, classes)
}
}
if len(srcJars) > 0 {
- classes := android.PathForModuleOut(ctx, "javac", jarName+strconv.Itoa(len(shardSrcs)))
- TransformJavaToClasses(ctx, classes, len(shardSrcs), nil, srcJars, flags, extraJarDeps)
+ classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs),
+ nil, srcJars, flags, extraJarDeps)
jars = append(jars, classes)
}
} else {
- classes := android.PathForModuleOut(ctx, "javac", jarName)
- TransformJavaToClasses(ctx, classes, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
+ classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
jars = append(jars, classes)
}
if ctx.Failed() {
@@ -1098,9 +1415,18 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
}
}
+ j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
+
+ var includeSrcJar android.WritablePath
+ if Bool(j.properties.Include_srcs) {
+ includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar")
+ TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps)
+ }
+
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)
+ extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources
var resArgs []string
var resDeps android.Paths
@@ -1111,11 +1437,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
resArgs = append(resArgs, fileArgs...)
resDeps = append(resDeps, fileDeps...)
- 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...)
- }
+ resArgs = append(resArgs, extraArgs...)
+ resDeps = append(resDeps, extraDeps...)
if len(resArgs) > 0 {
resourceJar := android.PathForModuleOut(ctx, "res", jarName)
@@ -1126,20 +1449,27 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
}
}
- if len(deps.staticResourceJars) > 0 {
- var jars android.Paths
- if j.resourceJar != nil {
- jars = append(jars, j.resourceJar)
- }
- jars = append(jars, deps.staticResourceJars...)
+ var resourceJars android.Paths
+ if j.resourceJar != nil {
+ resourceJars = append(resourceJars, j.resourceJar)
+ }
+ if Bool(j.properties.Include_srcs) {
+ resourceJars = append(resourceJars, includeSrcJar)
+ }
+ resourceJars = append(resourceJars, deps.staticResourceJars...)
+ if len(resourceJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
- TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
+ TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
false, nil, nil)
j.resourceJar = combinedJar
+ } else if len(resourceJars) == 1 {
+ j.resourceJar = resourceJars[0]
}
- jars = append(jars, deps.staticJars...)
+ if len(deps.staticJars) > 0 {
+ jars = append(jars, deps.staticJars...)
+ }
manifest := j.overrideManifest
if !manifest.Valid() && j.properties.Manifest != nil {
@@ -1154,13 +1484,19 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
serviceFile := file.String()
zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
}
+ rule := zip
+ args := map[string]string{
+ "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
+ }
+ if ctx.Config().IsEnvTrue("RBE_ZIP") {
+ rule = zipRE
+ args["implicits"] = strings.Join(services.Strings(), ",")
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: zip,
+ Rule: rule,
Output: servicesJar,
Implicits: services,
- Args: map[string]string{
- "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
- },
+ Args: args,
})
jars = append(jars, servicesJar)
}
@@ -1228,10 +1564,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
j.headerJarFile = j.implementationJarFile
}
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
- j.properties.Instrument = true
- }
+ // 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) {
@@ -1241,16 +1579,27 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
// merge implementation jar with resources if necessary
implementationAndResourcesJar := outputFile
if j.resourceJar != nil {
- jars := android.Paths{implementationAndResourcesJar, j.resourceJar}
+ jars := android.Paths{j.resourceJar, implementationAndResourcesJar}
combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
- TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
+ TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest,
false, nil, nil)
implementationAndResourcesJar = combinedJar
}
j.implementationAndResourcesJar = implementationAndResourcesJar
- if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
+ // 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
var dexOutputFile android.ModuleOutPath
dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
@@ -1258,9 +1607,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
return
}
+ configurationName := j.ConfigurationName()
+ primary := configurationName == ctx.ModuleName()
+
// Hidden API CSV generation and dex encoding
- dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile,
- j.deviceProperties.UncompressDex)
+ dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile,
+ proptools.Bool(j.deviceProperties.Uncompress_dex))
// merge dex jar with resources if necessary
if j.resourceJar != nil {
@@ -1268,7 +1620,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
false, nil, nil)
- if j.deviceProperties.UncompressDex {
+ if *j.deviceProperties.Uncompress_dex {
combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
dexOutputFile = combinedAlignedJar
@@ -1293,12 +1645,58 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
outputFile = implementationAndResourcesJar
}
+ if ctx.Device() {
+ lintSDKVersionString := func(sdkSpec sdkSpec) string {
+ if v := sdkSpec.version; v.isNumbered() {
+ return v.String()
+ } else {
+ return ctx.Config().DefaultAppTargetSdk()
+ }
+ }
+
+ j.linter.name = ctx.ModuleName()
+ j.linter.srcs = srcFiles
+ j.linter.srcJars = srcJars
+ j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
+ j.linter.classes = j.implementationJarFile
+ j.linter.minSdkVersion = lintSDKVersionString(j.minSdkVersion())
+ j.linter.targetSdkVersion = lintSDKVersionString(j.targetSdkVersion())
+ j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion())
+ j.linter.javaLanguageLevel = flags.javaVersion.String()
+ j.linter.kotlinLanguageLevel = "1.3"
+ if j.ApexName() != "" && ctx.Config().UnbundledBuild() {
+ j.linter.buildModuleReportZip = true
+ }
+ j.linter.lint(ctx)
+ }
+
ctx.CheckbuildFile(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) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int,
+ srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath {
+
+ kzipName := pathtools.ReplaceExtension(jarName, "kzip")
+ if idx >= 0 {
+ kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip"
+ jarName += strconv.Itoa(idx)
+ }
+
+ classes := android.PathForModuleOut(ctx, "javac", jarName)
+ TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps)
+
+ if ctx.Config().EmitXrefRules() {
+ extractionFile := android.PathForModuleOut(ctx, kzipName)
+ emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps)
+ j.kytheFiles = append(j.kytheFiles, extractionFile)
+ }
+
+ return classes
+}
+
// 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) {
@@ -1325,7 +1723,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 {
@@ -1333,7 +1732,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)
}
@@ -1342,27 +1741,27 @@ 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
// 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, nil, []string{"META-INF"})
+ 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,
@@ -1424,6 +1823,14 @@ func (j *Module) ExportedSdkLibs() []string {
return j.exportedSdkLibs
}
+func (j *Module) ExportedPlugins() (android.Paths, []string) {
+ return j.exportedPluginJars, j.exportedPluginClasses
+}
+
+func (j *Module) SrcJarArgs() ([]string, android.Paths) {
+ return j.srcJarArgs, j.srcJarDeps
+}
+
var _ logtagsProducer = (*Module)(nil)
func (j *Module) logtags() android.Paths {
@@ -1434,6 +1841,7 @@ func (j *Module) logtags() android.Paths {
func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
+ dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
if j.expandJarjarRules != nil {
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
@@ -1447,15 +1855,67 @@ func (j *Module) CompilerDeps() []string {
return jdeps
}
+func (j *Module) hasCode(ctx android.ModuleContext) bool {
+ srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
+ return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
+}
+
+func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+ return j.depIsInSameApex(ctx, dep)
+}
+
+func (j *Module) Stem() string {
+ return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
+}
+
+func (j *Module) ConfigurationName() string {
+ return proptools.StringDefault(j.deviceProperties.ConfigurationName, j.BaseModuleName())
+}
+
+func (j *Module) JacocoReportClassesFile() android.Path {
+ return j.jacocoReportClassesFile
+}
+
+func (j *Module) IsInstallable() bool {
+ return Bool(j.properties.Installable)
+}
+
//
// Java libraries (.jar file)
//
+type LibraryProperties struct {
+ Dist struct {
+ // The tag of the output of this module that should be output.
+ Tag *string `android:"arch_variant"`
+ } `android:"arch_variant"`
+}
+
type Library struct {
Module
+
+ libraryProperties LibraryProperties
+
+ InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
+}
+
+// Provides access to the list of permitted packages from updatable boot jars.
+type PermittedPackagesForUpdatableBootJars interface {
+ PermittedPackagesForUpdatableBootJars() []string
+}
+
+var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil)
+
+func (j *Library) PermittedPackagesForUpdatableBootJars() []string {
+ return j.properties.Permitted_packages
}
func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
+ // Store uncompressed (and aligned) any dex files from jars in APEXes.
+ if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() {
+ return true
+ }
+
// Store uncompressed (and do not strip) dex files from boot class path jars.
if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
return true
@@ -1474,16 +1934,33 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo
}
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
+ j.checkSdkVersions(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)
-
- if (Bool(j.properties.Installable) || ctx.Host()) && !android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
+ if j.deviceProperties.Uncompress_dex == nil {
+ // If the value was not force-set by the user, use reasonable default based on the module.
+ j.deviceProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
+ }
+ j.dexpreopter.uncompressedDex = *j.deviceProperties.Uncompress_dex
+ j.compile(ctx, nil)
+
+ exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform()
+ if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
+ var extraInstallDeps android.Paths
+ if j.InstallMixin != nil {
+ extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
+ }
j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
- ctx.ModuleName()+".jar", j.outputFile)
+ j.Stem()+".jar", j.outputFile, extraInstallDeps...)
+ }
+
+ // Verify Dist.Tag is set to a supported output
+ if j.libraryProperties.Dist.Tag != nil {
+ distFiles, err := j.OutputFiles(*j.libraryProperties.Dist.Tag)
+ if err != nil {
+ ctx.PropertyErrorf("dist.tag", "%s", err.Error())
+ }
+ j.distFile = distFiles[0]
}
}
@@ -1491,6 +1968,102 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
j.deps(ctx)
}
+const (
+ aidlIncludeDir = "aidl"
+ javaDir = "java"
+ jarFileSuffix = ".jar"
+ testConfigSuffix = "-AndroidTest.xml"
+)
+
+// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
+func sdkSnapshotFilePathForJar(osPrefix, name string) string {
+ return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix)
+}
+
+func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string {
+ return filepath.Join(javaDir, osPrefix, name+suffix)
+}
+
+type librarySdkMemberType struct {
+ android.SdkMemberTypeBase
+
+ // Function to retrieve the appropriate output jar (implementation or header) from
+ // the library.
+ jarToExportGetter func(j *Library) android.Path
+}
+
+func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ mctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*Library)
+ return ok
+}
+
+func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
+ return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import")
+}
+
+func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
+ return &librarySdkMemberProperties{}
+}
+
+type librarySdkMemberProperties struct {
+ android.SdkMemberPropertiesBase
+
+ JarToExport android.Path `android:"arch_variant"`
+ AidlIncludeDirs android.Paths
+}
+
+func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
+ j := variant.(*Library)
+
+ p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(j)
+ p.AidlIncludeDirs = j.AidlIncludeDirs()
+}
+
+func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
+ builder := ctx.SnapshotBuilder()
+
+ exportedJar := p.JarToExport
+ if exportedJar != nil {
+ snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name())
+ builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
+
+ propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
+ }
+
+ aidlIncludeDirs := p.AidlIncludeDirs
+ if len(aidlIncludeDirs) != 0 {
+ sdkModuleContext := ctx.SdkModuleContext()
+ for _, dir := range aidlIncludeDirs {
+ // TODO(jiyong): copy parcelable declarations only
+ aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil)
+ for _, file := range aidlFiles {
+ builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file))
+ }
+ }
+
+ // TODO(b/151933053) - add aidl include dirs property
+ }
+}
+
+var javaHeaderLibsSdkMemberType android.SdkMemberType = &librarySdkMemberType{
+ android.SdkMemberTypeBase{
+ PropertyName: "java_header_libs",
+ SupportsSdk: true,
+ },
+ func(j *Library) android.Path {
+ headerJars := j.HeaderJars()
+ if len(headerJars) != 1 {
+ panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
+ }
+
+ return headerJars[0]
+ },
+}
+
// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
//
// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
@@ -1505,12 +2078,13 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
func LibraryFactory() android.Module {
module := &Library{}
- module.AddProperties(
- &module.Module.properties,
- &module.Module.deviceProperties,
- &module.Module.dexpreoptProperties,
- &module.Module.protoProperties)
+ module.addHostAndDeviceProperties()
+ module.AddProperties(&module.libraryProperties)
+
+ module.initModuleAndImport(&module.ModuleBase)
+ android.InitApexModule(module)
+ android.InitSdkAwareModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
@@ -1527,12 +2101,11 @@ func LibraryStaticFactory() android.Module {
func LibraryHostFactory() android.Module {
module := &Library{}
- module.AddProperties(
- &module.Module.properties,
- &module.Module.protoProperties)
+ module.addHostProperties()
module.Module.properties.Installable = proptools.BoolPtr(true)
+ android.InitApexModule(module)
InitJavaModule(module, android.HostSupported)
return module
}
@@ -1557,6 +2130,15 @@ type testProperties struct {
// list of files or filegroup modules that provide data that should be installed alongside
// the test
Data []string `android:"path"`
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
+
+ // Add parameterized mainline modules to auto generated test config. The options will be
+ // handled by TradeFed to do downloading and installing the specified modules on the device.
+ Test_mainline_modules []string
}
type testHelperLibraryProperties struct {
@@ -1565,6 +2147,16 @@ type testHelperLibraryProperties struct {
Test_suites []string `android:"arch_variant"`
}
+type prebuiltTestProperties 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:"path,arch_variant"`
+}
+
type Test struct {
Library
@@ -1580,8 +2172,17 @@ type TestHelperLibrary struct {
testHelperLibraryProperties testHelperLibraryProperties
}
+type JavaTestImport struct {
+ Import
+
+ prebuiltTestProperties prebuiltTestProperties
+
+ testConfig android.Path
+}
+
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, j.testProperties.Test_suites)
+ j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
+ j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
j.Library.GenerateAndroidBuildActions(ctx)
@@ -1591,6 +2192,72 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex
j.Library.GenerateAndroidBuildActions(ctx)
}
+func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
+ j.prebuiltTestProperties.Test_suites, nil)
+
+ j.Import.GenerateAndroidBuildActions(ctx)
+}
+
+type testSdkMemberType struct {
+ android.SdkMemberTypeBase
+}
+
+func (mt *testSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ mctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (mt *testSdkMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*Test)
+ return ok
+}
+
+func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
+ return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import")
+}
+
+func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
+ return &testSdkMemberProperties{}
+}
+
+type testSdkMemberProperties struct {
+ android.SdkMemberPropertiesBase
+
+ JarToExport android.Path
+ TestConfig android.Path
+}
+
+func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
+ test := variant.(*Test)
+
+ implementationJars := test.ImplementationJars()
+ if len(implementationJars) != 1 {
+ panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name()))
+ }
+
+ p.JarToExport = implementationJars[0]
+ p.TestConfig = test.testConfig
+}
+
+func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
+ builder := ctx.SnapshotBuilder()
+
+ exportedJar := p.JarToExport
+ if exportedJar != nil {
+ snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name())
+ builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
+
+ propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
+ }
+
+ testConfig := p.TestConfig
+ if testConfig != nil {
+ snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix)
+ builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath)
+ propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath)
+ }
+}
+
// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
//
@@ -1602,15 +2269,12 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex
func TestFactory() android.Module {
module := &Test{}
- module.AddProperties(
- &module.Module.properties,
- &module.Module.deviceProperties,
- &module.Module.dexpreoptProperties,
- &module.Module.protoProperties,
- &module.testProperties)
+ module.addHostAndDeviceProperties()
+ module.AddProperties(&module.testProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
+ module.Module.linter.test = true
InitJavaModule(module, android.HostAndDeviceSupported)
return module
@@ -1620,13 +2284,37 @@ func TestFactory() android.Module {
func TestHelperLibraryFactory() android.Module {
module := &TestHelperLibrary{}
+ module.addHostAndDeviceProperties()
+ module.AddProperties(&module.testHelperLibraryProperties)
+
+ module.Module.properties.Installable = proptools.BoolPtr(true)
+ module.Module.dexpreopter.isTest = true
+ module.Module.linter.test = true
+
+ InitJavaModule(module, android.HostAndDeviceSupported)
+ return module
+}
+
+// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module
+// and makes sure that it is added to the appropriate test suite.
+//
+// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were
+// compiled against an Android classpath.
+//
+// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
+// for host modules.
+func JavaTestImportFactory() android.Module {
+ module := &JavaTestImport{}
+
module.AddProperties(
- &module.Module.properties,
- &module.Module.deviceProperties,
- &module.Module.dexpreoptProperties,
- &module.Module.protoProperties,
- &module.testHelperLibraryProperties)
+ &module.Import.properties,
+ &module.prebuiltTestProperties)
+
+ module.Import.properties.Installable = proptools.BoolPtr(true)
+ android.InitPrebuiltModule(module, &module.properties.Jars)
+ android.InitApexModule(module)
+ android.InitSdkAwareModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
@@ -1639,10 +2327,8 @@ func TestHelperLibraryFactory() android.Module {
func TestHostFactory() android.Module {
module := &Test{}
- module.AddProperties(
- &module.Module.properties,
- &module.Module.protoProperties,
- &module.testProperties)
+ module.addHostProperties()
+ module.AddProperties(&module.testProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -1670,7 +2356,7 @@ type Binary struct {
isWrapperVariant bool
wrapperFile android.Path
- binaryFile android.OutputPath
+ binaryFile android.InstallPath
}
func (j *Binary) HostToolPath() android.OptionalPath {
@@ -1726,12 +2412,8 @@ func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
func BinaryFactory() android.Module {
module := &Binary{}
- module.AddProperties(
- &module.Module.properties,
- &module.Module.deviceProperties,
- &module.Module.dexpreoptProperties,
- &module.Module.protoProperties,
- &module.binaryProperties)
+ module.addHostAndDeviceProperties()
+ module.AddProperties(&module.binaryProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -1747,10 +2429,8 @@ func BinaryFactory() android.Module {
func BinaryHostFactory() android.Module {
module := &Binary{}
- module.AddProperties(
- &module.Module.properties,
- &module.Module.protoProperties,
- &module.binaryProperties)
+ module.addHostProperties()
+ module.AddProperties(&module.binaryProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -1764,7 +2444,7 @@ func BinaryHostFactory() android.Module {
//
type ImportProperties struct {
- Jars []string `android:"path"`
+ Jars []string `android:"path,arch_variant"`
Sdk_version *string
@@ -1781,12 +2461,20 @@ type ImportProperties struct {
// if set to true, run Jetifier against .jar file. Defaults to false.
Jetifier *bool
+
+ // set the name of the output
+ Stem *string
}
type Import struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.ApexModuleBase
prebuilt android.Prebuilt
+ android.SdkBase
+
+ // Functionality common to Module and Import.
+ embeddableInModuleAndImport
properties ImportProperties
@@ -1794,14 +2482,18 @@ type Import struct {
exportedSdkLibs []string
}
-func (j *Import) sdkVersion() string {
- return String(j.properties.Sdk_version)
+func (j *Import) sdkVersion() sdkSpec {
+ return sdkSpecFrom(String(j.properties.Sdk_version))
}
-func (j *Import) minSdkVersion() string {
+func (j *Import) minSdkVersion() sdkSpec {
return j.sdkVersion()
}
+func (j *Import) MinSdkVersion() string {
+ return j.minSdkVersion().version.String()
+}
+
func (j *Import) Prebuilt() *android.Prebuilt {
return &j.prebuilt
}
@@ -1814,6 +2506,14 @@ func (j *Import) Name() string {
return j.prebuilt.Name(j.ModuleBase.Name())
}
+func (j *Import) Stem() string {
+ return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
+}
+
+func (a *Import) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
}
@@ -1821,7 +2521,7 @@ func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
- jarName := ctx.ModuleName() + ".jar"
+ jarName := j.Stem() + ".jar"
outputFile := android.PathForModuleOut(ctx, "combined", jarName)
TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
@@ -1832,6 +2532,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
j.combinedClasspathFile = outputFile
+ // If this is a component library (impl, stubs, etc.) for a java_sdk_library then
+ // add the name of that java_sdk_library to the exported sdk libs to make sure
+ // that, if necessary, a <uses-library> element for that java_sdk_library is
+ // added to the Android manifest.
+ j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
+
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -1855,7 +2561,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
if Bool(j.properties.Installable) {
ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
- ctx.ModuleName()+".jar", outputFile)
+ jarName, outputFile)
}
}
@@ -1898,6 +2604,18 @@ func (j *Import) ExportedSdkLibs() []string {
return j.exportedSdkLibs
}
+func (j *Import) ExportedPlugins() (android.Paths, []string) {
+ return nil, nil
+}
+
+func (j *Import) SrcJarArgs() ([]string, android.Paths) {
+ return nil, nil
+}
+
+func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+ return j.depIsInSameApex(ctx, dep)
+}
+
// Add compile time check for interface implementation
var _ android.IDEInfo = (*Import)(nil)
var _ android.IDECustomizedModuleName = (*Import)(nil)
@@ -1936,7 +2654,11 @@ func ImportFactory() android.Module {
module.AddProperties(&module.properties)
+ module.initModuleAndImport(&module.ModuleBase)
+
android.InitPrebuiltModule(module, &module.properties.Jars)
+ android.InitApexModule(module)
+ android.InitSdkAwareModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
@@ -1952,6 +2674,7 @@ func ImportFactoryHost() android.Module {
module.AddProperties(&module.properties)
android.InitPrebuiltModule(module, &module.properties.Jars)
+ android.InitApexModule(module)
InitJavaModule(module, android.HostSupported)
return module
}
@@ -1959,12 +2682,16 @@ func ImportFactoryHost() android.Module {
// dex_import module
type DexImportProperties struct {
- Jars []string
+ Jars []string `android:"path"`
+
+ // set the name of the output
+ Stem *string
}
type DexImport struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.ApexModuleBase
prebuilt android.Prebuilt
properties DexImportProperties
@@ -1987,8 +2714,20 @@ func (j *DexImport) Name() string {
return j.prebuilt.Name(j.ModuleBase.Name())
}
-func (j *DexImport) DepsMutator(ctx android.BottomUpMutatorContext) {
- android.ExtractSourcesDeps(ctx, j.properties.Jars)
+func (j *DexImport) Stem() string {
+ return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
+}
+
+func (a *DexImport) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
+func (a *DexImport) LintDepSets() LintDepSets {
+ return LintDepSets{}
+}
+
+func (j *DexImport) IsInstallable() bool {
+ return true
}
func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1996,8 +2735,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.PropertyErrorf("jars", "exactly one jar must be provided")
}
- j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
- j.dexpreopter.isInstallable = true
+ j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
@@ -2011,14 +2749,14 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// use zip2zip to uncompress classes*.dex files
rule.Command().
- Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
+ BuiltTool(ctx, "zip2zip").
FlagWithInput("-i ", inputJar).
FlagWithOutput("-o ", temporary).
FlagWithArg("-0 ", "'classes*.dex'")
// use zipalign to align uncompressed classes*.dex files
rule.Command().
- Tool(ctx.Config().HostToolPath(ctx, "zipalign")).
+ BuiltTool(ctx, "zipalign").
Flag("-f").
Text("4").
Input(temporary).
@@ -2041,8 +2779,10 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.maybeStrippedDexJarFile = dexOutputFile
- ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
- ctx.ModuleName()+".jar", dexOutputFile)
+ if j.IsForPlatform() {
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
+ j.Stem()+".jar", dexOutputFile)
+ }
}
func (j *DexImport) DexJar() android.Path {
@@ -2059,6 +2799,7 @@ func DexImportFactory() android.Module {
module.AddProperties(&module.properties)
android.InitPrebuiltModule(module, &module.properties.Jars)
+ android.InitApexModule(module)
InitJavaModule(module, android.DeviceSupported)
return module
}
@@ -2069,9 +2810,7 @@ func DexImportFactory() android.Module {
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
-}
-
-func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ android.ApexModuleBase
}
// java_defaults provides a set of properties that can be inherited by other java or android modules.
@@ -2109,10 +2848,9 @@ func defaultsFactory() android.Module {
return DefaultsFactory()
}
-func DefaultsFactory(props ...interface{}) android.Module {
+func DefaultsFactory() android.Module {
module := &Defaults{}
- module.AddProperties(props...)
module.AddProperties(
&CompilerProperties{},
&CompilerDeviceProperties{},
@@ -2126,14 +2864,37 @@ func DefaultsFactory(props ...interface{}) android.Module {
&ImportProperties{},
&AARImportProperties{},
&sdkLibraryProperties{},
+ &commonToSdkLibraryAndImportProperties{},
&DexImportProperties{},
+ &android.ApexProperties{},
+ &RuntimeResourceOverlayProperties{},
+ &LintProperties{},
)
android.InitDefaultsModule(module)
-
return module
}
+func kytheExtractJavaFactory() android.Singleton {
+ return &kytheExtractJavaSingleton{}
+}
+
+type kytheExtractJavaSingleton struct {
+}
+
+func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var xrefTargets android.Paths
+ ctx.VisitAllModules(func(module android.Module) {
+ if javaModule, ok := module.(xref); ok {
+ xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
+ }
+ })
+ // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
+ if len(xrefTargets) > 0 {
+ ctx.Phony("xref_java", xrefTargets...)
+ }
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String