diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 352 |
1 files changed, 287 insertions, 65 deletions
diff --git a/java/java.go b/java/java.go index 1a052b432..9b4a005f0 100644 --- a/java/java.go +++ b/java/java.go @@ -21,7 +21,9 @@ package java import ( "fmt" "path/filepath" + "strings" + "android/soong/bazel" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -73,6 +75,7 @@ func RegisterJavaSdkMemberTypes() { android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) android.RegisterSdkMemberType(javaLibsSdkMemberType) android.RegisterSdkMemberType(javaBootLibsSdkMemberType) + android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType) android.RegisterSdkMemberType(javaTestSdkMemberType) } @@ -146,6 +149,37 @@ var ( onlyCopyJarToSnapshot, } + // Supports adding java systemserver libraries to module_exports and sdk. + // + // The build has some implicit dependencies (via the systemserver jars configuration) on a number + // of modules that are part of the java systemserver classpath and which are provided by mainline + // modules but which are not otherwise used outside those mainline modules. + // + // As they are not needed outside the mainline modules adding them to the sdk/module-exports as + // either java_libs, or java_header_libs would end up exporting more information than was strictly + // necessary. The java_systemserver_libs property to allow those modules to be exported as part of + // the sdk/module_exports without exposing any unnecessary information. + javaSystemserverLibsSdkMemberType = &librarySdkMemberType{ + android.SdkMemberTypeBase{ + PropertyName: "java_systemserver_libs", + SupportsSdk: true, + }, + func(ctx android.SdkMemberContext, j *Library) android.Path { + // Java systemserver libs are only provided in the SDK to provide access to their dex + // implementation jar for use by dexpreopting. They do not need to provide an actual + // implementation jar but the java_import will need a file that exists so just copy an empty + // file. Any attempt to use that file as a jar will cause a build error. + return ctx.SnapshotBuilder().EmptyFile() + }, + func(osPrefix, name string) string { + // Create a special name for the implementation jar to try and provide some useful information + // to a developer that attempts to compile against this. + // TODO(b/175714559): Provide a proper error message in Soong not ninja. + return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) + }, + onlyCopyJarToSnapshot, + } + // Supports adding java test libraries to module_exports but not sdk. javaTestSdkMemberType = &testSdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ @@ -219,7 +253,7 @@ type ApexDependency interface { // Provides build path and install path to DEX jars. type UsesLibraryDependency interface { - DexJarBuildPath() android.Path + DexJarBuildPath() OptionalDexJarPath DexJarInstallPath() android.Path ClassLoaderContexts() dexpreopt.ClassLoaderContextMap } @@ -236,6 +270,9 @@ func (j *Module) XrefJavaFiles() android.Paths { type dependencyTag struct { blueprint.BaseDependencyTag name string + + // True if the dependency is relinked at runtime. + runtimeLinked bool } // installDependencyTag is a dependency tag that is annotated to cause the installed files of the @@ -246,6 +283,15 @@ type installDependencyTag struct { name string } +func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { + if d.runtimeLinked { + return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} + } + return nil +} + +var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} + type usesLibraryDependencyTag struct { dependencyTag @@ -262,10 +308,13 @@ type usesLibraryDependencyTag struct { func makeUsesLibraryDependencyTag(sdkVersion int, optional bool, implicit bool) usesLibraryDependencyTag { return usesLibraryDependencyTag{ - dependencyTag: dependencyTag{name: fmt.Sprintf("uses-library-%d", sdkVersion)}, - sdkVersion: sdkVersion, - optional: optional, - implicit: implicit, + dependencyTag: dependencyTag{ + name: fmt.Sprintf("uses-library-%d", sdkVersion), + runtimeLinked: true, + }, + sdkVersion: sdkVersion, + optional: optional, + implicit: implicit, } } @@ -276,21 +325,22 @@ func IsJniDepTag(depTag blueprint.DependencyTag) bool { var ( dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} staticLibTag = dependencyTag{name: "staticlib"} - libTag = dependencyTag{name: "javalib"} - java9LibTag = dependencyTag{name: "java9lib"} + libTag = dependencyTag{name: "javalib", runtimeLinked: true} + java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true} pluginTag = dependencyTag{name: "plugin"} errorpronePluginTag = dependencyTag{name: "errorprone-plugin"} exportedPluginTag = dependencyTag{name: "exported-plugin"} - bootClasspathTag = dependencyTag{name: "bootclasspath"} - systemModulesTag = dependencyTag{name: "system modules"} + bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true} + systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true} frameworkResTag = dependencyTag{name: "framework-res"} - kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"} - kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations"} + kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib", runtimeLinked: true} + kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations", runtimeLinked: true} + kotlinPluginTag = dependencyTag{name: "kotlin-plugin"} proguardRaiseTag = dependencyTag{name: "proguard-raise"} certificateTag = dependencyTag{name: "certificate"} instrumentationForTag = dependencyTag{name: "instrumentation_for"} extraLintCheckTag = dependencyTag{name: "extra-lint-check"} - jniLibTag = dependencyTag{name: "jnilib"} + jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true} syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} jniInstallTag = installDependencyTag{name: "jni install"} binaryInstallTag = installDependencyTag{name: "binary install"} @@ -380,6 +430,7 @@ type deps struct { aidlPreprocess android.OptionalPath kotlinStdlib android.Paths kotlinAnnotations android.Paths + kotlinPlugins android.Paths disableTurbine bool } @@ -398,6 +449,12 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext an return normalizeJavaVersion(ctx, javaVersion) } else if ctx.Device() { return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) + } else if ctx.Config().TargetsJava11() { + // Temporary experimental flag to be able to try and build with + // java version 11 options. The flag, if used, just sets Java + // 11 as the default version, leaving any components that + // target an older version intact. + return JAVA_VERSION_11 } else { return JAVA_VERSION_9 } @@ -411,6 +468,7 @@ const ( JAVA_VERSION_7 = 7 JAVA_VERSION_8 = 8 JAVA_VERSION_9 = 9 + JAVA_VERSION_11 = 11 ) func (v javaVersion) String() string { @@ -423,6 +481,8 @@ func (v javaVersion) String() string { return "1.8" case JAVA_VERSION_9: return "1.9" + case JAVA_VERSION_11: + return "11" default: return "unsupported" } @@ -443,8 +503,10 @@ func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) jav 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") + case "11": + return JAVA_VERSION_11 + case "10": + ctx.PropertyErrorf("java_version", "Java language levels 10 is not supported") return JAVA_VERSION_UNSUPPORTED default: ctx.PropertyErrorf("java_version", "Unrecognized Java language level") @@ -487,7 +549,7 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo } // Store uncompressed dex files that are preopted on /system. - if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) { + if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) { return true } if ctx.Config().UncompressPrivAppDex() && @@ -498,9 +560,18 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo return false } +// Sets `dexer.dexProperties.Uncompress_dex` to the proper value. +func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) { + if dexer.dexProperties.Uncompress_dex == nil { + // If the value was not force-set by the user, use reasonable default based on the module. + dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, dexpreopter)) + } +} + func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) + j.maxSdkVersion = j.MaxSdkVersion(ctx) apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if !apexInfo.IsForPlatform() { @@ -508,12 +579,10 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { } j.checkSdkVersions(ctx) - j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") + j.dexpreopter.installPath = j.dexpreopter.getInstallPath( + ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary - if j.dexProperties.Uncompress_dex == nil { - // If the value was not force-set by the user, use reasonable default based on the module. - j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter)) - } + setUncompressDex(ctx, &j.dexpreopter, &j.dexer) j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) j.compile(ctx, nil) @@ -527,8 +596,23 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { if j.InstallMixin != nil { extraInstallDeps = j.InstallMixin(ctx, j.outputFile) } - j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), - j.Stem()+".jar", j.outputFile, extraInstallDeps...) + hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host() + if hostDexNeeded { + j.hostdexInstallFile = ctx.InstallFile( + android.PathForHostDexInstall(ctx, "framework"), + j.Stem()+"-hostdex.jar", j.outputFile) + } + var installDir android.InstallPath + if ctx.InstallInTestcases() { + var archDir string + if !ctx.Host() { + archDir = ctx.DeviceConfig().DeviceArch() + } + installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) + } else { + installDir = android.PathForModuleInstall(ctx, "framework") + } + j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) } } @@ -672,6 +756,7 @@ func LibraryFactory() android.Module { android.InitApexModule(module) android.InitSdkAwareModule(module) + android.InitBazelModule(module) InitJavaModule(module, android.HostAndDeviceSupported) return module } @@ -694,6 +779,7 @@ func LibraryHostFactory() android.Module { android.InitApexModule(module) android.InitSdkAwareModule(module) + android.InitBazelModule(module) InitJavaModule(module, android.HostSupported) return module } @@ -742,6 +828,9 @@ type testProperties struct { // Names of modules containing JNI libraries that should be installed alongside the test. Jni_libs []string + + // Install the test into a folder named for the module in all test suites. + Per_testcase_directory *bool } type hostTestProperties struct { @@ -753,6 +842,9 @@ type testHelperLibraryProperties struct { // list of compatibility suites (for example "cts", "vts") that the module should be // installed into. Test_suites []string `android:"arch_variant"` + + // Install the test into a folder named for the module in all test suites. + Per_testcase_directory *bool } type prebuiltTestProperties struct { @@ -796,6 +888,20 @@ type JavaTestImport struct { dexJarFile android.Path } +func (j *Test) InstallInTestcases() bool { + // Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into + // testcases by base_rules.mk. + return !j.Host() +} + +func (j *TestHelperLibrary) InstallInTestcases() bool { + return true +} + +func (j *JavaTestImport) InstallInTestcases() bool { + return true +} + func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { if len(j.testHostProperties.Data_native_bins) > 0 { for _, target := range ctx.MultiTargets() { @@ -1027,14 +1133,14 @@ func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenC type binaryProperties struct { // installable script to execute the resulting jar - Wrapper *string `android:"path"` + Wrapper *string `android:"path,arch_variant"` // Name of the class containing main to be inserted into the manifest as Main-Class. Main_class *string // Names of modules containing JNI libraries that should be installed alongside the host // variant of the binary. - Jni_libs []string + Jni_libs []string `android:"arch_variant"` } type Binary struct { @@ -1072,14 +1178,23 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { if j.binaryProperties.Wrapper != nil { j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) } else { + if ctx.Windows() { + ctx.PropertyErrorf("wrapper", "wrapper is required for Windows") + } + j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") } + ext := "" + if ctx.Windows() { + ext = ".bat" + } + // The host installation rules make the installed wrapper depend on all the dependencies // of the wrapper variant, which will include the common variant's jar file and any JNI // libraries. This is verified by TestBinary. j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), - ctx.ModuleName(), j.wrapperFile) + ctx.ModuleName()+ext, j.wrapperFile) } } @@ -1115,6 +1230,8 @@ func BinaryFactory() android.Module { android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) android.InitDefaultableModule(module) + android.InitBazelModule(module) + return module } @@ -1132,6 +1249,7 @@ func BinaryHostFactory() android.Module { android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) android.InitDefaultableModule(module) + android.InitBazelModule(module) return module } @@ -1153,7 +1271,6 @@ type ImportProperties struct { Installable *bool // If not empty, classes are restricted to the specified packages and their sub-packages. - // This information is used to generate the updatable-bcp-packages.txt file. Permitted_packages []string // List of shared java libs that this module has dependencies to @@ -1195,7 +1312,7 @@ type Import struct { properties ImportProperties // output file containing classes.dex and resources - dexJarFile android.Path + dexJarFile OptionalDexJarPath dexJarInstallFile android.Path combinedClasspathFile android.Path @@ -1280,6 +1397,10 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.hideApexVariantFromMake = true } + if ctx.Windows() { + j.HideFromMake() + } + jars := android.PathsForModuleSrc(ctx, j.properties.Jars) jarName := j.Stem() + ".jar" @@ -1295,7 +1416,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) var flags javaBuilderFlags - var deapexerModule android.Module ctx.VisitDirectDeps(func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) @@ -1316,16 +1436,20 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } addCLCFromDep(ctx, module, j.classLoaderContexts) - - // Save away the `deapexer` module on which this depends, if any. - if tag == android.DeapexerTag { - deapexerModule = module - } }) if Bool(j.properties.Installable) { - ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), - jarName, outputFile) + var installDir android.InstallPath + if ctx.InstallInTestcases() { + var archDir string + if !ctx.Host() { + archDir = ctx.DeviceConfig().DeviceArch() + } + installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) + } else { + installDir = android.PathForModuleInstall(ctx, "framework") + } + ctx.InstallFile(installDir, jarName, outputFile) } j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) @@ -1335,26 +1459,28 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // obtained from the associated deapexer module. ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if ai.ForPrebuiltApex { - if deapexerModule == nil { - // This should never happen as a variant for a prebuilt_apex is only created if the - // deapexer module has been configured to export the dex implementation jar for this module. - ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q", - j.Name(), ai.ApexVariationName) - return - } - // Get the path of the dex implementation jar from the `deapexer` module. - di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) + di := android.FindDeapexerProviderForModule(ctx) + if di == nil { + return // An error has been reported by FindDeapexerProviderForModule. + } if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { - j.dexJarFile = dexOutputPath - j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) + dexJarFile := makeDexJarPathFromPath(dexOutputPath) + j.dexJarFile = dexJarFile + installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) + j.dexJarInstallFile = installPath + + j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath) + setUncompressDex(ctx, &j.dexpreopter, &j.dexer) + j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex + j.dexpreopt(ctx, dexOutputPath) // Initialize the hiddenapi structure. - j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil) + j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex) } else { // This should never happen as a variant for a prebuilt_apex is only created if the // prebuilt_apex has been configured to export the java library dex file. - ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name()) + ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) } } else if Bool(j.dexProperties.Compile_dex) { sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) @@ -1368,11 +1494,9 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Dex compilation - j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName) - if j.dexProperties.Uncompress_dex == nil { - // If the value was not force-set by the user, use reasonable default based on the module. - j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter)) - } + j.dexpreopter.installPath = j.dexpreopter.getInstallPath( + ctx, android.PathForModuleInstall(ctx, "framework", jarName)) + setUncompressDex(ctx, &j.dexpreopter, &j.dexer) j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex var dexOutputFile android.OutputPath @@ -1382,12 +1506,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } // Initialize the hiddenapi structure. - j.initHiddenAPI(ctx, dexOutputFile, outputFile, j.dexProperties.Uncompress_dex) + j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex) // Encode hidden API flags in dex file. dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) - j.dexJarFile = dexOutputFile + j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName) } } @@ -1425,7 +1549,7 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths { return android.Paths{j.combinedClasspathFile} } -func (j *Import) DexJarBuildPath() android.Path { +func (j *Import) DexJarBuildPath() OptionalDexJarPath { return j.dexJarFile } @@ -1488,9 +1612,6 @@ var _ android.IDEInfo = (*Import)(nil) var _ android.IDECustomizedModuleName = (*Import)(nil) // Collect information for opening IDE project files in java/jdeps.go. -const ( - removedPrefix = "prebuilt_" -) func (j *Import) IDEInfo(dpInfo *android.IdeInfo) { dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...) @@ -1509,7 +1630,7 @@ func (j *Import) IsInstallable() bool { return Bool(j.properties.Installable) } -var _ dexpreopterInterface = (*Import)(nil) +var _ DexpreopterInterface = (*Import)(nil) // java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module. // @@ -1570,7 +1691,7 @@ type DexImport struct { properties DexImportProperties - dexJarFile android.Path + dexJarFile OptionalDexJarPath dexpreopter @@ -1622,7 +1743,8 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.hideApexVariantFromMake = true } - j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") + j.dexpreopter.installPath = j.dexpreopter.getInstallPath( + ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") @@ -1660,7 +1782,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { }) } - j.dexJarFile = dexOutputFile + j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) j.dexpreopt(ctx, dexOutputFile) @@ -1670,7 +1792,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } -func (j *DexImport) DexJarBuildPath() android.Path { +func (j *DexImport) DexJarBuildPath() OptionalDexJarPath { return j.dexJarFile } @@ -1839,8 +1961,108 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, // from its CLC should be added to the current CLC. if sdkLib != nil { clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true, - dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) + dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) } else { clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) } } + +type javaLibraryAttributes struct { + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Javacopts bazel.StringListAttribute +} + +func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { + srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)) + attrs := &javaLibraryAttributes{ + Srcs: srcs, + } + + if m.properties.Javacflags != nil { + attrs.Javacopts = bazel.MakeStringListAttribute(m.properties.Javacflags) + } + + if m.properties.Libs != nil { + attrs.Deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.properties.Libs)) + } + + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_library", + Bzl_load_location: "//build/bazel/rules/java:library.bzl", + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) +} + +type javaBinaryHostAttributes struct { + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Main_class string + Jvm_flags bazel.StringListAttribute +} + +// JavaBinaryHostBp2Build is for java_binary_host bp2build. +func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { + mainClass := "" + if m.binaryProperties.Main_class != nil { + mainClass = *m.binaryProperties.Main_class + } + if m.properties.Manifest != nil { + mainClassInManifest, err := android.GetMainClassInManifest(ctx.Config(), android.PathForModuleSrc(ctx, *m.properties.Manifest).String()) + if err != nil { + return + } + mainClass = mainClassInManifest + } + srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)) + attrs := &javaBinaryHostAttributes{ + Srcs: srcs, + Main_class: mainClass, + } + + // Attribute deps + deps := []string{} + if m.properties.Static_libs != nil { + deps = append(deps, m.properties.Static_libs...) + } + if m.binaryProperties.Jni_libs != nil { + deps = append(deps, m.binaryProperties.Jni_libs...) + } + if len(deps) > 0 { + attrs.Deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, deps)) + } + + // Attribute jvm_flags + if m.binaryProperties.Jni_libs != nil { + jniLibPackages := map[string]bool{} + for _, jniLibLabel := range android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs).Includes { + jniLibPackage := jniLibLabel.Label + indexOfColon := strings.Index(jniLibLabel.Label, ":") + if indexOfColon > 0 { + // JNI lib from other package + jniLibPackage = jniLibLabel.Label[2:indexOfColon] + } else if indexOfColon == 0 { + // JNI lib in the same package of java_binary + packageOfCurrentModule := m.GetBazelLabel(ctx, m) + jniLibPackage = packageOfCurrentModule[2:strings.Index(packageOfCurrentModule, ":")] + } + if _, inMap := jniLibPackages[jniLibPackage]; !inMap { + jniLibPackages[jniLibPackage] = true + } + } + jniLibPaths := []string{} + for jniLibPackage, _ := range jniLibPackages { + // See cs/f:.*/third_party/bazel/.*java_stub_template.txt for the use of RUNPATH + jniLibPaths = append(jniLibPaths, "$${RUNPATH}"+jniLibPackage) + } + attrs.Jvm_flags = bazel.MakeStringListAttribute([]string{"-Djava.library.path=" + strings.Join(jniLibPaths, ":")}) + } + + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_binary", + } + + // Create the BazelTargetModule. + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) +} |