summaryrefslogtreecommitdiff
path: root/java/java.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/java.go')
-rw-r--r--java/java.go210
1 files changed, 136 insertions, 74 deletions
diff --git a/java/java.go b/java/java.go
index d5aeb7cb2..500ae37c7 100644
--- a/java/java.go
+++ b/java/java.go
@@ -27,6 +27,7 @@ import (
"android/soong/bazel"
"android/soong/bazel/cquery"
"android/soong/remoteexec"
+ "android/soong/testing"
"android/soong/ui/metrics/bp2build_metrics_proto"
"github.com/google/blueprint"
@@ -278,6 +279,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
@@ -694,6 +698,11 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
+ proguardSpecInfo := j.collectProguardSpecInfo(ctx)
+ ctx.SetProvider(ProguardSpecInfoProvider, proguardSpecInfo)
+ j.exportedProguardFlagFiles = proguardSpecInfo.ProguardFlagsFiles.ToList()
+ j.extraProguardFlagFiles = append(j.extraProguardFlagFiles, j.exportedProguardFlagFiles...)
+
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if !apexInfo.IsForPlatform() {
j.hideApexVariantFromMake = true
@@ -711,9 +720,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
j.compile(ctx, nil, nil, nil)
- // Collect the module directory for IDE info in java/jdeps.go.
- j.modulePaths = append(j.modulePaths, ctx.ModuleDir())
-
exclusivelyForApex := !apexInfo.IsForPlatform()
if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
var extraInstallDeps android.Paths
@@ -738,10 +744,6 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
-
- proguardSpecInfo := j.collectProguardSpecInfo(ctx)
- ctx.SetProvider(ProguardSpecInfoProvider, proguardSpecInfo)
- j.exportedProguardFlagFiles = proguardSpecInfo.ProguardFlagsFiles.ToList()
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1084,6 +1086,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()
@@ -1220,10 +1226,12 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
j.Test.generateAndroidBuildActionsWithConfig(ctx, configs)
+ ctx.SetProvider(testing.TestModuleProviderKey, testing.TestModuleProviderData{})
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.generateAndroidBuildActionsWithConfig(ctx, nil)
+ ctx.SetProvider(testing.TestModuleProviderKey, testing.TestModuleProviderData{})
}
func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) {
@@ -1605,6 +1613,7 @@ func BinaryHostFactory() android.Module {
type JavaApiContribution struct {
android.ModuleBase
android.DefaultableModuleBase
+ embeddableInModuleAndImport
properties struct {
// name of the API surface
@@ -1620,6 +1629,7 @@ func ApiContributionFactory() android.Module {
android.InitAndroidModule(module)
android.InitDefaultableModule(module)
module.AddProperties(&module.properties)
+ module.initModuleAndImport(module)
return module
}
@@ -1648,6 +1658,7 @@ type ApiLibrary struct {
hiddenAPI
dexer
+ embeddableInModuleAndImport
properties JavaApiLibraryProperties
@@ -1657,6 +1668,8 @@ type ApiLibrary struct {
extractedSrcJar android.WritablePath
// .dex of stubs, used for hiddenapi processing
dexJarFile OptionalDexJarPath
+
+ validationPaths android.Paths
}
type JavaApiLibraryProperties struct {
@@ -1667,11 +1680,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
@@ -1691,12 +1699,25 @@ 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 {
module := &ApiLibrary{}
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
module.AddProperties(&module.properties)
+ module.initModuleAndImport(module)
android.InitDefaultableModule(module)
return module
}
@@ -1710,7 +1731,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())
@@ -1749,12 +1771,17 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
FlagWithArg("--hide ", "InvalidNullabilityOverride").
FlagWithArg("--hide ", "ChangedDefault")
- // 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")
+ 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
}
@@ -1773,6 +1800,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
@@ -1809,47 +1842,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, srcFilesInfo []JavaApiImportInfo, apiFiles android.Paths) android.Paths {
- var 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 i, apiScope := range allApiScopes {
- for _, srcFileInfo := range srcFilesInfo {
- if srcFileInfo.ApiFile.Base() == scopeOrderedSourceFileNames[i] || srcFileInfo.ApiSurface == apiScope.name {
- sortedSrcFiles = append(sortedSrcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String()))
- }
- }
- // TODO: b/300964421 - Remove when api_files property is removed
- for _, apiFileName := range apiFiles {
- if apiFileName.Base() == scopeOrderedSourceFileNames[i] {
- sortedSrcFiles = append(sortedSrcFiles, apiFileName)
- }
- }
- }
-
- if len(srcFilesInfo)+len(apiFiles) != len(sortedSrcFiles) {
- var srcFiles android.Paths
- for _, srcFileInfo := range srcFilesInfo {
- srcFiles = append(srcFiles, srcFileInfo.ApiFile)
+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)
}
- ctx.ModuleErrorf("Unrecognizable source file found within %s", append(srcFiles, apiFiles...))
}
+ 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) {
@@ -1860,8 +1901,7 @@ 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())
@@ -1871,6 +1911,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
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 {
@@ -1889,24 +1930,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
- // These are api files in the module subdirectory, which are not provided by
- // java_api_contribution but provided directly as module property.
- var apiFiles android.Paths
- for _, api := range al.properties.Api_files {
- apiFiles = append(apiFiles, 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()))
}
- srcFiles := al.sortApiFilesByApiScope(ctx, srcFilesInfo, apiFiles)
-
if srcFiles == nil && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
}
- cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
+ cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths)
al.stubsFlags(ctx, cmd, stubsDir)
@@ -1916,6 +1960,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()))
@@ -1938,6 +1984,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
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")
@@ -2772,7 +2819,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
type javaResourcesAttributes struct {
Resources bazel.LabelListAttribute
Resource_strip_prefix *string
- Additional_resources bazel.LabelListAttribute
+ Additional_resources bazel.LabelListAttribute `blueprint:"mutated"`
}
func (m *Library) getResourceFilegroupStripPrefix(ctx android.Bp2buildMutatorContext, resourceFilegroup string) (*string, bool) {
@@ -2874,6 +2921,7 @@ type javaCommonAttributes struct {
Sdk_version bazel.StringAttribute
Java_version bazel.StringAttribute
Errorprone_force_enable bazel.BoolAttribute
+ Javac_shard_size *int64
}
type javaDependencyLabels struct {
@@ -2932,8 +2980,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext
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 {
@@ -2943,6 +2991,11 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext
}
}
}
+ srcs.Append(
+ bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleSrcExcludes(ctx,
+ m.properties.Openjdk9.Srcs,
+ m.properties.Exclude_srcs)))
srcs.ResolveExcludes()
javaSrcPartition := "java"
@@ -3026,8 +3079,9 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext
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
@@ -3043,14 +3097,17 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext
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 {
@@ -3067,18 +3124,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext
}
}
- 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 {
@@ -3093,6 +3140,20 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext
}
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,
@@ -3456,6 +3517,7 @@ func ApiContributionImportFactory() android.Module {
android.InitDefaultableModule(module)
android.InitPrebuiltModule(module, &[]string{""})
module.AddProperties(&module.properties)
+ module.AddProperties(&module.sdkLibraryComponentProperties)
return module
}