diff options
Diffstat (limited to 'java/java.go')
| -rw-r--r-- | java/java.go | 230 |
1 files changed, 164 insertions, 66 deletions
diff --git a/java/java.go b/java/java.go index 011dc1c54..4b01c316d 100644 --- a/java/java.go +++ b/java/java.go @@ -21,11 +21,13 @@ package java import ( "fmt" "path/filepath" + "sort" "strings" "android/soong/bazel" "android/soong/bazel/cquery" "android/soong/remoteexec" + "android/soong/ui/metrics/bp2build_metrics_proto" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -224,6 +226,23 @@ var ( }, "jar_name", "partition", "main_class") ) +type ProguardSpecInfo struct { + // If true, proguard flags files will be exported to reverse dependencies across libs edges + // If false, proguard flags files will only be exported to reverse dependencies across + // static_libs edges. + Export_proguard_flags_files bool + + // TransitiveDepsProguardSpecFiles is a depset of paths to proguard flags files that are exported from + // all transitive deps. This list includes all proguard flags files from transitive static dependencies, + // and all proguard flags files from transitive libs dependencies which set `export_proguard_spec: true`. + ProguardFlagsFiles *android.DepSet[android.Path] + + // implementation detail to store transitive proguard flags files from exporting shared deps + UnconditionallyExportedProguardFlags *android.DepSet[android.Path] +} + +var ProguardSpecInfoProvider = blueprint.NewProvider(ProguardSpecInfo{}) + // JavaInfo contains information about a java module for use by modules that depend on it. type JavaInfo struct { // HeaderJars is a list of jars that can be passed as the javac classpath in order to link @@ -274,7 +293,14 @@ type JavaInfo struct { // instrumented by jacoco. JacocoReportClassesFile android.Path - // TODO: Add device config declarations here? + // set of aconfig flags for all transitive libs deps + // TODO(joeo): It would be nice if this were over in the aconfig package instead of here. + // In order to do that, generated_java_library would need a way doing + // collectTransitiveAconfigFiles with one of the callbacks, and having that automatically + // propagated. If we were to clean up more of the stuff on JavaInfo that's not part of + // core java rules (e.g. AidlIncludeDirs), then maybe adding more framework to do that would be + // worth it. + TransitiveAconfigFiles *android.DepSet[android.Path] } var JavaInfoProvider = blueprint.NewProvider(JavaInfo{}) @@ -302,11 +328,6 @@ type UsesLibraryDependency interface { ClassLoaderContexts() dexpreopt.ClassLoaderContextMap } -// Provides transitive Proguard flag files to downstream DEX jars. -type LibraryDependency interface { - ExportedProguardFlagFiles() android.Paths -} - // TODO(jungjw): Move this to kythe.go once it's created. type xref interface { XrefJavaFiles() android.Paths @@ -618,12 +639,6 @@ type Library struct { InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) } -var _ LibraryDependency = (*Library)(nil) - -func (j *Library) ExportedProguardFlagFiles() android.Paths { - return j.exportedProguardFlagFiles -} - var _ android.ApexModule = (*Library)(nil) // Provides access to the list of permitted packages from apex boot jars. @@ -676,12 +691,15 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.minSdkVersion = j.MinSdkVersion(ctx) j.maxSdkVersion = j.MaxSdkVersion(ctx) + j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName()) + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if !apexInfo.IsForPlatform() { j.hideApexVariantFromMake = true } j.checkSdkVersions(ctx) + j.checkHeadersOnly(ctx) if ctx.Device() { j.dexpreopter.installPath = j.dexpreopter.getInstallPath( ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) @@ -690,7 +708,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) } - j.compile(ctx, nil) + j.compile(ctx, nil, nil, nil) // Collect the module directory for IDE info in java/jdeps.go. j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) @@ -720,14 +738,9 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) } - j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles, - android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)...) - ctx.VisitDirectDeps(func(m android.Module) { - if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag { - j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...) - } - }) - j.exportedProguardFlagFiles = android.FirstUniquePaths(j.exportedProguardFlagFiles) + proguardSpecInfo := j.collectProguardSpecInfo(ctx) + ctx.SetProvider(ProguardSpecInfoProvider, proguardSpecInfo) + j.exportedProguardFlagFiles = proguardSpecInfo.ProguardFlagsFiles.ToList() } func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { @@ -1468,6 +1481,8 @@ func (j *Binary) HostToolPath() android.OptionalPath { } func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName()) + if ctx.Arch().ArchType == android.Common { // Compile the jar if j.binaryProperties.Main_class != nil { @@ -1670,6 +1685,9 @@ type JavaApiLibraryProperties struct { // extracting the compiled class files provided by the // full_api_surface_stub module. Full_api_surface_stub *string + + // Version of previously released API file for compatibility check. + Previous_api *string `android:"path"` } func ApiLibraryFactory() android.Module { @@ -1713,7 +1731,6 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")). Flag(config.JavacVmFlags). Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED"). - FlagWithArg("-encoding ", "UTF-8"). FlagWithInputList("--source-files ", srcs, " ") cmd.Flag("--color"). @@ -1800,6 +1817,28 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { } } +// 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{} + + for _, scopeSourceFileName := range scopeOrderedSourceFileNames { + for _, sourceFileName := range srcFiles { + if sourceFileName.Base() == scopeSourceFileName { + sortedSrcFiles = append(sortedSrcFiles, sourceFileName) + } + } + } + if len(srcFiles) != len(sortedSrcFiles) { + ctx.ModuleErrorf("Unrecognizable source file found within %s", srcFiles) + } + + return sortedSrcFiles +} + func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule := android.NewRuleBuilder(pctx, ctx) @@ -1850,10 +1889,18 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) } + srcFiles = al.sortApiFilesByApiScope(ctx, srcFiles) + cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir) al.stubsFlags(ctx, cmd, stubsDir) + migratingNullability := String(al.properties.Previous_api) != "" + if migratingNullability { + previousApi := android.PathForModuleSrc(ctx, String(al.properties.Previous_api)) + cmd.FlagWithInput("--migrate-nullness ", previousApi) + } + 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())) @@ -1912,6 +1959,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar), ImplementationJars: android.PathsIfNonNil(al.stubsJar), AidlIncludeDirs: android.Paths{}, + // No aconfig libraries on api libraries }) } @@ -2233,6 +2281,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), AidlIncludeDirs: j.exportAidlIncludeDirs, + // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }) } @@ -2653,7 +2702,7 @@ func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonC var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String -var inList = android.InList +var inList = android.InList[string] // Add class loader context (CLC) of a given dependency to the current CLC. func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, @@ -2708,32 +2757,41 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, type javaResourcesAttributes struct { Resources bazel.LabelListAttribute Resource_strip_prefix *string + Additional_resources bazel.LabelListAttribute } -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.TopDownMutatorContext, 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 { 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 @@ -2744,23 +2802,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 { + 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), } } @@ -2805,12 +2891,8 @@ type bp2BuildJavaInfo struct { hasKotlin bool } -// Replaces //a/b/my_xsd_config with //a/b/my_xsd_config-java -func xsdConfigJavaTarget(ctx android.BazelConversionPathContext, mod blueprint.Module) string { - callback := func(xsd android.XsdConfigBp2buildTargets) string { - return xsd.JavaBp2buildTargetName() - } - return android.XsdConfigBp2buildTarget(ctx, mod, callback) +func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string { + return xsd.JavaBp2buildTargetName() } // convertLibraryAttrsBp2Build returns a javaCommonAttributes struct with @@ -2818,24 +2900,21 @@ func xsdConfigJavaTarget(ctx android.BazelConversionPathContext, mod blueprint.M // 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) { +func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) { var srcs bazel.LabelListAttribute var deps bazel.LabelListAttribute - var staticDeps bazel.LabelList + var staticDeps bazel.LabelListAttribute archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) for axis, configToProps := range archVariantProps { for config, _props := range configToProps { if archProps, ok := _props.(*CommonProperties); ok { - srcsNonXsd, srcsXsd := android.PartitionXsdSrcs(ctx, archProps.Srcs) - excludeSrcsNonXsd, _ := android.PartitionXsdSrcs(ctx, archProps.Exclude_srcs) - archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, srcsNonXsd, excludeSrcsNonXsd) + archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs) srcs.SetSelectValue(axis, config, archSrcs) - - // Add to static deps - xsdJavaConfigLibraryLabels := android.BazelLabelForModuleDepsWithFn(ctx, srcsXsd, xsdConfigJavaTarget) - staticDeps.Append(xsdJavaConfigLibraryLabels) - + if archProps.Jarjar_rules != nil { + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "jarjar_rules") + return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false + } } } } @@ -2843,6 +2922,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) javaSrcPartition := "java" protoSrcPartition := "proto" + xsdSrcPartition := "xsd" logtagSrcPartition := "logtag" aidlSrcPartition := "aidl" kotlinPartition := "kotlin" @@ -2851,6 +2931,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}}, protoSrcPartition: android.ProtoSrcLabelPartition, aidlSrcPartition: android.AidlSrcLabelPartition, + xsdSrcPartition: bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(javaXsdTargetName)}, kotlinPartition: bazel.LabelPartition{Extensions: []string{".kt"}}, }) @@ -2858,6 +2939,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) kotlinSrcs := srcPartitions[kotlinPartition] javaSrcs.Append(kotlinSrcs) + staticDeps.Append(srcPartitions[xsdSrcPartition]) + if !srcPartitions[logtagSrcPartition].IsEmpty() { logtagsLibName := m.Name() + "_logtags" ctx.CreateBazelTargetModule( @@ -2911,7 +2994,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) }, ) - staticDeps.Add(&bazel.Label{Label: ":" + javaAidlLibName}) + staticDeps.Append(bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + javaAidlLibName})) } var javacopts bazel.StringListAttribute //[]string @@ -2966,7 +3049,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) // 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. - staticDeps.Add(protoDepLabel) + if protoDepLabel != nil { + staticDeps.Append(bazel.MakeSingleLabelListAttribute(*protoDepLabel)) + } depLabels := &javaDependencyLabels{} depLabels.Deps = deps @@ -2981,7 +3066,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } } } - depLabels.StaticDeps.Value.Append(staticDeps) + depLabels.StaticDeps.Append(staticDeps) hasKotlin := !kotlinSrcs.IsEmpty() commonAttrs.kotlinAttributes = &kotlinAttributes{ @@ -2997,7 +3082,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) hasKotlin: hasKotlin, } - return commonAttrs, bp2BuildInfo + return commonAttrs, bp2BuildInfo, true } type javaLibraryAttributes struct { @@ -3027,7 +3112,10 @@ func javaLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties } func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { - commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx) + commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) + if !supported { + return + } depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps @@ -3074,7 +3162,10 @@ type javaBinaryHostAttributes struct { // JavaBinaryHostBp2Build is for java_binary_host bp2build. func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { - commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx) + commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) + if !supported { + return + } depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps @@ -3151,13 +3242,17 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { type javaTestHostAttributes struct { *javaCommonAttributes + Srcs bazel.LabelListAttribute Deps bazel.LabelListAttribute Runtime_deps bazel.LabelListAttribute } // javaTestHostBp2Build is for java_test_host bp2build. func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) { - commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx) + commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx) + if !supported { + return + } depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps @@ -3187,8 +3282,10 @@ func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) { hasKotlin: bp2BuildInfo.hasKotlin, } libName := createLibraryTarget(ctx, libInfo) - attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) + attrs.Srcs = commonAttrs.Srcs + attrs.Deps = deps + attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) // Create the BazelTargetModule. ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) } @@ -3301,7 +3398,8 @@ func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) { HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile), ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile), ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile), - //TODO(b/240308299) include AIDL information from Bazel + // TODO(b/240308299) include AIDL information from Bazel + // TODO: aconfig files? }) i.maybeInstall(ctx, jarName, outputFile) |