diff options
Diffstat (limited to 'java/java.go')
-rw-r--r-- | java/java.go | 331 |
1 files changed, 241 insertions, 90 deletions
diff --git a/java/java.go b/java/java.go index fe7f88f47..bc240508b 100644 --- a/java/java.go +++ b/java/java.go @@ -21,6 +21,7 @@ package java import ( "fmt" "path/filepath" + "sort" "strings" "android/soong/bazel" @@ -63,6 +64,7 @@ func registerJavaBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("dex_import", DexImportFactory) ctx.RegisterModuleType("java_api_library", ApiLibraryFactory) ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory) + ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory) // This mutator registers dependencies on dex2oat for modules that should be // dexpreopted. This is done late when the final variants have been @@ -276,6 +278,9 @@ type JavaInfo struct { // SrcJarDeps is a list of paths to depend on when packaging the sources of this module. SrcJarDeps android.Paths + // The source files of this module and all its transitive static dependencies. + TransitiveSrcFiles *android.DepSet[android.Path] + // ExportedPlugins is a list of paths that should be used as annotation processors for any // module that depends on this module. ExportedPlugins android.Paths @@ -1082,6 +1087,10 @@ func (j *JavaTestImport) InstallInTestcases() bool { return true } +func (j *TestHost) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { + return ctx.DeviceConfig().NativeCoverageEnabled() +} + func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) { if len(j.testHostProperties.Data_device_bins_first) > 0 { deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() @@ -1622,7 +1631,8 @@ func ApiContributionFactory() android.Module { } type JavaApiImportInfo struct { - ApiFile android.Path + ApiFile android.Path + ApiSurface string } var JavaApiImportProvider = blueprint.NewProvider(JavaApiImportInfo{}) @@ -1634,7 +1644,8 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon } ctx.SetProvider(JavaApiImportProvider, JavaApiImportInfo{ - ApiFile: apiFile, + ApiFile: apiFile, + ApiSurface: proptools.String(ap.properties.Api_surface), }) } @@ -1653,6 +1664,8 @@ type ApiLibrary struct { extractedSrcJar android.WritablePath // .dex of stubs, used for hiddenapi processing dexJarFile OptionalDexJarPath + + validationPaths android.Paths } type JavaApiLibraryProperties struct { @@ -1663,11 +1676,6 @@ type JavaApiLibraryProperties struct { // This is a list of Soong modules Api_contributions []string - // list of api.txt files relative to this directory that contribute to the - // API surface. - // This is a list of relative paths - Api_files []string `android:"path"` - // List of flags to be passed to the javac compiler to generate jar file Javacflags []string @@ -1687,6 +1695,18 @@ type JavaApiLibraryProperties struct { // Version of previously released API file for compatibility check. Previous_api *string `android:"path"` + + // java_system_modules module providing the jar to be added to the + // bootclasspath when compiling the stubs. + // The jar will also be passed to metalava as a classpath to + // generate compilable stubs. + System_modules *string + + // If true, the module runs validation on the API signature files provided + // by the modules passed via api_contributions by checking if the files are + // in sync with the source Java files. However, the environment variable + // DISABLE_STUB_VALIDATION has precedence over this property. + Enable_validation *bool } func ApiLibraryFactory() android.Module { @@ -1706,7 +1726,8 @@ func (al *ApiLibrary) StubsJar() android.Path { } func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, - srcs android.Paths, homeDir android.WritablePath) *android.RuleBuilderCommand { + srcs android.Paths, homeDir android.WritablePath, + classpath android.Paths) *android.RuleBuilderCommand { rule.Command().Text("rm -rf").Flag(homeDir.String()) rule.Command().Text("mkdir -p").Flag(homeDir.String()) @@ -1734,7 +1755,6 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, cmd.Flag("--color"). Flag("--quiet"). - Flag("--format=v2"). Flag("--include-annotations"). // The flag makes nullability issues as warnings rather than errors by replacing // @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull, @@ -1746,13 +1766,17 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, FlagWithArg("--hide ", "InvalidNullabilityOverride"). FlagWithArg("--hide ", "ChangedDefault") - // Force metalava to ignore classes on the classpath when an API file contains missing classes. - // See b/285140653 for more information. - cmd.FlagWithArg("--api-class-resolution ", "api") - - // Force metalava to sort overloaded methods by their order in the source code. - // See b/285312164 for more information. - cmd.FlagWithArg("--api-overloaded-method-order ", "source") + if len(classpath) == 0 { + // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore + // classes on the classpath when an API file contains missing classes. However, as this command + // does not specify `--classpath` this is not needed for that. However, this is also used as a + // signal to the special metalava code for generating stubs from text files that it needs to add + // some additional items into the API (e.g. default constructors). + cmd.FlagWithArg("--api-class-resolution ", "api") + } else { + cmd.FlagWithArg("--api-class-resolution ", "api:classpath") + cmd.FlagWithInputList("--classpath ", classpath, ":") + } return cmd } @@ -1771,6 +1795,12 @@ func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBui } } +func (al *ApiLibrary) addValidation(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, validationPaths android.Paths) { + for _, validationPath := range validationPaths { + cmd.Validation(validationPath) + } +} + // This method extracts the stub class files from the stub jar file provided // from full_api_surface_stub module instead of compiling the srcjar generated from invoking metalava. // This method is used because metalava can generate compilable from-text stubs only when @@ -1799,6 +1829,7 @@ func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.Ru Flag("-jar"). Flag("-write_if_changed"). Flag("-ignore_missing_files"). + Flag("-quiet"). FlagWithArg("-C ", unzippedSrcJarDir.String()). FlagWithInput("-l ", classFilesList). FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs) @@ -1806,36 +1837,55 @@ func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.Ru func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { apiContributions := al.properties.Api_contributions + addValidations := !ctx.Config().IsEnvTrue("DISABLE_STUB_VALIDATION") && + proptools.BoolDefault(al.properties.Enable_validation, true) for _, apiContributionName := range apiContributions { ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName) + + // Add the java_api_contribution module generating droidstubs module + // as dependency when validation adding conditions are met and + // the java_api_contribution module name has ".api.contribution" suffix. + // All droidstubs-generated modules possess the suffix in the name, + // but there is no such guarantee for tests. + if addValidations { + if strings.HasSuffix(apiContributionName, ".api.contribution") { + ctx.AddDependency(ctx.Module(), metalavaCurrentApiTimestampTag, strings.TrimSuffix(apiContributionName, ".api.contribution")) + } else { + ctx.ModuleErrorf("Validation is enabled for module %s but a "+ + "current timestamp provider is not found for the api "+ + "contribution %s", + ctx.ModuleName(), + apiContributionName, + ) + } + } } ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...) ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...) if al.properties.Full_api_surface_stub != nil { ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Full_api_surface_stub)) } + if al.properties.System_modules != nil { + ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules)) + } } -// API signature file names sorted from -// the narrowest api scope to the widest api scope -var scopeOrderedSourceFileNames = allApiScopes.Strings( - func(s *apiScope) string { return s.apiFilePrefix + "current.txt" }) - -func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFiles android.Paths) android.Paths { - sortedSrcFiles := android.Paths{} +// Map where key is the api scope name and value is the int value +// representing the order of the api scope, narrowest to the widest +var scopeOrderMap = allApiScopes.MapToIndex( + func(s *apiScope) string { return s.name }) - for _, scopeSourceFileName := range scopeOrderedSourceFileNames { - for _, sourceFileName := range srcFiles { - if sourceFileName.Base() == scopeSourceFileName { - sortedSrcFiles = append(sortedSrcFiles, sourceFileName) - } +func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo { + for _, srcFileInfo := range srcFilesInfo { + if srcFileInfo.ApiSurface == "" { + ctx.ModuleErrorf("Api surface not defined for the associated api file %s", srcFileInfo.ApiFile) } } - if len(srcFiles) != len(sortedSrcFiles) { - ctx.ModuleErrorf("Unrecognizable source file found within %s", srcFiles) - } + sort.Slice(srcFilesInfo, func(i, j int) bool { + return scopeOrderMap[srcFilesInfo[i].ApiSurface] < scopeOrderMap[srcFilesInfo[j].ApiSurface] + }) - return sortedSrcFiles + return srcFilesInfo } func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -1846,27 +1896,26 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { android.PathForModuleOut(ctx, "metalava.sbox.textproto")). SandboxInputs() - var stubsDir android.OptionalPath - stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir")) + stubsDir := android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir")) rule.Command().Text("rm -rf").Text(stubsDir.String()) rule.Command().Text("mkdir -p").Text(stubsDir.String()) homeDir := android.PathForModuleOut(ctx, "metalava", "home") - var srcFiles android.Paths + var srcFilesInfo []JavaApiImportInfo var classPaths android.Paths var staticLibs android.Paths var depApiSrcsStubsJar android.Path + var systemModulesPaths android.Paths ctx.VisitDirectDeps(func(dep android.Module) { tag := ctx.OtherModuleDependencyTag(dep) switch tag { case javaApiContributionTag: provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo) - providerApiFile := provider.ApiFile - if providerApiFile == nil && !ctx.Config().AllowMissingDependencies() { + if provider.ApiFile == nil && !ctx.Config().AllowMissingDependencies() { ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name()) } - srcFiles = append(srcFiles, android.PathForSource(ctx, providerApiFile.String())) + srcFilesInfo = append(srcFilesInfo, provider) case libTag: provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) classPaths = append(classPaths, provider.HeaderJars...) @@ -1876,21 +1925,27 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { case depApiSrcsTag: provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) depApiSrcsStubsJar = provider.HeaderJars[0] + case systemModulesTag: + module := dep.(SystemModulesProvider) + systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...) + case metalavaCurrentApiTimestampTag: + if currentApiTimestampProvider, ok := dep.(currentApiTimestampProvider); ok { + al.validationPaths = append(al.validationPaths, currentApiTimestampProvider.CurrentApiTimestamp()) + } } }) - // Add the api_files inputs - for _, api := range al.properties.Api_files { - srcFiles = append(srcFiles, android.PathForModuleSrc(ctx, api)) + srcFilesInfo = al.sortApiFilesByApiScope(ctx, srcFilesInfo) + var srcFiles android.Paths + for _, srcFileInfo := range srcFilesInfo { + srcFiles = append(srcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String())) } if srcFiles == nil && !ctx.Config().AllowMissingDependencies() { ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) } - srcFiles = al.sortApiFilesByApiScope(ctx, srcFiles) - - cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir) + cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths) al.stubsFlags(ctx, cmd, stubsDir) @@ -1900,6 +1955,8 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { cmd.FlagWithInput("--migrate-nullness ", previousApi) } + al.addValidation(ctx, cmd, al.validationPaths) + al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar") al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, "metalava", "stubs.jar") al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName())) @@ -1915,13 +1972,14 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { FlagWithArg("-C ", stubsDir.String()). FlagWithArg("-D ", stubsDir.String()) - rule.Build("metalava", "metalava merged") + rule.Build("metalava", "metalava merged text") if depApiSrcsStubsJar == nil { var flags javaBuilderFlags flags.javaVersion = getStubsJavaVersion() flags.javacFlags = strings.Join(al.properties.Javacflags, " ") flags.classpath = classpath(classPaths) + flags.bootClasspath = classpath(systemModulesPaths) annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar") @@ -2756,32 +2814,41 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, type javaResourcesAttributes struct { Resources bazel.LabelListAttribute Resource_strip_prefix *string + Additional_resources bazel.LabelListAttribute `blueprint:"mutated"` } -func (m *Library) javaResourcesGetSingleFilegroupStripPrefix(ctx android.TopDownMutatorContext) (string, bool) { - if otherM, ok := ctx.ModuleFromName(m.properties.Java_resources[0]); ok && len(m.properties.Java_resources) == 1 { +func (m *Library) getResourceFilegroupStripPrefix(ctx android.Bp2buildMutatorContext, resourceFilegroup string) (*string, bool) { + if otherM, ok := ctx.ModuleFromName(resourceFilegroup); ok { if fg, isFilegroup := otherM.(android.FileGroupPath); isFilegroup { - return filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx)), true + return proptools.StringPtr(filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx))), true } } - return "", false + return proptools.StringPtr(""), false } -func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorContext) *javaResourcesAttributes { +func (m *Library) convertJavaResourcesAttributes(ctx android.Bp2buildMutatorContext) *javaResourcesAttributes { var resources bazel.LabelList var resourceStripPrefix *string - if m.properties.Java_resources != nil && len(m.properties.Java_resource_dirs) > 0 { - ctx.ModuleErrorf("bp2build doesn't support both java_resources and java_resource_dirs being set on the same module.") - } + additionalJavaResourcesMap := make(map[string]*javaResourcesAttributes) if m.properties.Java_resources != nil { - if prefix, ok := m.javaResourcesGetSingleFilegroupStripPrefix(ctx); ok { - resourceStripPrefix = proptools.StringPtr(prefix) - } else { + for _, res := range m.properties.Java_resources { + if prefix, isFilegroup := m.getResourceFilegroupStripPrefix(ctx, res); isFilegroup { + otherM, _ := ctx.ModuleFromName(res) + resourcesTargetName := ctx.ModuleName() + "_filegroup_resources_" + otherM.Name() + additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{ + Resources: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{res})), + Resource_strip_prefix: prefix, + } + } else { + resources.Append(android.BazelLabelForModuleSrc(ctx, []string{res})) + } + } + + if !resources.IsEmpty() { resourceStripPrefix = proptools.StringPtr(ctx.ModuleDir()) } - resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources)) } //TODO(b/179889880) handle case where glob includes files outside package @@ -2792,23 +2859,51 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte m.properties.Exclude_java_resources, ) - for i, resDep := range resDeps { + for _, resDep := range resDeps { dir, files := resDep.dir, resDep.files - resources.Append(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files))) - // Bazel includes the relative path from the WORKSPACE root when placing the resource // inside the JAR file, so we need to remove that prefix - resourceStripPrefix = proptools.StringPtr(dir.String()) - if i > 0 { - // TODO(b/226423379) allow multiple resource prefixes - ctx.ModuleErrorf("bp2build does not support more than one directory in java_resource_dirs (b/226423379)") + prefix := proptools.StringPtr(dir.String()) + resourcesTargetName := ctx.ModuleName() + "_resource_dir_" + dir.String() + additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{ + Resources: bazel.MakeLabelListAttribute(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files))), + Resource_strip_prefix: prefix, + } + } + + var additionalResourceLabels bazel.LabelList + if len(additionalJavaResourcesMap) > 0 { + var additionalResources []string + for resName, _ := range additionalJavaResourcesMap { + additionalResources = append(additionalResources, resName) } + sort.Strings(additionalResources) + + for i, resName := range additionalResources { + resAttr := additionalJavaResourcesMap[resName] + if resourceStripPrefix == nil && i == 0 { + resourceStripPrefix = resAttr.Resource_strip_prefix + resources = resAttr.Resources.Value + } else if !resAttr.Resources.IsEmpty() { + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "java_resources", + Bzl_load_location: "//build/bazel/rules/java:java_resources.bzl", + }, + android.CommonAttributes{Name: resName}, + resAttr, + ) + additionalResourceLabels.Append(android.BazelLabelForModuleSrc(ctx, []string{resName})) + } + } + } return &javaResourcesAttributes{ Resources: bazel.MakeLabelListAttribute(resources), Resource_strip_prefix: resourceStripPrefix, + Additional_resources: bazel.MakeLabelListAttribute(additionalResourceLabels), } } @@ -2821,6 +2916,7 @@ type javaCommonAttributes struct { Sdk_version bazel.StringAttribute Java_version bazel.StringAttribute Errorprone_force_enable bazel.BoolAttribute + Javac_shard_size *int64 } type javaDependencyLabels struct { @@ -2862,15 +2958,25 @@ func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string { // which has other non-attribute information needed for bp2build conversion // that needs different handling depending on the module types, and thus needs // to be returned to the calling function. -func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) { +func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) { var srcs bazel.LabelListAttribute var deps bazel.LabelListAttribute var staticDeps bazel.LabelListAttribute + if proptools.String(m.deviceProperties.Sdk_version) == "" && m.DeviceSupported() { + // TODO(b/297356704): handle platform apis in bp2build + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version unset") + return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false + } else if proptools.String(m.deviceProperties.Sdk_version) == "core_platform" { + // TODO(b/297356582): handle core_platform in bp2build + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version core_platform") + return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false + } + archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) for axis, configToProps := range archVariantProps { - for config, _props := range configToProps { - if archProps, ok := _props.(*CommonProperties); ok { + for config, p := range configToProps { + if archProps, ok := p.(*CommonProperties); ok { archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs) srcs.SetSelectValue(axis, config, archSrcs) if archProps.Jarjar_rules != nil { @@ -2880,6 +2986,11 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } } } + srcs.Append( + bazel.MakeLabelListAttribute( + android.BazelLabelForModuleSrcExcludes(ctx, + m.properties.Openjdk9.Srcs, + m.properties.Exclude_srcs))) srcs.ResolveExcludes() javaSrcPartition := "java" @@ -2963,8 +3074,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) plugins := bazel.MakeLabelListAttribute( android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), ) - if m.properties.Javacflags != nil { - javacopts = bazel.MakeStringListAttribute(m.properties.Javacflags) + if m.properties.Javacflags != nil || m.properties.Openjdk9.Javacflags != nil { + javacopts = bazel.MakeStringListAttribute( + append(append([]string{}, m.properties.Javacflags...), m.properties.Openjdk9.Javacflags...)) } epEnabled := m.properties.Errorprone.Enabled @@ -2980,14 +3092,17 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) javacopts.Append(bazel.MakeStringListAttribute([]string{"-XepDisableAllChecks"})) } + resourcesAttrs := m.convertJavaResourcesAttributes(ctx) + commonAttrs := &javaCommonAttributes{ Srcs: javaSrcs, - javaResourcesAttributes: m.convertJavaResourcesAttributes(ctx), + javaResourcesAttributes: resourcesAttrs, Plugins: plugins, Javacopts: javacopts, Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, Errorprone_force_enable: errorproneForceEnable, + Javac_shard_size: m.properties.Javac_shard_size, } for axis, configToProps := range archVariantProps { @@ -3004,18 +3119,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } } - protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition]) - // Soong does not differentiate between a java_library and the Bazel equivalent of - // a java_proto_library + proto_library pair. Instead, in Soong proto sources are - // listed directly in the srcs of a java_library, and the classes produced - // by protoc are included directly in the resulting JAR. Thus upstream dependencies - // that depend on a java_library with proto sources can link directly to the protobuf API, - // and so this should be a static dependency. - if protoDepLabel != nil { - staticDeps.Append(bazel.MakeSingleLabelListAttribute(*protoDepLabel)) - } - depLabels := &javaDependencyLabels{} + deps.Append(resourcesAttrs.Additional_resources) depLabels.Deps = deps for axis, configToProps := range archVariantProps { @@ -3030,6 +3135,20 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } depLabels.StaticDeps.Append(staticDeps) + var additionalProtoDeps bazel.LabelListAttribute + additionalProtoDeps.Append(depLabels.Deps) + additionalProtoDeps.Append(depLabels.StaticDeps) + protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition], additionalProtoDeps) + // Soong does not differentiate between a java_library and the Bazel equivalent of + // a java_proto_library + proto_library pair. Instead, in Soong proto sources are + // listed directly in the srcs of a java_library, and the classes produced + // by protoc are included directly in the resulting JAR. Thus upstream dependencies + // that depend on a java_library with proto sources can link directly to the protobuf API, + // and so this should be a static dependency. + if protoDepLabel != nil { + depLabels.StaticDeps.Append(bazel.MakeSingleLabelListAttribute(*protoDepLabel)) + } + hasKotlin := !kotlinSrcs.IsEmpty() commonAttrs.kotlinAttributes = &kotlinAttributes{ Kotlincflags: &m.properties.Kotlincflags, @@ -3073,7 +3192,7 @@ func javaLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties } } -func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { +func javaLibraryBp2Build(ctx android.Bp2buildMutatorContext, m *Library) { commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) if !supported { return @@ -3081,16 +3200,22 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps + exports := depLabels.StaticDeps if !commonAttrs.Srcs.IsEmpty() { - deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them + deps.Append(exports) // we should only append these if there are sources to use them } else if !deps.IsEmpty() { - ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") + // java_library does not accept deps when there are no srcs because + // there is no compilation happening, but it accepts exports. + // The non-empty deps here are unnecessary as deps on the java_library + // since they aren't being propagated to any dependencies. + // So we can drop deps here. + deps = bazel.LabelListAttribute{} } var props bazel.BazelTargetModuleProperties attrs := &javaLibraryAttributes{ javaCommonAttributes: commonAttrs, Deps: deps, - Exports: depLabels.StaticDeps, + Exports: exports, } name := m.Name() @@ -3123,7 +3248,7 @@ type javaBinaryHostAttributes struct { } // JavaBinaryHostBp2Build is for java_binary_host bp2build. -func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { +func javaBinaryHostBp2Build(ctx android.Bp2buildMutatorContext, m *Binary) { commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) if !supported { return @@ -3210,7 +3335,7 @@ type javaTestHostAttributes struct { } // javaTestHostBp2Build is for java_test_host bp2build. -func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) { +func javaTestHostBp2Build(ctx android.Bp2buildMutatorContext, m *TestHost) { commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) if !supported { return @@ -3263,7 +3388,7 @@ type libraryCreationInfo struct { // helper function that creates java_library target from java_binary_host or java_test_host, // and returns the library target name, -func createLibraryTarget(ctx android.TopDownMutatorContext, libInfo libraryCreationInfo) string { +func createLibraryTarget(ctx android.Bp2buildMutatorContext, libInfo libraryCreationInfo) string { libName := libInfo.baseName + "_lib" var libProps bazel.BazelTargetModuleProperties if libInfo.hasKotlin { @@ -3286,7 +3411,7 @@ type bazelJavaImportAttributes struct { } // java_import bp2Build converter. -func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (i *Import) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { var jars bazel.LabelListAttribute archVariantProps := i.GetArchVariantProperties(ctx, &ImportProperties{}) for axis, configToProps := range archVariantProps { @@ -3322,7 +3447,6 @@ func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { javaLibraryBazelTargetModuleProperties(), android.CommonAttributes{Name: name + "-neverlink"}, neverlinkAttrs) - } var _ android.MixedBuildBuildable = (*Import)(nil) @@ -3375,3 +3499,30 @@ func (i *Import) QueueBazelCall(ctx android.BaseModuleContext) { func (i *Import) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { return true } + +type JavaApiContributionImport struct { + JavaApiContribution + + prebuilt android.Prebuilt +} + +func ApiContributionImportFactory() android.Module { + module := &JavaApiContributionImport{} + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + android.InitPrebuiltModule(module, &[]string{""}) + module.AddProperties(&module.properties) + return module +} + +func (module *JavaApiContributionImport) Prebuilt() *android.Prebuilt { + return &module.prebuilt +} + +func (module *JavaApiContributionImport) Name() string { + return module.prebuilt.Name(module.ModuleBase.Name()) +} + +func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { + ap.JavaApiContribution.GenerateAndroidBuildActions(ctx) +} |