diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 322 |
1 files changed, 273 insertions, 49 deletions
diff --git a/java/java.go b/java/java.go index 9c0fcbaa0..4c6a5a5ac 100644 --- a/java/java.go +++ b/java/java.go @@ -34,24 +34,53 @@ import ( ) func init() { - android.RegisterModuleType("java_defaults", defaultsFactory) - - 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.RegisterSingletonType("logtags", LogtagsSingleton) - android.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) + RegisterJavaBuildComponents(android.InitRegistrationContext) + + // Register sdk member types. + android.RegisterSdkMemberType(&headerLibrarySdkMemberType{ + librarySdkMemberType{ + android.SdkMemberTypeBase{ + PropertyName: "java_header_libs", + SupportsSdk: true, + }, + }, + }) + + android.RegisterSdkMemberType(&implLibrarySdkMemberType{ + librarySdkMemberType{ + android.SdkMemberTypeBase{ + PropertyName: "java_libs", + }, + }, + }) + + 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) { @@ -405,10 +434,6 @@ func (j *Module) OutputFiles(tag string) (android.Paths, error) { } } -func (j *Module) DexJarFile() android.Path { - return j.dexJarFile -} - var _ android.OutputFileProducer = (*Module)(nil) type Dependency interface { @@ -422,6 +447,7 @@ type Dependency interface { ExportedPlugins() (android.Paths, []string) SrcJarArgs() ([]string, android.Paths) BaseModuleName() string + JacocoReportClassesFile() android.Path } type SdkLibraryDependency interface { @@ -449,7 +475,6 @@ type dependencyTag struct { type jniDependencyTag struct { blueprint.BaseDependencyTag - target android.Target } func IsJniDepTag(depTag blueprint.DependencyTag) bool { @@ -475,6 +500,14 @@ 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 @@ -542,6 +575,16 @@ func (j *Module) targetSdkVersion() string { return j.sdkVersion() } +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)) @@ -568,8 +611,33 @@ 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.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...) @@ -589,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") } } @@ -792,8 +867,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { return } switch module.(type) { - case *Library: - case *AndroidLibrary: + case *Library, *AndroidLibrary: if to, ok := module.(linkTypeContext); ok { switch tag { case bootClasspathTag, libTag, staticLibTag: @@ -1393,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) } @@ -1658,6 +1726,10 @@ 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) // @@ -1711,23 +1783,53 @@ func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { } const ( - aidlIncludeDir = "aidl" - javaStubDir = "java" - javaStubFileSuffix = ".jar" + aidlIncludeDir = "aidl" + javaDir = "java" + jarFileSuffix = ".jar" + testConfigSuffix = "-AndroidTest.xml" ) -// path to the stub file of a java library. Relative to <sdk_root>/<api_dir> -func (j *Library) javaStubFilePathFor() string { - return filepath.Join(javaStubDir, j.Name()+javaStubFileSuffix) +// 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 (j *Library) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder) { - headerJars := j.HeaderJars() - if len(headerJars) != 1 { - panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) +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) + } } - snapshotRelativeJavaLibPath := j.javaStubFilePathFor() - builder.CopyToSnapshot(headerJars[0], snapshotRelativeJavaLibPath) + 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 @@ -1737,10 +1839,40 @@ func (j *Library) BuildSnapshot(sdkModuleContext android.ModuleContext, builder } } - module := builder.AddPrebuiltModule(sdkModuleContext.OtherModuleName(j), "java_import") + 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 @@ -1823,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 @@ -1838,6 +1980,14 @@ 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.testProperties.Auto_gen_config) @@ -1850,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. // @@ -1893,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. // @@ -2085,6 +2306,10 @@ 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...) } @@ -2394,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{}, |