diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/aar.go | 13 | ||||
-rwxr-xr-x | java/app.go | 130 | ||||
-rw-r--r-- | java/base.go | 6 | ||||
-rw-r--r-- | java/device_host_converter.go | 2 | ||||
-rw-r--r-- | java/dex.go | 11 | ||||
-rw-r--r-- | java/droiddoc.go | 25 | ||||
-rw-r--r-- | java/java.go | 126 | ||||
-rw-r--r-- | java/java_test.go | 43 | ||||
-rw-r--r-- | java/kotlin.go | 3 | ||||
-rw-r--r-- | java/platform_compat_config.go | 2 | ||||
-rw-r--r-- | java/plugin.go | 2 | ||||
-rw-r--r-- | java/sdk_library.go | 72 | ||||
-rw-r--r-- | java/sdk_library_test.go | 5 |
13 files changed, 323 insertions, 117 deletions
diff --git a/java/aar.go b/java/aar.go index 021619603..f28d97149 100644 --- a/java/aar.go +++ b/java/aar.go @@ -993,7 +993,7 @@ var extractJNI = pctx.AndroidStaticRule("extractJNI", `jni_files=$$(find $outDir/jni -type f) && ` + // print error message if there are no JNI libs for this arch `[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` + - `${config.SoongZipCmd} -o $out -P 'lib/${archString}' ` + + `${config.SoongZipCmd} -o $out -L 0 -P 'lib/${archString}' ` + `-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`, CommandDeps: []string{"${config.SoongZipCmd}"}, }, @@ -1239,7 +1239,7 @@ type bazelAndroidLibraryImport struct { Sdk_version bazel.StringAttribute } -func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) (*bazelAapt, bool) { +func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.Bp2buildMutatorContext) (*bazelAapt, bool) { manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") resourceFiles := bazel.LabelList{ @@ -1275,7 +1275,7 @@ func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) ( }, true } -func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (a *AARImport) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { 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. @@ -1328,7 +1328,7 @@ func AndroidLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperti } } -func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (a *AndroidLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { commonAttrs, bp2buildInfo, supported := a.convertLibraryAttrsBp2Build(ctx) if !supported { return @@ -1340,7 +1340,10 @@ func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) 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.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") + ctx.MarkBp2buildUnconvertible( + bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, + "Module has direct dependencies but no sources. Bazel will not allow this.") + return } name := a.Name() props := AndroidLibraryBazelTargetModuleProperties() diff --git a/java/app.go b/java/app.go index 7ee0e3857..dabc3192e 100755 --- a/java/app.go +++ b/java/app.go @@ -31,6 +31,7 @@ import ( "android/soong/dexpreopt" "android/soong/genrule" "android/soong/tradefed" + "android/soong/ui/metrics/bp2build_metrics_proto" ) func init() { @@ -1115,6 +1116,8 @@ type AndroidTest struct { testConfig android.Path extraTestConfigs android.Paths data android.Paths + + android.BazelModuleBase } func (a *AndroidTest) InstallInTestcases() bool { @@ -1232,6 +1235,8 @@ func AndroidTestFactory() android.Module { android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) android.InitDefaultableModule(module) android.InitOverridableModule(module, &module.overridableAppProperties.Overrides) + + android.InitBazelModule(module) return module } @@ -1253,6 +1258,8 @@ type AndroidTestHelperApp struct { AndroidApp appTestHelperAppProperties appTestHelperAppProperties + + android.BazelModuleBase } func (a *AndroidTestHelperApp) InstallInTestcases() bool { @@ -1284,6 +1291,7 @@ func AndroidTestHelperAppFactory() android.Module { android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) android.InitDefaultableModule(module) android.InitApexModule(module) + android.InitBazelModule(module) return module } @@ -1590,11 +1598,11 @@ type bazelAndroidAppCertificateAttributes struct { Certificate string } -func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { androidAppCertificateBp2Build(ctx, m) } -func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) { +func androidAppCertificateBp2Build(ctx android.Bp2buildMutatorContext, module *AndroidAppCertificate) { var certificate string if module.properties.Certificate != nil { certificate = *module.properties.Certificate @@ -1614,7 +1622,6 @@ func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *An type manifestValueAttribute struct { MinSdkVersion *string - MaxSdkVersion *string TargetSdkVersion *string } @@ -1628,38 +1635,34 @@ type bazelAndroidAppAttributes struct { Manifest_values *manifestValueAttribute Optimize *bool Proguard_specs bazel.LabelListAttribute + Updatable *bool } -// ConvertWithBp2build is used to convert android_app to Bazel. -func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (bool, android.CommonAttributes, *bazelAndroidAppAttributes) { aapt, supported := a.convertAaptAttrsWithBp2Build(ctx) if !supported { - return + return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{} } - certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate) - - manifestValues := &manifestValueAttribute{} - // TODO(b/274474008 ): Directly convert deviceProperties.Min_sdk_version in bp2build - // MinSdkVersion(ctx) calls SdkVersion(ctx) if no value for min_sdk_version is set - minSdkVersion := a.MinSdkVersion(ctx) - if !minSdkVersion.IsPreview() && !minSdkVersion.IsInvalid() { - if minSdkStr, err := minSdkVersion.EffectiveVersionString(ctx); err == nil { - manifestValues.MinSdkVersion = &minSdkStr - } + if a.appProperties.Jni_uses_platform_apis != nil { + ctx.MarkBp2buildUnconvertible( + bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, + "TODO - b/299360988: Add bp2build support for jni_uses_platform_apis", + ) + return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{} } - - maxSdkVersion := a.MaxSdkVersion(ctx) - if !maxSdkVersion.IsPreview() && !maxSdkVersion.IsInvalid() { - if maxSdkStr, err := maxSdkVersion.EffectiveVersionString(ctx); err == nil { - manifestValues.MaxSdkVersion = &maxSdkStr - } + if a.appProperties.Jni_uses_sdk_apis != nil { + ctx.MarkBp2buildUnconvertible( + bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, + "TODO - b/299360988: Add bp2build support for jni_uses_sdk_apis", + ) + return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{} } - targetSdkVersion := a.TargetSdkVersion(ctx) - if !targetSdkVersion.IsPreview() && !targetSdkVersion.IsInvalid() { - if targetSdkStr, err := targetSdkVersion.EffectiveVersionString(ctx); err == nil { - manifestValues.TargetSdkVersion = &targetSdkStr - } + certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate) + + manifestValues := &manifestValueAttribute{ + MinSdkVersion: a.deviceProperties.Min_sdk_version, + TargetSdkVersion: a.deviceProperties.Target_sdk_version, } appAttrs := &bazelAndroidAppAttributes{ @@ -1668,6 +1671,7 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { Certificate: certificate, Certificate_name: certificateName, Manifest_values: manifestValues, + Updatable: a.appProperties.Updatable, } if !BoolDefault(a.dexProperties.Optimize.Enabled, true) { @@ -1706,17 +1710,26 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx) if !supported { - return + return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{} } depLabels := bp2BuildInfo.DepLabels deps := depLabels.Deps deps.Append(depLabels.StaticDeps) - props := bazel.BazelTargetModuleProperties{ - Rule_class: "android_binary", - Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl", + var jniDeps bazel.LabelListAttribute + archVariantProps := a.GetArchVariantProperties(ctx, &appProperties{}) + for axis, configToProps := range archVariantProps { + for config, _props := range configToProps { + if archProps, ok := _props.(*appProperties); ok { + archJniLibs := android.BazelLabelForModuleDeps( + ctx, + android.LastUniqueStrings(android.CopyOf(archProps.Jni_libs))) + jniDeps.SetSelectValue(axis, config, archJniLibs) + } + } } + deps.Append(jniDeps) if !bp2BuildInfo.hasKotlin { appAttrs.javaCommonAttributes = commonAttrs @@ -1743,10 +1756,55 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } } - ctx.CreateBazelTargetModule( - props, - android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)}, - appAttrs, - ) + return true, android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)}, appAttrs +} + +// 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", + } + ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs) + } + +} + +// ConvertWithBp2build is used to convert android_test to Bazel. +func (at *AndroidTest) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { + if ok, commonAttrs, appAttrs := convertWithBp2build(ctx, &at.AndroidApp); ok { + props := bazel.BazelTargetModuleProperties{ + Rule_class: "android_test", + Bzl_load_location: "//build/bazel/rules/android:android_test.bzl", + } + + ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs) + } + +} + +func (atha *AndroidTestHelperApp) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { + if ok, commonAttrs, appAttrs := convertWithBp2build(ctx, &atha.AndroidApp); ok { + // 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, + // 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) + + props := bazel.BazelTargetModuleProperties{ + Rule_class: "android_binary", + Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl", + } + + ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs) + } } diff --git a/java/base.go b/java/base.go index 8f483989e..a110aff56 100644 --- a/java/base.go +++ b/java/base.go @@ -1077,8 +1077,8 @@ func (j *Module) AddJSONData(d *map[string]interface{}) { } -func (module *Module) addGeneratedSrcJars(path android.Path) { - module.properties.Generated_srcjars = append(module.properties.Generated_srcjars, path) +func (j *Module) addGeneratedSrcJars(path android.Path) { + j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path) } func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) { @@ -2359,7 +2359,7 @@ type ModuleWithStem interface { var _ ModuleWithStem = (*Module)(nil) -func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (j *Module) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { switch ctx.ModuleType() { case "java_library", "java_library_host", "java_library_static", "tradefed_java_library_host": if lib, ok := ctx.Module().(*Library); ok { diff --git a/java/device_host_converter.go b/java/device_host_converter.go index 5460dc993..c5ba245ea 100644 --- a/java/device_host_converter.go +++ b/java/device_host_converter.go @@ -198,7 +198,7 @@ type bazelDeviceHostConverterAttributes struct { Exports bazel.LabelListAttribute } -func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{ Rule_class: "java_host_for_device", diff --git a/java/dex.go b/java/dex.go index 5b8cf3dfb..c1d51c7bf 100644 --- a/java/dex.go +++ b/java/dex.go @@ -315,15 +315,14 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Fl if BoolDefault(opt.Proguard_compatibility, true) { r8Flags = append(r8Flags, "--force-proguard-compatibility") - } else { + } + + if Bool(opt.Optimize) || Bool(opt.Obfuscate) { // TODO(b/213833843): Allow configuration of the prefix via a build variable. var sourceFilePrefix = "go/retraceme " var sourceFileTemplate = "\"" + sourceFilePrefix + "%MAP_ID\"" - // TODO(b/200967150): Also tag the source file in compat builds. - if Bool(opt.Optimize) || Bool(opt.Obfuscate) { - r8Flags = append(r8Flags, "--map-id-template", "%MAP_HASH") - r8Flags = append(r8Flags, "--source-file-template", sourceFileTemplate) - } + r8Flags = append(r8Flags, "--map-id-template", "%MAP_HASH") + r8Flags = append(r8Flags, "--source-file-template", sourceFileTemplate) } // TODO(ccross): Don't shrink app instrumentation tests by default. diff --git a/java/droiddoc.go b/java/droiddoc.go index 3ba306554..d5547d05c 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -22,6 +22,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/bazel" "android/soong/java/config" ) @@ -844,6 +845,7 @@ type ExportedDroiddocDirProperties struct { type ExportedDroiddocDir struct { android.ModuleBase + android.BazelModuleBase properties ExportedDroiddocDirProperties @@ -856,6 +858,7 @@ func ExportedDroiddocDirFactory() android.Module { module := &ExportedDroiddocDir{} module.AddProperties(&module.properties) android.InitAndroidModule(module) + android.InitBazelModule(module) return module } @@ -867,6 +870,28 @@ func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleCont d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")}) } +// ConvertWithBp2build implements android.BazelModule. +func (d *ExportedDroiddocDir) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { + props := bazel.BazelTargetModuleProperties{ + // Use the native py_library rule. + Rule_class: "droiddoc_exported_dir", + Bzl_load_location: "//build/bazel/rules/droiddoc:droiddoc_exported_dir.bzl", + } + + type BazelAttrs struct { + Dir *string + Srcs bazel.LabelListAttribute + } + + attrs := &BazelAttrs{ + Dir: proptools.StringPtr(*d.properties.Path), + Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{filepath.Join(*d.properties.Path, "**/*")})), + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: d.Name()}, attrs) + +} + // Defaults type DocDefaults struct { android.ModuleBase diff --git a/java/java.go b/java/java.go index 270f45615..d5aeb7cb2 100644 --- a/java/java.go +++ b/java/java.go @@ -64,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 @@ -1623,7 +1624,8 @@ func ApiContributionFactory() android.Module { } type JavaApiImportInfo struct { - ApiFile android.Path + ApiFile android.Path + ApiSurface string } var JavaApiImportProvider = blueprint.NewProvider(JavaApiImportInfo{}) @@ -1635,7 +1637,8 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon } ctx.SetProvider(JavaApiImportProvider, JavaApiImportInfo{ - ApiFile: apiFile, + ApiFile: apiFile, + ApiSurface: proptools.String(ap.properties.Api_surface), }) } @@ -1821,18 +1824,29 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { 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{} +func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo, apiFiles android.Paths) android.Paths { + var sortedSrcFiles android.Paths - for _, scopeSourceFileName := range scopeOrderedSourceFileNames { - for _, sourceFileName := range srcFiles { - if sourceFileName.Base() == scopeSourceFileName { - sortedSrcFiles = append(sortedSrcFiles, sourceFileName) + 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(srcFiles) != len(sortedSrcFiles) { - ctx.ModuleErrorf("Unrecognizable source file found within %s", srcFiles) + + 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 @@ -1853,7 +1867,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 @@ -1862,11 +1876,10 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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...) @@ -1880,16 +1893,19 @@ 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 { - srcFiles = append(srcFiles, android.PathForModuleSrc(ctx, api)) + apiFiles = append(apiFiles, android.PathForModuleSrc(ctx, api)) } + srcFiles := al.sortApiFilesByApiScope(ctx, srcFilesInfo, apiFiles) + 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) al.stubsFlags(ctx, cmd, stubsDir) @@ -2759,7 +2775,7 @@ type javaResourcesAttributes struct { Additional_resources bazel.LabelListAttribute } -func (m *Library) getResourceFilegroupStripPrefix(ctx android.TopDownMutatorContext, resourceFilegroup string) (*string, bool) { +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 proptools.StringPtr(filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx))), true @@ -2768,7 +2784,7 @@ func (m *Library) getResourceFilegroupStripPrefix(ctx android.TopDownMutatorCont 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 @@ -2886,9 +2902,8 @@ type javaAidlLibraryAttributes struct { // depending on the module type. type bp2BuildJavaInfo struct { // separates dependencies into dynamic dependencies and static dependencies. - DepLabels *javaDependencyLabels - hasKotlin bool - onlyProtoInSrcs bool + DepLabels *javaDependencyLabels + hasKotlin bool } func javaXsdTargetName(xsd android.XsdConfigBp2buildTargets) string { @@ -2900,7 +2915,7 @@ 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 @@ -2951,9 +2966,6 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) staticDeps.Append(srcPartitions[xsdSrcPartition]) - _, protoInSrcs := srcPartitions[protoSrcPartition] - onlyProtoInSrcs := protoInSrcs && len(srcPartitions) == 1 - if !srcPartitions[logtagSrcPartition].IsEmpty() { logtagsLibName := m.Name() + "_logtags" ctx.CreateBazelTargetModule( @@ -3091,9 +3103,8 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } bp2BuildInfo := &bp2BuildJavaInfo{ - DepLabels: depLabels, - hasKotlin: hasKotlin, - onlyProtoInSrcs: onlyProtoInSrcs, + DepLabels: depLabels, + hasKotlin: hasKotlin, } return commonAttrs, bp2BuildInfo, true @@ -3125,7 +3136,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 @@ -3137,19 +3148,12 @@ func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { if !commonAttrs.Srcs.IsEmpty() { deps.Append(exports) // we should only append these if there are sources to use them } else if !deps.IsEmpty() { - if bp2BuildInfo.onlyProtoInSrcs { - // java_library does not accept deps when there are no srcs because - // there is no compilation happening, but it accepts exports. - // bp2build converts this module to 2 java_libraries + java_xx_proto_library + proto_library - // the non-empty deps here are not necessary for compiling the protos, in which case - // they're unnecessary as deps on the java_library as well since they aren't - // being propagated to any dependencies. - // so we can put the deps to exports and drop deps here. - exports.Append(deps) - deps = bazel.LabelListAttribute{} - } else { - 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{ @@ -3188,7 +3192,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 @@ -3275,7 +3279,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 @@ -3328,7 +3332,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 { @@ -3351,7 +3355,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 { @@ -3387,7 +3391,6 @@ func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { javaLibraryBazelTargetModuleProperties(), android.CommonAttributes{Name: name + "-neverlink"}, neverlinkAttrs) - } var _ android.MixedBuildBuildable = (*Import)(nil) @@ -3440,3 +3443,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) +} diff --git a/java/java_test.go b/java/java_test.go index 27933c3bf..2ee05ec73 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1865,11 +1865,13 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) { java_api_contribution { name: "foo1", api_file: "current.txt", + api_surface: "public", } ` provider_bp_b := `java_api_contribution { name: "foo2", api_file: "current.txt", + api_surface: "public", } ` ctx, _ := testJavaWithFS(t, ` @@ -1919,24 +1921,28 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { java_api_contribution { name: "foo1", api_file: "current.txt", + api_surface: "public", } ` provider_bp_b := ` java_api_contribution { name: "foo2", api_file: "current.txt", + api_surface: "public", } ` provider_bp_c := ` java_api_contribution { name: "foo3", - api_file: "current.txt", + api_file: "system-current.txt", + api_surface: "system", } ` provider_bp_d := ` java_api_contribution { name: "foo4", - api_file: "current.txt", + api_file: "system-current.txt", + api_surface: "system", } ` ctx, _ := testJavaWithFS(t, ` @@ -1992,8 +1998,9 @@ func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"}, }, { - moduleName: "bar3", - sourceTextFileDirs: []string{"c/current.txt", "a/current.txt", "b/current.txt", "d/current.txt", "api1/current.txt", "api2/current.txt"}, + 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"}, }, } for _, c := range testcases { @@ -2011,12 +2018,14 @@ func TestJavaApiLibraryJarGeneration(t *testing.T) { java_api_contribution { name: "foo1", api_file: "current.txt", + api_surface: "public", } ` provider_bp_b := ` java_api_contribution { name: "foo2", api_file: "current.txt", + api_surface: "public", } ` ctx, _ := testJavaWithFS(t, ` @@ -2064,12 +2073,14 @@ func TestJavaApiLibraryLibsLink(t *testing.T) { java_api_contribution { name: "foo1", api_file: "current.txt", + api_surface: "public", } ` provider_bp_b := ` java_api_contribution { name: "foo2", api_file: "current.txt", + api_surface: "public", } ` lib_bp_a := ` @@ -2139,12 +2150,14 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) { java_api_contribution { name: "foo1", api_file: "current.txt", + api_surface: "public", } ` provider_bp_b := ` java_api_contribution { name: "foo2", api_file: "current.txt", + api_surface: "public", } ` lib_bp_a := ` @@ -2213,12 +2226,14 @@ func TestJavaApiLibraryFullApiSurfaceStub(t *testing.T) { java_api_contribution { name: "foo1", api_file: "current.txt", + api_surface: "public", } ` provider_bp_b := ` java_api_contribution { name: "foo2", api_file: "current.txt", + api_surface: "public", } ` lib_bp_a := ` @@ -2388,3 +2403,23 @@ func TestHeadersOnly(t *testing.T) { javac := ctx.ModuleForTests("foo", "android_common").MaybeRule("javac") android.AssertDeepEquals(t, "javac rule", nil, javac.Rule) } + +func TestJavaApiContributionImport(t *testing.T) { + ctx, _ := testJava(t, ` + java_api_library { + name: "foo", + api_contributions: ["bar"], + } + java_api_contribution_import { + name: "bar", + api_file: "current.txt", + api_surface: "public", + } + `) + m := ctx.ModuleForTests("foo", "android_common") + manifest := m.Output("metalava.sbox.textproto") + sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest) + manifestCommand := sboxProto.Commands[0].GetCommand() + sourceFilesFlag := "--source-files current.txt" + android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) +} diff --git a/java/kotlin.go b/java/kotlin.go index 3637e2e71..aa2db0ecd 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -145,7 +145,7 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp `$kaptProcessorPath ` + `$kaptProcessor ` + `-Xbuild-file=$kotlinBuildFile && ` + - `${config.SoongZipCmd} -jar -o $out -C $kaptDir/stubs -D $kaptDir/stubs && ` + + `${config.SoongZipCmd} -jar -write_if_changed -o $out -C $kaptDir/stubs -D $kaptDir/stubs && ` + `rm -rf "$srcJarDir"`, CommandDeps: []string{ "${config.KotlincCmd}", @@ -157,6 +157,7 @@ var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupp }, Rspfile: "$out.rsp", RspfileContent: `$in`, + Restat: true, }, "kotlincFlags", "encodedJavacFlags", "kaptProcessorPath", "kaptProcessor", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "kaptDir", "kotlinJvmTarget", diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index 124827523..662a2d768 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -130,7 +130,7 @@ type bazelPlatformCompatConfigAttributes struct { Src bazel.LabelAttribute } -func (p *platformCompatConfig) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (p *platformCompatConfig) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { props := bazel.BazelTargetModuleProperties{ Rule_class: "platform_compat_config", Bzl_load_location: "//build/bazel/rules/java:platform_compat_config.bzl", diff --git a/java/plugin.go b/java/plugin.go index 51272981b..4d4c199f7 100644 --- a/java/plugin.go +++ b/java/plugin.go @@ -64,7 +64,7 @@ type pluginAttributes struct { } // ConvertWithBp2build is used to convert android_app to Bazel. -func (p *Plugin) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (p *Plugin) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { pluginName := p.Name() commonAttrs, bp2BuildInfo, supported := p.convertLibraryAttrsBp2Build(ctx) if !supported { diff --git a/java/sdk_library.go b/java/sdk_library.go index d1620af9f..27f862662 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2276,27 +2276,25 @@ func SdkLibraryFactory() android.Module { } type bazelSdkLibraryAttributes struct { - Public bazel.StringAttribute - System bazel.StringAttribute - Test bazel.StringAttribute - Module_lib bazel.StringAttribute - System_server bazel.StringAttribute + Public *bazel.Label + System *bazel.Label + Test *bazel.Label + Module_lib *bazel.Label + System_server *bazel.Label } // java_sdk_library bp2build converter -func (module *SdkLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) { +func (module *SdkLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { if ctx.ModuleType() != "java_sdk_library" { ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "") return } - nameToAttr := make(map[string]bazel.StringAttribute) + nameToAttr := make(map[string]*bazel.Label) for _, scope := range module.getGeneratedApiScopes(ctx) { - apiSurfaceFile := path.Join(module.getApiDir(), scope.apiFilePrefix+"current.txt") - var scopeStringAttribute bazel.StringAttribute - scopeStringAttribute.SetValue(apiSurfaceFile) - nameToAttr[scope.name] = scopeStringAttribute + apiSurfaceFile := android.BazelLabelForModuleSrcSingle(ctx, path.Join(module.getApiDir(), scope.apiFilePrefix+"current.txt")) + nameToAttr[scope.name] = &apiSurfaceFile } attrs := bazelSdkLibraryAttributes{ @@ -2355,6 +2353,7 @@ type sdkLibraryImportProperties struct { type SdkLibraryImport struct { android.ModuleBase android.DefaultableModuleBase + android.BazelModuleBase prebuilt android.Prebuilt android.ApexModuleBase @@ -2438,6 +2437,7 @@ func sdkLibraryImportFactory() android.Module { android.InitPrebuiltModule(module, &[]string{""}) android.InitApexModule(module) + android.InitBazelModule(module) InitJavaModule(module, android.HostAndDeviceSupported) module.SetDefaultableHook(func(mctx android.DefaultableHookContext) { @@ -2448,6 +2448,33 @@ func sdkLibraryImportFactory() android.Module { return module } +// java_sdk_library bp2build converter +func (i *SdkLibraryImport) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) { + nameToAttr := make(map[string]*bazel.Label) + + for scope, props := range i.scopeProperties { + if api := proptools.String(props.Current_api); api != "" { + apiSurfaceFile := android.BazelLabelForModuleSrcSingle(ctx, api) + nameToAttr[scope.name] = &apiSurfaceFile + } + } + + attrs := bazelSdkLibraryAttributes{ + Public: nameToAttr["public"], + System: nameToAttr["system"], + Test: nameToAttr["test"], + Module_lib: nameToAttr["module-lib"], + System_server: nameToAttr["system-server"], + } + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_sdk_library", + Bzl_load_location: "//build/bazel/rules/java:sdk_library.bzl", + } + + name := android.RemoveOptionalPrebuiltPrefix(i.Name()) + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, &attrs) +} + var _ PermittedPackagesForUpdatableBootJars = (*SdkLibraryImport)(nil) func (module *SdkLibraryImport) PermittedPackagesForUpdatableBootJars() []string { @@ -2479,6 +2506,10 @@ func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHo if len(scopeProperties.Stub_srcs) > 0 { module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties) } + + if scopeProperties.Current_api != nil { + module.createPrebuiltApiContribution(mctx, apiScope, scopeProperties) + } } javaSdkLibraries := javaSdkLibraries(mctx.Config()) @@ -2534,6 +2565,25 @@ func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.Defaulta mctx.CreateModule(PrebuiltStubsSourcesFactory, &props) } +func (module *SdkLibraryImport) createPrebuiltApiContribution(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) { + api_file := scopeProperties.Current_api + api_surface := &apiScope.name + + props := struct { + Name *string + Api_surface *string + Api_file *string + Visibility []string + }{} + + props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope) + ".api.contribution") + props.Api_surface = api_surface + props.Api_file = api_file + props.Visibility = []string{"//visibility:override", "//visibility:public"} + + mctx.CreateModule(ApiContributionImportFactory, &props) +} + // Add the dependencies on the child module in the component deps mutator so that it // creates references to the prebuilt and not the source modules. func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 868d697ce..0b46919d2 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -74,6 +74,8 @@ func TestJavaSdkLibrary(t *testing.T) { name: "quuz", public: { jars: ["c.jar"], + current_api: "api/current.txt", + removed_api: "api/removed.txt", }, } java_sdk_library_import { @@ -173,6 +175,9 @@ func TestJavaSdkLibrary(t *testing.T) { android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs) } + // test if quuz have created the api_contribution module + result.ModuleForTests(apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "") + fooDexJar := result.ModuleForTests("foo", "android_common").Rule("d8") // tests if kotlinc generated files are NOT excluded from output of foo. android.AssertStringDoesNotContain(t, "foo dex", fooDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module") |