Implement bp2build for the `package` module
* We are interested mostly in the conversion the `default_applicable_licenses`
attribute, as `default_visibility` cannot be handled until every module's
`visibility` is handled.
* Several referenced license modules had to be manually enabled for
conversion, and likewise a few trivial Android.bp containing only
package and license modules.
* As Bazel allows only a single `package` rule, the package rules in a
manually converted BUILD.bazel files were removed (in
external/protobuf and prebuilts/clang/host/linux-x86 trees).
* The converted package rule is emitted before the `load` statements per
Bazel documentation.
Bug: 190817312
Test: treehugger
Change-Id: If8bf6fee1580177de3bb402923615bcd48923ed2
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index ab028e5..e55f297 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -37,6 +37,7 @@
var (
Bp2buildDefaultConfig = Bp2BuildConfig{
+ "art": Bp2BuildDefaultTrue,
"art/libartbase": Bp2BuildDefaultTrueRecursively,
"art/libartpalette": Bp2BuildDefaultTrueRecursively,
"art/libdexfile": Bp2BuildDefaultTrueRecursively,
@@ -54,6 +55,7 @@
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
"build/soong/cc/symbolfile": Bp2BuildDefaultTrue,
+ "build/soong/licenses": Bp2BuildDefaultTrue,
"build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively,
"build/soong/scripts": Bp2BuildDefaultTrueRecursively,
@@ -98,6 +100,7 @@
"external/aac": Bp2BuildDefaultTrueRecursively,
"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
"external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively,
+ "external/auto": Bp2BuildDefaultTrue,
"external/auto/common": Bp2BuildDefaultTrueRecursively,
"external/auto/service": Bp2BuildDefaultTrueRecursively,
"external/boringssl": Bp2BuildDefaultTrueRecursively,
@@ -232,6 +235,7 @@
"prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively,
"prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue,
"prebuilts/sdk/current/support": Bp2BuildDefaultTrue,
+ "prebuilts/tools": Bp2BuildDefaultTrue,
"prebuilts/tools/common/m2": Bp2BuildDefaultTrue,
"system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures
@@ -273,6 +277,7 @@
"system/libprocinfo": Bp2BuildDefaultTrue,
"system/libziparchive": Bp2BuildDefaultTrueRecursively,
"system/logging": Bp2BuildDefaultTrueRecursively,
+ "system/media": Bp2BuildDefaultTrue,
"system/media/audio": Bp2BuildDefaultTrueRecursively,
"system/media/audio_utils": Bp2BuildDefaultTrueRecursively,
"system/memory/libion": Bp2BuildDefaultTrueRecursively,
@@ -492,6 +497,7 @@
}
Bp2buildModuleTypeAlwaysConvertList = []string{
+ "license",
"linker_config",
"java_import",
"java_import_host",
diff --git a/android/license.go b/android/license.go
index c36f488..cde5e6e 100644
--- a/android/license.go
+++ b/android/license.go
@@ -78,9 +78,11 @@
Visibility: m.properties.Visibility,
}
- // TODO(asmundak): Soong supports multiple license texts while Bazel does not.
- if len(m.properties.License_text) > 1 {
- fmt.Fprintf(os.Stderr, "%s:%s: warning: using only the first license_text item\n",
+ // TODO(asmundak): Soong supports multiple license texts while Bazel's license
+ // rule does not. Have android_license create a genrule to concatenate multiple
+ // license texts.
+ if len(m.properties.License_text) > 1 && ctx.Config().IsEnvTrue("BP2BUILD_VERBOSE") {
+ fmt.Fprintf(os.Stderr, "warning: using only the first license_text item from //%s:%s\n",
ctx.ModuleDir(), m.Name())
}
if len(m.properties.License_text) >= 1 {
diff --git a/android/package.go b/android/package.go
index 878e4c4..2bf6521 100644
--- a/android/package.go
+++ b/android/package.go
@@ -15,6 +15,7 @@
package android
import (
+ "android/soong/bazel"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -37,12 +38,33 @@
Default_applicable_licenses []string
}
+type bazelPackageAttributes struct {
+ Default_visibility []string
+ Default_applicable_licenses bazel.LabelListAttribute
+}
+
type packageModule struct {
ModuleBase
+ BazelModuleBase
properties packageProperties
}
+var _ Bazelable = &packageModule{}
+
+func (p *packageModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "package",
+ },
+ CommonAttributes{},
+ &bazelPackageAttributes{
+ Default_applicable_licenses: bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, p.properties.Default_applicable_licenses)),
+ // FIXME(asmundak): once b/221436821 is resolved
+ Default_visibility: []string{"//visibility:public"},
+ })
+}
+
func (p *packageModule) GenerateAndroidBuildActions(ModuleContext) {
// Nothing to do.
}
@@ -59,7 +81,7 @@
func PackageFactory() Module {
module := &packageModule{}
- module.AddProperties(&module.properties)
+ module.AddProperties(&module.properties, &module.commonProperties.BazelConversionStatus)
// The name is the relative path from build root to the directory containing this
// module. Set that name at the earliest possible moment that information is available
@@ -76,5 +98,7 @@
// its checking and parsing phases so make it the primary licenses property.
setPrimaryLicensesProperty(module, "default_applicable_licenses", &module.properties.Default_applicable_licenses)
+ InitBazelModule(module)
+
return module
}
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index a3f618e..7c9af1a 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -67,6 +67,7 @@
"license_kind_conversion_test.go",
"linker_config_conversion_test.go",
"ndk_headers_conversion_test.go",
+ "package_conversion_test.go",
"performance_test.go",
"prebuilt_etc_conversion_test.go",
"python_binary_conversion_test.go",
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 49b9144..ee162b2 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -64,7 +64,16 @@
// BazelTargets is a typedef for a slice of BazelTarget objects.
type BazelTargets []BazelTarget
-// sort a list of BazelTargets in-place by name
+func (targets BazelTargets) packageRule() *BazelTarget {
+ for _, target := range targets {
+ if target.ruleClass == "package" {
+ return &target
+ }
+ }
+ return nil
+}
+
+// sort a list of BazelTargets in-place, by name, and by generated/handcrafted types.
func (targets BazelTargets) sort() {
sort.Slice(targets, func(i, j int) bool {
return targets[i].name < targets[j].name
@@ -77,7 +86,9 @@
func (targets BazelTargets) String() string {
var res string
for i, target := range targets {
- res += target.content
+ if target.ruleClass != "package" {
+ res += target.content
+ }
if i != len(targets)-1 {
res += "\n\n"
}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 731b17e..b6190c6 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -96,10 +96,14 @@
# This file was automatically generated by bp2build for the Bazel migration project.
# Feel free to edit or test it, but do *not* check it into your version control system.
`
-
- // Hardcode the default visibility.
- content += "package(default_visibility = [\"//visibility:public\"])\n"
content += targets.LoadStatements()
+ content += "\n\n"
+ // Get package rule from the handcrafted BUILD file, otherwise emit the default one.
+ prText := "package(default_visibility = [\"//visibility:public\"])\n"
+ if pr := targets.packageRule(); pr != nil {
+ prText = pr.content
+ }
+ content += prText
} else if mode == QueryView {
content = soongModuleLoad
}
@@ -160,7 +164,7 @@
// internal to Soong only, and these fields do not have PkgPath.
return true
}
- // fields with tag `blueprint:"mutated"` are exported to enable modification in mutators, etc
+ // fields with tag `blueprint:"mutated"` are exported to enable modification in mutators, etc.
// but cannot be set in a .bp file
if proptools.HasTag(field, "blueprint", "mutated") {
return true
diff --git a/bp2build/package_conversion_test.go b/bp2build/package_conversion_test.go
new file mode 100644
index 0000000..3704b2d
--- /dev/null
+++ b/bp2build/package_conversion_test.go
@@ -0,0 +1,85 @@
+// 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/genrule"
+ "testing"
+)
+
+func registerDependentModules(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("license", android.LicenseFactory)
+ ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+}
+
+func TestPackage(t *testing.T) {
+ tests := []struct {
+ description string
+ modules string
+ expected []ExpectedRuleTarget
+ }{
+ {
+ description: "with default applicable licenses",
+ modules: `
+license {
+ name: "my_license",
+ visibility: [":__subpackages__"],
+ license_kinds: ["SPDX-license-identifier-Apache-2.0"],
+ license_text: ["NOTICE"],
+}
+
+package {
+ default_applicable_licenses: ["my_license"],
+}
+`,
+ expected: []ExpectedRuleTarget{
+ {
+ "package",
+ "",
+ AttrNameToString{
+ "default_applicable_licenses": `[":my_license"]`,
+ "default_visibility": `["//visibility:public"]`,
+ },
+ android.HostAndDeviceDefault,
+ },
+ {
+ "android_license",
+ "my_license",
+ AttrNameToString{
+ "license_kinds": `["SPDX-license-identifier-Apache-2.0"]`,
+ "license_text": `"NOTICE"`,
+ "visibility": `[":__subpackages__"]`,
+ },
+ android.HostAndDeviceDefault,
+ },
+ },
+ },
+ }
+ for _, test := range tests {
+ expected := make([]string, 0, len(test.expected))
+ for _, e := range test.expected {
+ expected = append(expected, e.String())
+ }
+ RunBp2BuildTestCase(t, registerDependentModules,
+ Bp2buildTestCase{
+ Description: test.description,
+ ModuleTypeUnderTest: "package",
+ ModuleTypeUnderTestFactory: android.PackageFactory,
+ Blueprint: test.modules,
+ ExpectedBazelTargets: expected,
+ })
+ }
+}
diff --git a/tests/lib.sh b/tests/lib.sh
index 7248ade..4b4d908 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -123,6 +123,7 @@
symlink_directory prebuilts/jdk
symlink_directory external/bazel-skylib
symlink_directory external/bazelbuild-rules_android
+ symlink_directory external/bazelbuild-rules_license
symlink_directory external/bazelbuild-kotlin-rules
symlink_file WORKSPACE