diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 800 |
1 files changed, 629 insertions, 171 deletions
diff --git a/java/java.go b/java/java.go index a2e9ab023..4c6a5a5ac 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,79 @@ import ( ) func init() { - android.RegisterModuleType("java_defaults", defaultsFactory) + RegisterJavaBuildComponents(android.InitRegistrationContext) + + // Register sdk member types. + android.RegisterSdkMemberType(&headerLibrarySdkMemberType{ + librarySdkMemberType{ + android.SdkMemberTypeBase{ + PropertyName: "java_header_libs", + SupportsSdk: true, + }, + }, + }) - 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) + android.RegisterSdkMemberType(&implLibrarySdkMemberType{ + librarySdkMemberType{ + android.SdkMemberTypeBase{ + PropertyName: "java_libs", + }, + }, + }) - android.RegisterSingletonType("logtags", LogtagsSingleton) + 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.RegisterSingletonType("logtags", LogtagsSingleton) + ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) +} + +func (j *Module) checkSdkVersion(ctx android.ModuleContext) { + if j.SocSpecific() || j.DeviceSpecific() || + (j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { + if sc, ok := ctx.Module().(sdkContext); ok { + if sc.sdkVersion() == "" { + 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).") + } + } + } +} + +func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { + if sc, ok := ctx.Module().(sdkContext); ok { + usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis) + if usePlatformAPI != (sc.sdkVersion() == "") { + if usePlatformAPI { + ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.") + } else { + ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.") + } + } + + } } // TODO: @@ -82,9 +139,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 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"` @@ -120,6 +174,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 @@ -127,10 +184,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 } @@ -181,8 +238,8 @@ 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. @@ -193,7 +250,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 { @@ -255,9 +314,13 @@ 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 + // set the name of the output + Stem *string + UncompressDex bool `blueprint:"mutated"` IsSDKLibrary bool `blueprint:"mutated"` } @@ -270,6 +333,8 @@ func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool { type Module struct { android.ModuleBase android.DefaultableModuleBase + android.ApexModuleBase + android.SdkBase properties CompilerProperties protoProperties android.ProtoProperties @@ -327,11 +392,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 @@ -345,6 +416,9 @@ type Module struct { hiddenAPI dexpreopter + + // list of the xref extraction files + kytheFiles android.Paths } func (j *Module) OutputFiles(tag string) (android.Paths, error) { @@ -353,15 +427,13 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) { 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) } } -func (j *Module) DexJarFile() android.Path { - return j.dexJarFile -} - var _ android.OutputFileProducer = (*Module)(nil) type Dependency interface { @@ -372,7 +444,10 @@ type Dependency interface { DexJar() android.Path AidlIncludeDirs() android.Paths ExportedSdkLibs() []string + ExportedPlugins() (android.Paths, []string) SrcJarArgs() ([]string, android.Paths) + BaseModuleName() string + JacocoReportClassesFile() android.Path } type SdkLibraryDependency interface { @@ -380,21 +455,14 @@ type SdkLibraryDependency interface { SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion string) android.Paths } -type SrcDependency interface { - CompiledSrcs() android.Paths - CompiledSrcJars() android.Paths +type xref interface { + XrefJavaFiles() android.Paths } -func (j *Module) CompiledSrcs() android.Paths { - return j.compiledJavaSrcs +func (j *Module) XrefJavaFiles() android.Paths { + return j.kytheFiles } -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) @@ -407,13 +475,19 @@ 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"} @@ -426,12 +500,27 @@ var ( usesLibTag = dependencyTag{name: "uses-library"} ) +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 @@ -468,6 +557,10 @@ func (j *Module) sdkVersion() string { return String(j.deviceProperties.Sdk_version) } +func (j *Module) systemModules() string { + return proptools.String(j.deviceProperties.System_modules) +} + func (j *Module) minSdkVersion() string { if j.deviceProperties.Min_sdk_version != nil { return *j.deviceProperties.Min_sdk_version @@ -482,37 +575,35 @@ func (j *Module) targetSdkVersion() string { return j.sdkVersion() } -func (j *Module) noFrameworkLibs() bool { - return Bool(j.properties.No_framework_libs) +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() { sdkDep := decodeSdkDep(ctx, sdkContext(j)) - if sdkDep.hasStandardLibs() { - 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, 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...) - } + 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, systemModulesTag, sdkDep.systemModules) + 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("sdk_version", - `system_modules is required to be set when sdk_version is "none", 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 ctx.ModuleName() == "android_stubs_current" || ctx.ModuleName() == "android_system_stubs_current" || ctx.ModuleName() == "android_test_stubs_current" { @@ -520,12 +611,36 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } } - ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) - ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...) + 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.AddFarVariationDependencies([]blueprint.Variation{ - {Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant}, - }, pluginTag, j.properties.Plugins...) + ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) + ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...) + + 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") { @@ -542,7 +657,14 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } } - 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") } } @@ -557,18 +679,6 @@ func hasSrcExt(srcs []string, ext string) bool { return false } -func shardPaths(paths android.Paths, shardSize int) []android.Paths { - ret := make([]android.Paths, 0, (len(paths)+shardSize-1)/shardSize) - for len(paths) > shardSize { - ret = append(ret, paths[0:shardSize]) - paths = paths[shardSize:] - } - if len(paths) > 0 { - ret = append(ret, paths) - } - return ret -} - func (j *Module) hasSrcExt(ext string) bool { return hasSrcExt(j.properties.Srcs, ext) } @@ -618,6 +728,7 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt type deps struct { classpath classpath + java9Classpath classpath bootClasspath classpath processorPath classpath processorClasses []string @@ -627,8 +738,7 @@ type deps struct { aidlIncludeDirs android.Paths srcs android.Paths srcJars android.Paths - systemModules android.Path - systemModulesDeps android.Paths + systemModules *systemModules aidlPreprocess android.OptionalPath kotlinStdlib android.Paths kotlinAnnotations android.Paths @@ -654,7 +764,12 @@ const ( javaPlatform ) -func getLinkType(m *Module, name string) (ret linkType, stubs bool) { +type linkTypeContext interface { + android.Module + getLinkType(name string) (ret linkType, stubs bool) +} + +func (m *Module) getLinkType(name string) (ret linkType, stubs bool) { ver := m.sdkVersion() switch { case name == "core.current.stubs" || name == "core.platform.api.stubs" || @@ -685,16 +800,16 @@ func getLinkType(m *Module, name string) (ret linkType, stubs bool) { } } -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 { @@ -728,7 +843,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...) @@ -750,11 +866,13 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { // Handled by AndroidApp.collectAppDeps return } - - if to, ok := module.(*Library); ok { - switch tag { - case bootClasspathTag, libTag, staticLibTag: - checkLinkType(ctx, j, to, tag.(dependencyTag)) + switch module.(type) { + case *Library, *AndroidLibrary: + if to, ok := module.(linkTypeContext); ok { + switch tag { + case bootClasspathTag, libTag, staticLibTag: + checkLinkType(ctx, j, to, tag.(dependencyTag)) + } } } switch dep := module.(type) { @@ -776,6 +894,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()...) @@ -784,21 +906,30 @@ 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 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 frameworkApkTag: if ctx.ModuleName() == "android_stubs_current" || @@ -831,6 +962,12 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { } default: switch tag { + case bootClasspathTag: + // If a system modules dependency has been added to the bootclasspath + // then add its libs to the bootclasspath. + sm := module.(*SystemModules) + deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...) + case systemModulesTag: if deps.systemModules != nil { panic("Found two system module dependencies") @@ -839,8 +976,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { if sm.outputDir == nil || len(sm.outputDeps) == 0 { panic("Missing directory for system module dependency") } - deps.systemModules = sm.outputDir - deps.systemModulesDeps = sm.outputDeps + deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps} } } }) @@ -850,8 +986,12 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { return deps } -func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) string { - var ret string +func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) { + deps.processorPath = append(deps.processorPath, pluginJars...) + deps.processorClasses = append(deps.processorClasses, pluginClasses...) +} + +func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion { v := sdkContext.sdkVersion() // For PDK builds, use the latest SDK version instead of "current" if ctx.Config().IsPdkBuild() && @@ -869,23 +1009,66 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sd ctx.PropertyErrorf("sdk_version", "%s", err) } if javaVersion != "" { - ret = javaVersion + return normalizeJavaVersion(ctx, javaVersion) } else if ctx.Device() && sdk <= 23 { - ret = "1.7" - } else if ctx.Device() && sdk <= 29 || !ctx.Config().TargetOpenJDK9() { - ret = "1.8" - } else if ctx.Device() && - sdkContext.sdkVersion() != "" && - sdkContext.sdkVersion() != "none" && - sdkContext.sdkVersion() != "core_platform" && - 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 JAVA_VERSION_7 + } else if ctx.Device() && sdk <= 29 { + return JAVA_VERSION_8 + } else if ctx.Device() && ctx.Config().UnbundledBuildUsePrebuiltSdks() { + // TODO(b/142896162): once we have prebuilt system modules we can use 1.9 for unbundled builds + return JAVA_VERSION_8 } else { - ret = "1.9" + return JAVA_VERSION_9 } +} + +type javaVersion int - return ret +const ( + JAVA_VERSION_UNSUPPORTED = 0 + JAVA_VERSION_6 = 6 + JAVA_VERSION_7 = 7 + JAVA_VERSION_8 = 8 + JAVA_VERSION_9 = 9 +) + +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 { @@ -897,7 +1080,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() { @@ -905,6 +1088,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 { @@ -925,13 +1109,13 @@ 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, ",") - if len(flags.bootClasspath) == 0 && ctx.Host() && flags.javaVersion != "1.9" && - decodeSdkDep(ctx, sdkContext(j)).hasStandardLibs() && - 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. @@ -955,7 +1139,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.) @@ -968,10 +1152,7 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB } // systemModules - if deps.systemModules != nil { - flags.systemModules = append(flags.systemModules, deps.systemModules) - flags.systemModulesDeps = append(flags.systemModulesDeps, deps.systemModulesDeps...) - } + flags.systemModules = deps.systemModules // aidl flags. flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs) @@ -986,13 +1167,12 @@ func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaB } 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) @@ -1008,10 +1188,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { srcJars = append(srcJars, aaptSrcJar) } - // Collect source files from compiledJavaSrcs, compiledSrcJars and filter out Exclude_srcs - // that IDEInfo struct will use - j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...) - if j.properties.Jarjar_rules != nil { j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules) } @@ -1028,6 +1204,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { } } + // Collect .java files for AIDEGen + j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...) + var kotlinJars android.Paths if srcFiles.HasExt(".kt") { @@ -1052,6 +1231,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar 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...) @@ -1121,21 +1303,20 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { shardSize := int(*(j.properties.Javac_shard_size)) var shardSrcs []android.Paths if len(uniqueSrcFiles) > 0 { - shardSrcs = shardPaths(uniqueSrcFiles, shardSize) + 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() { @@ -1286,12 +1467,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.headerJarFile = j.implementationJarFile } - if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { - if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { - j.properties.Instrument = true - } - } - if j.shouldInstrument(ctx) { outputFile = j.instrument(ctx, flags, outputFile, jarName) } @@ -1317,11 +1492,9 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { return } - if !ctx.Config().UnbundledBuild() { - // Hidden API CSV generation and dex encoding - dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile, - j.deviceProperties.UncompressDex) - } + // Hidden API CSV generation and dex encoding + dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile, + j.deviceProperties.UncompressDex) // merge dex jar with resources if necessary if j.resourceJar != nil { @@ -1360,6 +1533,27 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { 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) { @@ -1485,6 +1679,10 @@ 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 } @@ -1518,12 +1716,28 @@ func (j *Module) hasCode(ctx android.ModuleContext) bool { return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0 } +func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { + depTag := ctx.OtherModuleDependencyTag(dep) + // dependencies other than the static linkage are all considered crossing APEX boundary + return depTag == staticLibTag +} + +func (j *Module) Stem() string { + return proptools.StringDefault(j.deviceProperties.Stem, j.Name()) +} + +func (j *Module) JacocoReportClassesFile() android.Path { + return j.jacocoReportClassesFile +} + // // Java libraries (.jar file) // type Library struct { Module + + InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) } func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { @@ -1545,16 +1759,22 @@ 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.checkSdkVersion(ctx) + j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary j.dexpreopter.isInstallable = Bool(j.properties.Installable) j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex j.compile(ctx, nil) - if (Bool(j.properties.Installable) || ctx.Host()) && !android.DirectlyInAnyApex(ctx, ctx.ModuleName()) { + 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) + ctx.ModuleName()+".jar", j.outputFile, extraInstallDeps...) } } @@ -1562,6 +1782,97 @@ 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(member android.SdkMember) string { + return sdkSnapshotFilePathForMember(member, jarFileSuffix) +} + +func sdkSnapshotFilePathForMember(member android.SdkMember, suffix string) string { + return filepath.Join(javaDir, member.Name()+suffix) +} + +type librarySdkMemberType struct { + android.SdkMemberTypeBase +} + +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) buildSnapshot( + sdkModuleContext android.ModuleContext, + builder android.SnapshotBuilder, + member android.SdkMember, + jarToExportGetter func(j *Library) android.Path) { + + variants := member.Variants() + if len(variants) != 1 { + sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name()) + for _, variant := range variants { + sdkModuleContext.ModuleErrorf(" %q", variant) + } + } + variant := variants[0] + j := variant.(*Library) + + exportedJar := jarToExportGetter(j) + snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(member) + builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) + + for _, dir := range j.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)) + } + } + + module := builder.AddPrebuiltModule(member, "java_import") + module.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) +} + +type headerLibrarySdkMemberType struct { + librarySdkMemberType +} + +func (mt *headerLibrarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) { + mt.librarySdkMemberType.buildSnapshot(sdkModuleContext, builder, member, 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] + }) +} + +type implLibrarySdkMemberType struct { + librarySdkMemberType +} + +func (mt *implLibrarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) { + mt.librarySdkMemberType.buildSnapshot(sdkModuleContext, builder, member, 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] + }) +} + // 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 @@ -1582,6 +1893,8 @@ func LibraryFactory() android.Module { &module.Module.dexpreoptProperties, &module.Module.protoProperties) + android.InitApexModule(module) + android.InitSdkAwareModule(module) InitJavaModule(module, android.HostAndDeviceSupported) return module } @@ -1604,6 +1917,7 @@ func LibraryHostFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) + android.InitApexModule(module) InitJavaModule(module, android.HostSupported) return module } @@ -1628,6 +1942,11 @@ 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 } type testHelperLibraryProperties struct { @@ -1636,6 +1955,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 @@ -1651,8 +1980,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) @@ -1662,6 +2000,53 @@ 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) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) { + variants := member.Variants() + if len(variants) != 1 { + sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name()) + for _, variant := range variants { + sdkModuleContext.ModuleErrorf(" %q", variant) + } + } + variant := variants[0] + j := variant.(*Test) + + implementationJars := j.ImplementationJars() + if len(implementationJars) != 1 { + panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) + } + + snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(member) + builder.CopyToSnapshot(implementationJars[0], snapshotRelativeJavaLibPath) + + snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(member, testConfigSuffix) + builder.CopyToSnapshot(j.testConfig, snapshotRelativeTestConfigPath) + + module := builder.AddPrebuiltModule(member, "java_test_import") + module.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) + module.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. // @@ -1705,6 +2090,30 @@ func TestHelperLibraryFactory() android.Module { 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.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 +} + // java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to // allow running the test with `atest` or a `TEST_MAPPING` file. // @@ -1744,7 +2153,7 @@ type Binary struct { isWrapperVariant bool wrapperFile android.Path - binaryFile android.OutputPath + binaryFile android.InstallPath } func (j *Binary) HostToolPath() android.OptionalPath { @@ -1855,12 +2264,17 @@ 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 properties ImportProperties @@ -1888,6 +2302,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...) } @@ -1895,7 +2317,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) @@ -1929,7 +2351,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) } } @@ -1972,6 +2394,10 @@ 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 } @@ -2015,6 +2441,8 @@ func ImportFactory() android.Module { module.AddProperties(&module.properties) android.InitPrebuiltModule(module, &module.properties.Jars) + android.InitApexModule(module) + android.InitSdkAwareModule(module) InitJavaModule(module, android.HostAndDeviceSupported) return module } @@ -2030,6 +2458,7 @@ func ImportFactoryHost() android.Module { module.AddProperties(&module.properties) android.InitPrebuiltModule(module, &module.properties.Jars) + android.InitApexModule(module) InitJavaModule(module, android.HostSupported) return module } @@ -2037,12 +2466,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 @@ -2065,8 +2498,8 @@ 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 (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -2074,7 +2507,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.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.isInstallable = true j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) @@ -2089,14 +2522,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). @@ -2137,6 +2570,7 @@ func DexImportFactory() android.Module { module.AddProperties(&module.properties) android.InitPrebuiltModule(module, &module.properties.Jars) + android.InitApexModule(module) InitJavaModule(module, android.DeviceSupported) return module } @@ -2147,6 +2581,7 @@ func DexImportFactory() android.Module { type Defaults struct { android.ModuleBase android.DefaultsModuleBase + android.ApexModuleBase } // java_defaults provides a set of properties that can be inherited by other java or android modules. @@ -2184,10 +2619,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{}, @@ -2202,13 +2636,37 @@ func DefaultsFactory(props ...interface{}) android.Module { &AARImportProperties{}, &sdkLibraryProperties{}, &DexImportProperties{}, + &android.ApexProperties{}, ) 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.Build(pctx, android.BuildParams{ + Rule: blueprint.Phony, + Output: android.PathForPhony(ctx, "xref_java"), + Inputs: xrefTargets, + }) + } +} + var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String |