diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index b668042b9..b05c64baa 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -169,6 +169,7 @@ var ( "packages/apps/DevCamera": Bp2BuildDefaultTrue, "packages/apps/HTMLViewer": Bp2BuildDefaultTrue, "packages/apps/Protips": Bp2BuildDefaultTrue, + "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue, "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively, "packages/modules/adb": Bp2BuildDefaultTrue, "packages/modules/adb/apex": Bp2BuildDefaultTrue, @@ -182,6 +183,8 @@ var ( "packages/screensavers/Basic": Bp2BuildDefaultTrue, "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue, "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, + "prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue, + "prebuilts/sdk/current/support": Bp2BuildDefaultTrue, "prebuilts/tools/common/m2": Bp2BuildDefaultTrue, "system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures "system/apex/apexer": Bp2BuildDefaultTrue, @@ -258,7 +261,6 @@ var ( "packages/apps/Music":/* recursive = */ true, "packages/apps/QuickSearchBox":/* recursive = */ true, - "packages/apps/WallpaperPicker":/* recursive = */ false, "prebuilts/bazel":/* recursive = */ true, "prebuilts/bundletool":/* recursive = */ true, @@ -267,8 +269,6 @@ var ( "prebuilts/jdk/jdk11":/* recursive = */ false, "prebuilts/misc":/* recursive = */ false, // not recursive because we need bp2build converted build files in prebuilts/misc/common/asm "prebuilts/sdk":/* recursive = */ false, - "prebuilts/sdk/current/extras/app-toolkit":/* recursive = */ false, - "prebuilts/sdk/current/support":/* recursive = */ false, "prebuilts/sdk/tools":/* recursive = */ false, "prebuilts/r8":/* recursive = */ false, } diff --git a/bp2build/Android.bp b/bp2build/Android.bp index 07557d604..713ee090f 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -34,6 +34,7 @@ bootstrap_go_package { "soong-ui-metrics", ], testSrcs: [ + "aar_conversion_test.go", "android_app_certificate_conversion_test.go", "android_app_conversion_test.go", "apex_conversion_test.go", diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go new file mode 100644 index 000000000..8e7c2b5da --- /dev/null +++ b/bp2build/aar_conversion_test.go @@ -0,0 +1,138 @@ +// Copyright 2022 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "android/soong/java" + "fmt" + + "testing" +) + +func TestConvertAndroidLibrary(t *testing.T) { + t.Helper() + RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{ + Description: "Android Library - simple example", + ModuleTypeUnderTest: "android_library", + ModuleTypeUnderTestFactory: java.AndroidLibraryFactory, + Filesystem: map[string]string{ + "lib.java": "", + "arm.java": "", + "x86.java": "", + "res/res.png": "", + "manifest/AndroidManifest.xml": "", + }, + Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + ` +android_library { + name: "TestLib", + srcs: ["lib.java"], + arch: { + arm: { + srcs: ["arm.java"], + }, + x86: { + srcs: ["x86.java"], + } + }, + manifest: "manifest/AndroidManifest.xml", + static_libs: ["static_lib_dep"], + java_version: "7", +} +`, + ExpectedBazelTargets: []string{ + makeBazelTarget( + "android_library", + "TestLib", + AttrNameToString{ + "srcs": `["lib.java"] + select({ + "//build/bazel/platforms/arch:arm": ["arm.java"], + "//build/bazel/platforms/arch:x86": ["x86.java"], + "//conditions:default": [], + })`, + "manifest": `"manifest/AndroidManifest.xml"`, + "resource_files": `["res/res.png"]`, + "deps": `[":static_lib_dep"]`, + "exports": `[":static_lib_dep"]`, + "javacopts": `["-source 1.7 -target 1.7"]`, + }), + }}) +} + +func TestConvertAndroidLibraryWithNoSources(t *testing.T) { + t.Helper() + RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{ + Description: "Android Library - modules with deps must have sources", + ModuleTypeUnderTest: "android_library", + ModuleTypeUnderTestFactory: java.AndroidLibraryFactory, + Filesystem: map[string]string{ + "res/res.png": "", + "AndroidManifest.xml": "", + }, + Blueprint: simpleModuleDoNotConvertBp2build("android_library", "lib_dep") + ` +android_library { + name: "TestLib", + srcs: [], + manifest: "AndroidManifest.xml", + libs: ["lib_dep"], +} +`, + ExpectedErr: fmt.Errorf("Module has direct dependencies but no sources. Bazel will not allow this."), + ExpectedBazelTargets: []string{}, + }) +} + +func TestConvertAndroidLibraryImport(t *testing.T) { + t.Helper() + RunBp2BuildTestCase( + t, + func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("android_library", java.AndroidLibraryFactory) + }, + Bp2buildTestCase{ + Description: "Android Library Import", + ModuleTypeUnderTest: "android_library_import", + ModuleTypeUnderTestFactory: java.AARImportFactory, + Filesystem: map[string]string{ + "import.aar": "", + }, + // Bazel's aar_import can only export *_import targets, so we expect + // only "static_import_dep" in exports, but both "static_lib_dep" and + // "static_import_dep" in deps + Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + + simpleModuleDoNotConvertBp2build("android_library_import", "static_import_dep") + ` +android_library_import { + name: "TestImport", + aars: ["import.aar"], + static_libs: ["static_lib_dep", "static_import_dep"], +} +`, + ExpectedBazelTargets: []string{ + makeBazelTarget( + "aar_import", + "TestImport", + AttrNameToString{ + "aar": `"import.aar"`, + "deps": `[ + ":static_lib_dep", + ":static_import_dep", + ]`, + "exports": `[":static_import_dep"]`, + }, + ), + }, + }, + ) +} diff --git a/java/aar.go b/java/aar.go index a59ecb8ca..d5996ba02 100644 --- a/java/aar.go +++ b/java/aar.go @@ -21,6 +21,7 @@ import ( "strings" "android/soong/android" + "android/soong/bazel" "android/soong/dexpreopt" "github.com/google/blueprint" @@ -490,6 +491,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa type AndroidLibrary struct { Library aapt + android.BazelModuleBase androidLibraryProperties androidLibraryProperties @@ -605,6 +607,7 @@ func AndroidLibraryFactory() android.Module { android.InitApexModule(module) InitJavaModule(module, android.DeviceSupported) + android.InitBazelModule(module) return module } @@ -643,6 +646,7 @@ type AARImport struct { android.ModuleBase android.DefaultableModuleBase android.ApexModuleBase + android.BazelModuleBase prebuilt android.Prebuilt // Functionality common to Module and Import. @@ -973,5 +977,96 @@ func AARImportFactory() android.Module { android.InitPrebuiltModule(module, &module.properties.Aars) android.InitApexModule(module) InitJavaModuleMultiTargets(module, android.DeviceSupported) + android.InitBazelModule(module) return module } + +type bazelAapt struct { + Manifest bazel.Label + Resource_files bazel.LabelListAttribute +} + +type bazelAndroidLibrary struct { + *javaLibraryAttributes + *bazelAapt +} + +type bazelAndroidLibraryImport struct { + Aar bazel.Label + Deps bazel.LabelListAttribute + Exports bazel.LabelListAttribute +} + +func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt { + manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") + + resourceFiles := bazel.LabelList{ + Includes: []bazel.Label{}, + } + for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") { + files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir)) + resourceFiles.Includes = append(resourceFiles.Includes, files...) + } + return &bazelAapt{ + android.BazelLabelForModuleSrcSingle(ctx, manifest), + bazel.MakeLabelListAttribute(resourceFiles), + } +} + +func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + 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. + for _, depName := range a.properties.Static_libs { + if dep, ok := ctx.ModuleFromName(depName); ok { + switch dep.(type) { + case *AARImport, *Import: + exportableStaticLibs = append(exportableStaticLibs, depName) + } + } + } + name := android.RemoveOptionalPrebuiltPrefix(a.Name()) + deps := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(append(a.properties.Static_libs, a.properties.Libs...)))) + exports := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(exportableStaticLibs)) + + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "aar_import", + Bzl_load_location: "@rules_android//rules:rules.bzl", + }, + android.CommonAttributes{Name: name}, + &bazelAndroidLibraryImport{ + Aar: aars.Includes[0], + Deps: bazel.MakeLabelListAttribute(deps), + Exports: bazel.MakeLabelListAttribute(exports), + }, + ) + +} + +func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + commonAttrs, depLabels := a.convertLibraryAttrsBp2Build(ctx) + + deps := depLabels.Deps + 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.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "android_library", + Bzl_load_location: "@rules_android//rules:rules.bzl", + }, + android.CommonAttributes{Name: a.Name()}, + &bazelAndroidLibrary{ + &javaLibraryAttributes{ + javaCommonAttributes: commonAttrs, + Deps: deps, + Exports: depLabels.StaticDeps, + }, + a.convertAaptAttrsWithBp2Build(ctx), + }, + ) +} diff --git a/java/app.go b/java/app.go index c3699784c..7b5efc7c4 100755 --- a/java/app.go +++ b/java/app.go @@ -1444,10 +1444,9 @@ func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *An type bazelAndroidAppAttributes struct { *javaCommonAttributes + *bazelAapt Deps bazel.LabelListAttribute - Manifest bazel.Label Custom_package *string - Resource_files bazel.LabelListAttribute Certificate *bazel.Label Certificate_name *string } @@ -1457,23 +1456,9 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { commonAttrs, depLabels := a.convertLibraryAttrsBp2Build(ctx) deps := depLabels.Deps - if !commonAttrs.Srcs.IsEmpty() { - deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them - } else if !deps.IsEmpty() || !depLabels.StaticDeps.IsEmpty() { - ctx.ModuleErrorf("android_app has dynamic or static dependencies but no sources." + - " Bazel does not allow direct dependencies without sources nor exported" + - " dependencies on android_binary rule.") - } + deps.Append(depLabels.StaticDeps) - manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") - - resourceFiles := bazel.LabelList{ - Includes: []bazel.Label{}, - } - for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") { - files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir)) - resourceFiles.Includes = append(resourceFiles.Includes, files...) - } + aapt := a.convertAaptAttrsWithBp2Build(ctx) var certificate *bazel.Label certificateNamePtr := a.overridableAppProperties.Certificate @@ -1484,14 +1469,12 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { certificate = &c certificateNamePtr = nil } - attrs := &bazelAndroidAppAttributes{ commonAttrs, + aapt, deps, - android.BazelLabelForModuleSrcSingle(ctx, manifest), // TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES a.overridableAppProperties.Package_name, - bazel.MakeLabelListAttribute(resourceFiles), certificate, certificateNamePtr, } @@ -1500,7 +1483,6 @@ func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) { Rule_class: "android_binary", Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl", } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs) } diff --git a/java/java.go b/java/java.go index f4ec04ef4..481c625f3 100644 --- a/java/java.go +++ b/java/java.go @@ -2333,12 +2333,12 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) var deps bazel.LabelList if m.properties.Libs != nil { - deps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Libs)) + deps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Libs)))) } var staticDeps bazel.LabelList if m.properties.Static_libs != nil { - staticDeps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Static_libs)) + staticDeps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Static_libs)))) } protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition])