diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 330 |
1 files changed, 275 insertions, 55 deletions
diff --git a/java/java.go b/java/java.go index 0dfb968e9..77ab40279 100644 --- a/java/java.go +++ b/java/java.go @@ -24,6 +24,7 @@ import ( "strings" "android/soong/bazel" + "android/soong/bazel/cquery" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -118,6 +119,16 @@ var ( copyEverythingToSnapshot, } + snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool { + // In the S build the build will break if updatable-media does not provide a full implementation + // jar. That issue was fixed in Tiramisu by b/229932396. + if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" { + return true + } + + return false + } + // Supports adding java boot libraries to module_exports and sdk. // // The build has some implicit dependencies (via the boot jars configuration) on a number of @@ -135,13 +146,21 @@ var ( SupportsSdk: true, }, func(ctx android.SdkMemberContext, j *Library) android.Path { + if snapshotRequiresImplementationJar(ctx) { + return exportImplementationClassesJar(ctx, j) + } + // Java boot libs are only provided in the SDK to provide access to their dex implementation // jar for use by dexpreopting and boot jars package check. 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 { + func(ctx android.SdkMemberContext, osPrefix, name string) string { + if snapshotRequiresImplementationJar(ctx) { + return sdkSnapshotFilePathForJar(ctx, osPrefix, name) + } + // 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. @@ -164,6 +183,9 @@ var ( android.SdkMemberTypeBase{ PropertyName: "java_systemserver_libs", SupportsSdk: true, + + // This was only added in Tiramisu. + SupportedBuildReleaseSpecification: "Tiramisu+", }, func(ctx android.SdkMemberContext, j *Library) android.Path { // Java systemserver libs are only provided in the SDK to provide access to their dex @@ -172,7 +194,7 @@ var ( // file. Any attempt to use that file as a jar will cause a build error. return ctx.SnapshotBuilder().EmptyFile() }, - func(osPrefix, name string) string { + func(_ android.SdkMemberContext, 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. @@ -510,6 +532,20 @@ func (v javaVersion) String() string { } } +func (v javaVersion) StringForKotlinc() string { + // $ ./external/kotlinc/bin/kotlinc -jvm-target foo + // error: unknown JVM target version: foo + // Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 + switch v { + case JAVA_VERSION_7: + return "1.6" + case JAVA_VERSION_9: + return "9" + default: + return v.String() + } +} + // Returns true if javac targeting this version uses system modules instead of a bootclasspath. func (v javaVersion) usesJavaModules() bool { return v >= 9 @@ -528,7 +564,7 @@ func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) jav case "11": return JAVA_VERSION_11 case "17": - return JAVA_VERSION_11 + return JAVA_VERSION_17 case "10", "12", "13", "14", "15", "16": ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion) return JAVA_VERSION_UNSUPPORTED @@ -655,7 +691,7 @@ const ( ) // path to the jar file of a java library. Relative to <sdk_root>/<api_dir> -func sdkSnapshotFilePathForJar(osPrefix, name string) string { +func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string { return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix) } @@ -672,7 +708,7 @@ type librarySdkMemberType struct { // Function to compute the snapshot relative path to which the named library's // jar should be copied. - snapshotPathGetter func(osPrefix, name string) string + snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string // True if only the jar should be copied to the snapshot, false if the jar plus any additional // files like aidl files should also be copied. @@ -730,7 +766,7 @@ func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberConte exportedJar := p.JarToExport if exportedJar != nil { // Delegate the creation of the snapshot relative path to the member type. - snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(p.OsPrefix(), ctx.Name()) + snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name()) // Copy the exported jar to the snapshot. builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) @@ -864,7 +900,25 @@ type hostTestProperties struct { Data_native_bins []string `android:"arch_variant"` // list of device binary modules that should be installed alongside the test - Data_device_bins []string `android:"arch_variant"` + // This property only adds the first variant of the dependency + Data_device_bins_first []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property adds 64bit AND 32bit variants of the dependency + Data_device_bins_both []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property only adds 64bit variants of the dependency + Data_device_bins_64 []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property adds 32bit variants of the dependency if available, or else + // defaults to the 64bit variant + Data_device_bins_prefer32 []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + // This property only adds 32bit variants of the dependency + Data_device_bins_32 []string `android:"arch_variant"` } type testHelperLibraryProperties struct { @@ -931,6 +985,83 @@ func (j *JavaTestImport) InstallInTestcases() bool { return true } +func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) { + if len(j.testHostProperties.Data_device_bins_first) > 0 { + deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() + ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...) + } + + var maybeAndroid32Target *android.Target + var maybeAndroid64Target *android.Target + android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32") + android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64") + if len(android32TargetList) > 0 { + maybeAndroid32Target = &android32TargetList[0] + } + if len(android64TargetList) > 0 { + maybeAndroid64Target = &android64TargetList[0] + } + + if len(j.testHostProperties.Data_device_bins_both) > 0 { + if maybeAndroid32Target == nil && maybeAndroid64Target == nil { + ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets) + return + } + if maybeAndroid32Target != nil { + ctx.AddFarVariationDependencies( + maybeAndroid32Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_both..., + ) + } + if maybeAndroid64Target != nil { + ctx.AddFarVariationDependencies( + maybeAndroid64Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_both..., + ) + } + } + + if len(j.testHostProperties.Data_device_bins_prefer32) > 0 { + if maybeAndroid32Target != nil { + ctx.AddFarVariationDependencies( + maybeAndroid32Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_prefer32..., + ) + } else { + if maybeAndroid64Target == nil { + ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets) + return + } + ctx.AddFarVariationDependencies( + maybeAndroid64Target.Variations(), + dataDeviceBinsTag, + j.testHostProperties.Data_device_bins_prefer32..., + ) + } + } + + if len(j.testHostProperties.Data_device_bins_32) > 0 { + if maybeAndroid32Target == nil { + ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets) + return + } + deviceVariations := maybeAndroid32Target.Variations() + ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...) + } + + if len(j.testHostProperties.Data_device_bins_64) > 0 { + if maybeAndroid64Target == nil { + ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets) + return + } + deviceVariations := maybeAndroid64Target.Variations() + ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...) + } +} + func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { if len(j.testHostProperties.Data_native_bins) > 0 { for _, target := range ctx.MultiTargets() { @@ -938,11 +1069,6 @@ func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { } } - if len(j.testHostProperties.Data_device_bins) > 0 { - deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() - ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins...) - } - if len(j.testProperties.Jni_libs) > 0 { for _, target := range ctx.MultiTargets() { sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) @@ -950,6 +1076,8 @@ func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { } } + j.addDataDeviceBinsDeps(ctx) + j.deps(ctx) } @@ -957,17 +1085,40 @@ func (j *TestHost) AddExtraResource(p android.Path) { j.extraResources = append(j.extraResources, p) } +func (j *TestHost) dataDeviceBins() []string { + ret := make([]string, 0, + len(j.testHostProperties.Data_device_bins_first)+ + len(j.testHostProperties.Data_device_bins_both)+ + len(j.testHostProperties.Data_device_bins_prefer32)+ + len(j.testHostProperties.Data_device_bins_32)+ + len(j.testHostProperties.Data_device_bins_64), + ) + + ret = append(ret, j.testHostProperties.Data_device_bins_first...) + ret = append(ret, j.testHostProperties.Data_device_bins_both...) + ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...) + ret = append(ret, j.testHostProperties.Data_device_bins_32...) + ret = append(ret, j.testHostProperties.Data_device_bins_64...) + + return ret +} + func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { var configs []tradefed.Config - if len(j.testHostProperties.Data_device_bins) > 0 { + dataDeviceBins := j.dataDeviceBins() + if len(dataDeviceBins) > 0 { // add Tradefed configuration to push device bins to device for testing remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name()) options := []tradefed.Option{{Name: "cleanup", Value: "true"}} - for _, bin := range j.testHostProperties.Data_device_bins { + for _, bin := range dataDeviceBins { fullPath := filepath.Join(remoteDir, bin) options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath}) } - configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options}) + configs = append(configs, tradefed.Object{ + Type: "target_preparer", + Class: "com.android.tradefed.targetprep.PushFilePreparer", + Options: options, + }) } j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) @@ -1081,7 +1232,7 @@ func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, exportedJar := p.JarToExport if exportedJar != nil { - snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name()) + snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(ctx, p.OsPrefix(), ctx.Name()) builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) @@ -1111,7 +1262,7 @@ func TestFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true - module.Module.linter.test = true + module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) android.InitSdkAwareModule(module) InitJavaModule(module, android.HostAndDeviceSupported) @@ -1127,7 +1278,7 @@ func TestHelperLibraryFactory() android.Module { module.Module.properties.Installable = proptools.BoolPtr(true) module.Module.dexpreopter.isTest = true - module.Module.linter.test = true + module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) InitJavaModule(module, android.HostAndDeviceSupported) return module @@ -1327,6 +1478,10 @@ type ImportProperties struct { // specified. Min_sdk_version *string + // The max sdk version placeholder used to replace maxSdkVersion attributes on permission + // and uses-permission tags in manifest_fixer. + Replace_max_sdk_version_placeholder *string + Installable *bool // If not empty, classes are restricted to the specified packages and their sub-packages. @@ -1406,6 +1561,13 @@ func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return j.SdkVersion(ctx) } +func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { + if j.properties.Replace_max_sdk_version_placeholder != nil { + return android.SdkSpecFrom(ctx, *j.properties.Replace_max_sdk_version_placeholder) + } + return android.SdkSpecFrom(ctx, "") +} + func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return j.SdkVersion(ctx) } @@ -1449,7 +1611,8 @@ func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { } } -func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { +func (j *Import) commonBuildActions(ctx android.ModuleContext) { + //TODO(b/231322772) these should come from Bazel once available j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) @@ -1460,6 +1623,10 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { if ctx.Windows() { j.HideFromMake() } +} + +func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { + j.commonBuildActions(ctx) jars := android.PathsForModuleSrc(ctx, j.properties.Jars) @@ -1501,19 +1668,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { addCLCFromDep(ctx, module, j.classLoaderContexts) }) - if Bool(j.properties.Installable) { - 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.maybeInstall(ctx, jarName, outputFile) j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) @@ -1587,6 +1742,24 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { }) } +func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) { + if !Bool(j.properties.Installable) { + return + } + + 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) +} + func (j *Import) OutputFiles(tag string) (android.Paths, error) { switch tag { case "", ".jar": @@ -1885,9 +2058,7 @@ func DexImportFactory() android.Module { return module } -// // Defaults -// type Defaults struct { android.ModuleBase android.DefaultsModuleBase @@ -1902,29 +2073,29 @@ type Defaults struct { // // Example: // -// java_defaults { -// name: "example_defaults", -// srcs: ["common/**/*.java"], -// javacflags: ["-Xlint:all"], -// aaptflags: ["--auto-add-overlay"], -// } +// java_defaults { +// name: "example_defaults", +// srcs: ["common/**/*.java"], +// javacflags: ["-Xlint:all"], +// aaptflags: ["--auto-add-overlay"], +// } // -// java_library { -// name: "example", -// defaults: ["example_defaults"], -// srcs: ["example/**/*.java"], -// } +// java_library { +// name: "example", +// defaults: ["example_defaults"], +// srcs: ["example/**/*.java"], +// } // // is functionally identical to: // -// java_library { -// name: "example", -// srcs: [ -// "common/**/*.java", -// "example/**/*.java", -// ], -// javacflags: ["-Xlint:all"], -// } +// java_library { +// name: "example", +// srcs: [ +// "common/**/*.java", +// "example/**/*.java", +// ], +// javacflags: ["-Xlint:all"], +// } func DefaultsFactory() android.Module { module := &Defaults{} @@ -2162,12 +2333,12 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) var deps bazel.LabelList if m.properties.Libs != nil { - deps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Libs)) + deps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Libs)))) } var staticDeps bazel.LabelList if m.properties.Static_libs != nil { - staticDeps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Static_libs)) + staticDeps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Static_libs)))) } protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition]) @@ -2322,5 +2493,54 @@ func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { props := bazel.BazelTargetModuleProperties{Rule_class: "java_import"} ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: android.RemoveOptionalPrebuiltPrefix(i.Name())}, attrs) +} + +var _ android.MixedBuildBuildable = (*Import)(nil) + +func (i *Import) getBazelModuleLabel(ctx android.BaseModuleContext) string { + return android.RemoveOptionalPrebuiltPrefixFromBazelLabel(i.GetBazelLabel(ctx, i)) +} + +func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) { + i.commonBuildActions(ctx) + + bazelCtx := ctx.Config().BazelContext + filePaths, err := bazelCtx.GetOutputFiles(i.getBazelModuleLabel(ctx), android.GetConfigKey(ctx)) + if err != nil { + ctx.ModuleErrorf(err.Error()) + return + } + + bazelJars := android.Paths{} + for _, bazelOutputFile := range filePaths { + bazelJars = append(bazelJars, android.PathForBazelOut(ctx, bazelOutputFile)) + } + + jarName := android.RemoveOptionalPrebuiltPrefix(i.Name()) + ".jar" + outputFile := android.PathForModuleOut(ctx, "bazelCombined", jarName) + TransformJarsToJar(ctx, outputFile, "combine prebuilt jars", bazelJars, + android.OptionalPath{}, // manifest + false, // stripDirEntries + []string{}, // filesToStrip + []string{}, // dirsToStrip + ) + i.combinedClasspathFile = outputFile + + ctx.SetProvider(JavaInfoProvider, JavaInfo{ + HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile), + ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile), + ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile), + //TODO(b/240308299) include AIDL information from Bazel + }) + + i.maybeInstall(ctx, jarName, outputFile) +} +func (i *Import) QueueBazelCall(ctx android.BaseModuleContext) { + bazelCtx := ctx.Config().BazelContext + bazelCtx.QueueBazelRequest(i.getBazelModuleLabel(ctx), cquery.GetOutputFiles, android.GetConfigKey(ctx)) +} + +func (i *Import) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { + return true } |