diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/aar.go | 29 | ||||
| -rwxr-xr-x | java/app.go | 53 | ||||
| -rw-r--r-- | java/base.go | 34 | ||||
| -rw-r--r-- | java/droidstubs.go | 29 | ||||
| -rw-r--r-- | java/java.go | 84 | ||||
| -rw-r--r-- | java/java_test.go | 70 | ||||
| -rw-r--r-- | java/platform_bootclasspath.go | 17 | ||||
| -rw-r--r-- | java/platform_bootclasspath_test.go | 29 | ||||
| -rw-r--r-- | java/proto.go | 17 | ||||
| -rw-r--r-- | java/sdk_library.go | 11 | ||||
| -rw-r--r-- | java/testing.go | 86 |
11 files changed, 317 insertions, 142 deletions
diff --git a/java/aar.go b/java/aar.go index f28d97149..44496dc57 100644 --- a/java/aar.go +++ b/java/aar.go @@ -1223,6 +1223,7 @@ func AARImportFactory() android.Module { type bazelAapt struct { Manifest bazel.Label Resource_files bazel.LabelListAttribute + Resource_zips bazel.LabelListAttribute Assets_dir bazel.StringAttribute Assets bazel.LabelListAttribute } @@ -1267,15 +1268,30 @@ func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.Bp2buildMutatorContext) assets = bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))) } + var resourceZips bazel.LabelList + if len(a.aaptProperties.Resource_zips) > 0 { + if ctx.ModuleName() == "framework-res" { + resourceZips = android.BazelLabelForModuleSrc(ctx, a.aaptProperties.Resource_zips) + } else { + //TODO: b/301593550 - Implement support for this + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "resource_zips") + return &bazelAapt{}, false + } + } return &bazelAapt{ android.BazelLabelForModuleSrcSingle(ctx, manifest), bazel.MakeLabelListAttribute(resourceFiles), + bazel.MakeLabelListAttribute(resourceZips), assetsDir, bazel.MakeLabelListAttribute(assets), }, true } func (a *AARImport) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { + if len(a.properties.Aars) == 0 { + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "aars can't be empty") + return + } aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{}) exportableStaticLibs := []string{} // TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel. @@ -1340,10 +1356,12 @@ func (a *AndroidLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) if !commonAttrs.Srcs.IsEmpty() { deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them } else if !depLabels.Deps.IsEmpty() { - ctx.MarkBp2buildUnconvertible( - bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, - "Module has direct dependencies but no sources. Bazel will not allow this.") - return + // android_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 android_library + // since they aren't being propagated to any dependencies. + // So we can drop deps here. + deps = bazel.LabelListAttribute{} } name := a.Name() props := AndroidLibraryBazelTargetModuleProperties() @@ -1352,6 +1370,9 @@ func (a *AndroidLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) if !supported { return } + if hasJavaResources := aaptAttrs.ConvertJavaResources(ctx, commonAttrs); hasJavaResources { + return + } ctx.CreateBazelTargetModule( props, android.CommonAttributes{Name: name}, diff --git a/java/app.go b/java/app.go index dabc3192e..166c22d94 100755 --- a/java/app.go +++ b/java/app.go @@ -1638,6 +1638,15 @@ type bazelAndroidAppAttributes struct { Updatable *bool } +func (b bazelAapt) ConvertJavaResources(ctx android.Bp2buildMutatorContext, javaAttrs *javaCommonAttributes) bool { + // TODO (b/300470246) bp2build support for java_resources & java_resource_dirs in android rules + hasJavaResources := !javaAttrs.javaResourcesAttributes.Resources.IsEmpty() + if hasJavaResources { + ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, "(b/300470246) java resources in android_* module") + } + return hasJavaResources +} + func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (bool, android.CommonAttributes, *bazelAndroidAppAttributes) { aapt, supported := a.convertAaptAttrsWithBp2Build(ctx) if !supported { @@ -1674,9 +1683,25 @@ func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (boo Updatable: a.appProperties.Updatable, } - if !BoolDefault(a.dexProperties.Optimize.Enabled, true) { - appAttrs.Optimize = proptools.BoolPtr(false) - } else { + // As framework-res has no sources, no deps in the Bazel sense, and java compilation, dexing and optimization is skipped by + // Soong specifically for it, return early here before any of the conversion work for the above is attempted. + if ctx.ModuleName() == "framework-res" { + appAttrs.bazelAapt = aapt + return true, android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)}, appAttrs + } + + // Optimization is.. + // - enabled by default for android_app, android_test_helper_app + // - disabled by default for android_test + // + // TODO(b/192032291): Disable android_test_helper_app optimization by + // default after auditing downstream usage. + if a.dexProperties.Optimize.EnabledByDefault != a.dexer.effectiveOptimizeEnabled() { + // Property is explicitly defined by default from default, so emit the Bazel attribute. + appAttrs.Optimize = proptools.BoolPtr(a.dexer.effectiveOptimizeEnabled()) + } + + if a.dexer.effectiveOptimizeEnabled() { handCraftedFlags := "" if Bool(a.dexProperties.Optimize.Ignore_warnings) { handCraftedFlags += "-ignorewarning " @@ -1712,6 +1737,10 @@ func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (boo if !supported { return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{} } + if hasJavaResources := aapt.ConvertJavaResources(ctx, commonAttrs); hasJavaResources { + return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{} + } + depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps @@ -1762,11 +1791,18 @@ func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (boo // ConvertWithBp2build is used to convert android_app to Bazel. func (a *AndroidApp) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { if ok, commonAttrs, appAttrs := convertWithBp2build(ctx, a); ok { - props := bazel.BazelTargetModuleProperties{ - Rule_class: "android_binary", - Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl", + var props bazel.BazelTargetModuleProperties + if ctx.ModuleName() == "framework-res" { + props = bazel.BazelTargetModuleProperties{ + Rule_class: "framework_resources", + Bzl_load_location: "//build/bazel/rules/android:framework_resources.bzl", + } + } else { + props = bazel.BazelTargetModuleProperties{ + Rule_class: "android_binary", + Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl", + } } - ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs) } @@ -1790,13 +1826,12 @@ func (atha *AndroidTestHelperApp) ConvertWithBp2build(ctx android.Bp2buildMutato // an android_test_helper_app is an android_binary with testonly = True commonAttrs.Testonly = proptools.BoolPtr(true) - // additionally, it sets default values differently to android_app, + // android_test_helper_app sets default values differently to android_app, // https://cs.android.com/android/platform/superproject/main/+/main:build/soong/java/app.go;l=1273-1279;drc=e12c083198403ec694af6c625aed11327eb2bf7f // // installable: true (settable prop) // use_embedded_native_libs: true (settable prop) // lint.test: true (settable prop) - // optimize EnabledByDefault: true (blueprint mutated prop) // AlwaysPackageNativeLibs: true (blueprint mutated prop) // dexpreopt isTest: true (not prop) diff --git a/java/base.go b/java/base.go index a110aff56..db237dac0 100644 --- a/java/base.go +++ b/java/base.go @@ -432,6 +432,9 @@ type Module struct { srcJarArgs []string srcJarDeps android.Paths + // the source files of this module and all its static dependencies + transitiveSrcFiles *android.DepSet[android.Path] + // jar file containing implementation classes and resources including static library // dependencies implementationAndResourcesJar android.Path @@ -1343,10 +1346,17 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath jars = append(jars, classes) } } + // Assume approximately 5 sources per srcjar. + // For framework-minus-apex in AOSP at the time this was written, there are 266 srcjars, with a mean + // of 5.8 sources per srcjar, but a median of 1, a standard deviation of 10, and a max of 48 source files. if len(srcJars) > 0 { - classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs), - nil, srcJars, flags, extraJarDeps) - jars = append(jars, classes) + startIdx := len(shardSrcs) + shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5) + for idx, shardSrcJars := range shardSrcJarsList { + classes := j.compileJavaClasses(ctx, jarName, startIdx+idx, + nil, shardSrcJars, flags, extraJarDeps) + jars = append(jars, classes) + } } } else { classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps) @@ -1687,6 +1697,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath j.linter.lint(ctx) } + j.collectTransitiveSrcFiles(ctx, srcFiles) + ctx.CheckbuildFile(outputFile) j.collectTransitiveAconfigFiles(ctx) @@ -1701,6 +1713,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath AidlIncludeDirs: j.exportAidlIncludeDirs, SrcJarArgs: j.srcJarArgs, SrcJarDeps: j.srcJarDeps, + TransitiveSrcFiles: j.transitiveSrcFiles, ExportedPlugins: j.exportedPluginJars, ExportedPluginClasses: j.exportedPluginClasses, ExportedPluginDisableTurbine: j.exportedDisableTurbine, @@ -2025,6 +2038,21 @@ func (j *Module) JacocoReportClassesFile() android.Path { return j.jacocoReportClassesFile } +func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) { + var fromDeps []*android.DepSet[android.Path] + ctx.VisitDirectDeps(func(module android.Module) { + tag := ctx.OtherModuleDependencyTag(module) + if tag == staticLibTag { + depInfo := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) + if depInfo.TransitiveSrcFiles != nil { + fromDeps = append(fromDeps, depInfo.TransitiveSrcFiles) + } + } + }) + + j.transitiveSrcFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps) +} + func (j *Module) IsInstallable() bool { return Bool(j.properties.Installable) } diff --git a/java/droidstubs.go b/java/droidstubs.go index 1d5dd7624..67a55bd49 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -24,7 +24,6 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" - "android/soong/bazel" "android/soong/java/config" "android/soong/remoteexec" ) @@ -855,34 +854,6 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } -var _ android.ApiProvider = (*Droidstubs)(nil) - -type bazelJavaApiContributionAttributes struct { - Api bazel.LabelAttribute - Api_surface *string -} - -func (d *Droidstubs) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) { - props := bazel.BazelTargetModuleProperties{ - Rule_class: "java_api_contribution", - Bzl_load_location: "//build/bazel/rules/apis:java_api_contribution.bzl", - } - apiFile := d.properties.Check_api.Current.Api_file - // Do not generate a target if check_api is not set - if apiFile == nil { - return - } - attrs := &bazelJavaApiContributionAttributes{ - Api: *bazel.MakeLabelAttribute( - android.BazelLabelForModuleSrcSingle(ctx, proptools.String(apiFile)).Label, - ), - Api_surface: proptools.StringPtr(bazelApiSurfaceName(d.Name())), - } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{ - Name: android.ApiContributionTargetName(ctx.ModuleName()), - }, attrs) -} - func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) { api_file := d.properties.Check_api.Current.Api_file api_surface := d.properties.Api_surface diff --git a/java/java.go b/java/java.go index d5aeb7cb2..cac49a2c5 100644 --- a/java/java.go +++ b/java/java.go @@ -278,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 @@ -1667,11 +1670,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 @@ -1819,37 +1817,22 @@ 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" }) +// 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 }) -func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo, apiFiles android.Paths) android.Paths { - var sortedSrcFiles android.Paths - - 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) - } +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) } } + sort.Slice(srcFilesInfo, func(i, j int) bool { + return scopeOrderMap[srcFilesInfo[i].ApiSurface] < scopeOrderMap[srcFilesInfo[j].ApiSurface] + }) - if len(srcFilesInfo)+len(apiFiles) != len(sortedSrcFiles) { - var srcFiles android.Paths - for _, srcFileInfo := range srcFilesInfo { - srcFiles = append(srcFiles, srcFileInfo.ApiFile) - } - ctx.ModuleErrorf("Unrecognizable source file found within %s", append(srcFiles, apiFiles...)) - } - - return sortedSrcFiles + return srcFilesInfo } func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -1892,16 +1875,12 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { } }) - // 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()) } @@ -3067,17 +3046,6 @@ 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{} depLabels.Deps = deps @@ -3093,6 +3061,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, diff --git a/java/java_test.go b/java/java_test.go index 2ee05ec73..d51604a25 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1885,7 +1885,6 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) { name: "bar2", api_surface: "system", api_contributions: ["foo1", "foo2"], - api_files: ["api1/current.txt", "api2/current.txt"] } `, map[string][]byte{ @@ -1903,7 +1902,7 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) { }, { moduleName: "bar2", - sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "api1/current.txt", "api2/current.txt"}, + sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"}, }, } for _, c := range testcases { @@ -1975,7 +1974,6 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { api_surface: "system", defaults:["baz1", "baz2"], api_contributions: ["foo4"], - api_files: ["api1/current.txt", "api2/current.txt"] } `, map[string][]byte{ @@ -2000,7 +1998,7 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { { moduleName: "bar3", // API text files need to be sorted from the narrower api scope to the wider api scope - sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "api1/current.txt", "api2/current.txt", "c/system-current.txt", "d/system-current.txt"}, + sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "c/system-current.txt", "d/system-current.txt"}, }, } for _, c := range testcases { @@ -2265,27 +2263,26 @@ func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) { android.AssertStringDoesContain(t, "Command expected to contain full_api_surface_stub output jar", manifestCommand, "lib1.jar") } -func TestJavaApiLibraryFilegroupInput(t *testing.T) { - ctx, _ := testJavaWithFS(t, ` - filegroup { - name: "default_current.txt", - srcs: ["current.txt"], +func TestTransitiveSrcFiles(t *testing.T) { + ctx, _ := testJava(t, ` + java_library { + name: "a", + srcs: ["a.java"], } - - java_api_library { - name: "foo", - api_files: [":default_current.txt"], + java_library { + name: "b", + srcs: ["b.java"], } - `, - map[string][]byte{ - "current.txt": nil, - }) - - m := ctx.ModuleForTests("foo", "android_common") - outputs := fmt.Sprint(m.AllOutputs()) - if !strings.Contains(outputs, "foo/foo.jar") { - t.Errorf("Module output does not contain expected jar %s", "foo/foo.jar") - } + java_library { + name: "c", + srcs: ["c.java"], + libs: ["a"], + static_libs: ["b"], + } + `) + c := ctx.ModuleForTests("c", "android_common").Module() + transitiveSrcFiles := android.Paths(ctx.ModuleProvider(c, JavaInfoProvider).(JavaInfo).TransitiveSrcFiles.ToList()) + android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings()) } func TestTradefedOptions(t *testing.T) { @@ -2423,3 +2420,30 @@ func TestJavaApiContributionImport(t *testing.T) { sourceFilesFlag := "--source-files current.txt" android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) } + +func TestJavaApiLibraryApiFilesSorting(t *testing.T) { + ctx, _ := testJava(t, ` + java_api_library { + name: "foo", + api_contributions: [ + "system-server-api-stubs-docs-non-updatable.api.contribution", + "test-api-stubs-docs-non-updatable.api.contribution", + "system-api-stubs-docs-non-updatable.api.contribution", + "module-lib-api-stubs-docs-non-updatable.api.contribution", + "api-stubs-docs-non-updatable.api.contribution", + ], + } + `) + m := ctx.ModuleForTests("foo", "android_common") + manifest := m.Output("metalava.sbox.textproto") + sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest) + manifestCommand := sboxProto.Commands[0].GetCommand() + + // Api files are sorted from the narrowest api scope to the widest api scope. + // test api and module lib api surface do not have subset/superset relationship, + // but they will never be passed as inputs at the same time. + sourceFilesFlag := "--source-files default/java/api/current.txt " + + "default/java/api/system-current.txt default/java/api/test-current.txt " + + "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt" + android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag) +} diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index ade739552..02a2298cd 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -57,6 +57,9 @@ type platformBootclasspathModule struct { // Path to the monolithic hiddenapi-unsupported.csv file. hiddenAPIMetadataCSV android.OutputPath + + // Path to a srcjar containing all the transitive sources of the bootclasspath. + srcjar android.OutputPath } type platformBootclasspathProperties struct { @@ -95,6 +98,8 @@ func (b *platformBootclasspathModule) OutputFiles(tag string) (android.Paths, er return android.Paths{b.hiddenAPIIndexCSV}, nil case "hiddenapi-metadata.csv": return android.Paths{b.hiddenAPIMetadataCSV}, nil + case ".srcjar": + return android.Paths{b.srcjar}, nil } return nil, fmt.Errorf("unknown tag %s", tag) @@ -173,6 +178,18 @@ func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.Mo allModules = append(allModules, apexModules...) b.configuredModules = allModules + var transitiveSrcFiles android.Paths + for _, module := range allModules { + depInfo := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) + if depInfo.TransitiveSrcFiles != nil { + transitiveSrcFiles = append(transitiveSrcFiles, depInfo.TransitiveSrcFiles.ToList()...) + } + } + jarArgs := resourcePathsToJarArgs(transitiveSrcFiles) + jarArgs = append(jarArgs, "-srcjar") // Move srcfiles to the right package + b.srcjar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-transitive.srcjar").OutputPath + TransformResourcesToJar(ctx, b.srcjar, jarArgs, transitiveSrcFiles) + // Gather all the fragments dependencies. b.fragments = gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag) diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go index ff2da4bb2..37ff6395c 100644 --- a/java/platform_bootclasspath_test.go +++ b/java/platform_bootclasspath_test.go @@ -81,6 +81,15 @@ func TestPlatformBootclasspath(t *testing.T) { RunTest(t) }) + fooSourceSrc := "source/a.java" + barSrc := "a.java" + + checkSrcJarInputs := func(t *testing.T, result *android.TestResult, name string, expected []string) { + t.Helper() + srcjar := result.ModuleForTests(name, "android_common").Output(name + "-transitive.srcjar") + android.AssertStringDoesContain(t, "srcjar arg", srcjar.Args["jarArgs"], "-srcjar") + android.AssertArrayString(t, "srcjar inputs", expected, srcjar.Implicits.Strings()) + } t.Run("source", func(t *testing.T) { result := android.GroupFixturePreparers( preparer, @@ -91,6 +100,10 @@ func TestPlatformBootclasspath(t *testing.T) { "platform:foo", "platform:bar", }) + checkSrcJarInputs(t, result, "platform-bootclasspath", []string{ + fooSourceSrc, + barSrc, + }) }) t.Run("prebuilt", func(t *testing.T) { @@ -103,6 +116,10 @@ func TestPlatformBootclasspath(t *testing.T) { "platform:prebuilt_foo", "platform:bar", }) + checkSrcJarInputs(t, result, "platform-bootclasspath", []string{ + // TODO(b/151360309): This should also have the srcs for prebuilt_foo + barSrc, + }) }) t.Run("source+prebuilt - source preferred", func(t *testing.T) { @@ -116,6 +133,10 @@ func TestPlatformBootclasspath(t *testing.T) { "platform:foo", "platform:bar", }) + checkSrcJarInputs(t, result, "platform-bootclasspath", []string{ + fooSourceSrc, + barSrc, + }) }) t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) { @@ -129,6 +150,10 @@ func TestPlatformBootclasspath(t *testing.T) { "platform:prebuilt_foo", "platform:bar", }) + checkSrcJarInputs(t, result, "platform-bootclasspath", []string{ + // TODO(b/151360309): This should also have the srcs for prebuilt_foo + barSrc, + }) }) t.Run("dex import", func(t *testing.T) { @@ -146,6 +171,10 @@ func TestPlatformBootclasspath(t *testing.T) { "platform:prebuilt_foo", "platform:bar", }) + checkSrcJarInputs(t, result, "platform-bootclasspath", []string{ + // TODO(b/151360309): This should also have the srcs for prebuilt_foo + barSrc, + }) }) } diff --git a/java/proto.go b/java/proto.go index 2ed7b27e9..48adadcc9 100644 --- a/java/proto.go +++ b/java/proto.go @@ -151,11 +151,17 @@ type protoAttributes struct { // a specific .proto file module explicitly. Transitive_deps bazel.LabelListAttribute + // This is the libs and the static_libs of the original java_library module. + // On the bazel side, after proto sources are generated in java_*_proto_library, a java_library + // will compile them. The libs and static_libs from the original java_library module need + // to be linked because they are necessary in compile-time classpath. + Additional_proto_deps bazel.LabelListAttribute + Sdk_version bazel.StringAttribute Java_version bazel.StringAttribute } -func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) *bazel.Label { +func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute, AdditionalProtoDeps bazel.LabelListAttribute) *bazel.Label { protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs) if !ok { return nil @@ -184,10 +190,11 @@ func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs baze } protoAttrs := &protoAttributes{ - Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs), - Transitive_deps: bazel.MakeLabelListAttribute(protoInfo.Transitive_proto_libs), - Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, - Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, + Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs), + Transitive_deps: bazel.MakeLabelListAttribute(protoInfo.Transitive_proto_libs), + Additional_proto_deps: AdditionalProtoDeps, + Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, + Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, } name := m.Name() + suffix diff --git a/java/sdk_library.go b/java/sdk_library.go index 27f862662..e410a41fa 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -286,6 +286,17 @@ func (scopes apiScopes) Strings(accessor func(*apiScope) string) []string { return list } +// Method that maps the apiScopes properties to the index of each apiScopes elements. +// apiScopes property to be used as the key can be specified with the input accessor. +// Only a string property of apiScope can be used as the key of the map. +func (scopes apiScopes) MapToIndex(accessor func(*apiScope) string) map[string]int { + ret := make(map[string]int) + for i, scope := range scopes { + ret[accessor(scope)] = i + } + return ret +} + var ( scopeByName = make(map[string]*apiScope) allScopeNames []string diff --git a/java/testing.go b/java/testing.go index f2bcccfce..98bea7f14 100644 --- a/java/testing.go +++ b/java/testing.go @@ -424,30 +424,80 @@ func gatherRequiredDepsForTest() string { `, extra) } - extraApiLibraryModules := map[string]string{ - "android_stubs_current.from-text": "api/current.txt", - "android_system_stubs_current.from-text": "api/system-current.txt", - "android_test_stubs_current.from-text": "api/test-current.txt", - "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt", - "android_module_lib_stubs_current_full.from-text": "api/module-lib-current.txt", - "android_system_server_stubs_current.from-text": "api/system-server-current.txt", - "core.current.stubs.from-text": "api/current.txt", - "legacy.core.platform.api.stubs.from-text": "api/current.txt", - "stable.core.platform.api.stubs.from-text": "api/current.txt", - "core-lambda-stubs.from-text": "api/current.txt", - "android-non-updatable.stubs.from-text": "api/current.txt", - "android-non-updatable.stubs.system.from-text": "api/system-current.txt", - "android-non-updatable.stubs.test.from-text": "api/test-current.txt", - "android-non-updatable.stubs.module_lib.from-text": "api/module-lib-current.txt", + type apiContributionStruct struct { + name string + apiSurface string + apiFile string } - for libName, apiFile := range extraApiLibraryModules { + var publicApiContribution = apiContributionStruct{ + name: "api-stubs-docs-non-updatable.api.contribution", + apiSurface: "public", + apiFile: "api/current.txt", + } + var systemApiContribution = apiContributionStruct{ + name: "system-api-stubs-docs-non-updatable.api.contribution", + apiSurface: "system", + apiFile: "api/system-current.txt", + } + var testApiContribution = apiContributionStruct{ + name: "test-api-stubs-docs-non-updatable.api.contribution", + apiSurface: "test", + apiFile: "api/test-current.txt", + } + var moduleLibApiContribution = apiContributionStruct{ + name: "module-lib-api-stubs-docs-non-updatable.api.contribution", + apiSurface: "module-lib", + apiFile: "api/module-lib-current.txt", + } + var systemServerApiContribution = apiContributionStruct{ + // This module does not exist but is named this way for consistency + name: "system-server-api-stubs-docs-non-updatable.api.contribution", + apiSurface: "system-server", + apiFile: "api/system-server-current.txt", + } + var apiContributionStructs = []apiContributionStruct{ + publicApiContribution, + systemApiContribution, + testApiContribution, + moduleLibApiContribution, + systemServerApiContribution, + } + + extraApiLibraryModules := map[string]apiContributionStruct{ + "android_stubs_current.from-text": publicApiContribution, + "android_system_stubs_current.from-text": systemApiContribution, + "android_test_stubs_current.from-text": testApiContribution, + "android_module_lib_stubs_current.from-text": moduleLibApiContribution, + "android_module_lib_stubs_current_full.from-text": moduleLibApiContribution, + "android_system_server_stubs_current.from-text": systemServerApiContribution, + "core.current.stubs.from-text": publicApiContribution, + "legacy.core.platform.api.stubs.from-text": publicApiContribution, + "stable.core.platform.api.stubs.from-text": publicApiContribution, + "core-lambda-stubs.from-text": publicApiContribution, + "android-non-updatable.stubs.from-text": publicApiContribution, + "android-non-updatable.stubs.system.from-text": systemApiContribution, + "android-non-updatable.stubs.test.from-text": testApiContribution, + "android-non-updatable.stubs.module_lib.from-text": moduleLibApiContribution, + } + + for _, apiContribution := range apiContributionStructs { + bp += fmt.Sprintf(` + java_api_contribution { + name: "%s", + api_surface: "%s", + api_file: "%s", + } + `, apiContribution.name, apiContribution.apiSurface, apiContribution.apiFile) + } + + for libName, apiContribution := range extraApiLibraryModules { bp += fmt.Sprintf(` java_api_library { name: "%s", - api_files: ["%s"], + api_contributions: ["%s"], } - `, libName, apiFile) + `, libName, apiContribution.name) } bp += ` |