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
This commit is contained in:
Sasha Smundak
2022-08-04 13:31:14 -07:00
parent a93c62b375
commit 8bea267caf
8 changed files with 144 additions and 10 deletions

View File

@@ -37,6 +37,7 @@ const (
var ( var (
Bp2buildDefaultConfig = Bp2BuildConfig{ Bp2buildDefaultConfig = Bp2BuildConfig{
"art": Bp2BuildDefaultTrue,
"art/libartbase": Bp2BuildDefaultTrueRecursively, "art/libartbase": Bp2BuildDefaultTrueRecursively,
"art/libartpalette": Bp2BuildDefaultTrueRecursively, "art/libartpalette": Bp2BuildDefaultTrueRecursively,
"art/libdexfile": Bp2BuildDefaultTrueRecursively, "art/libdexfile": Bp2BuildDefaultTrueRecursively,
@@ -54,6 +55,7 @@ var (
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir "build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue, "build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
"build/soong/cc/symbolfile": Bp2BuildDefaultTrue, "build/soong/cc/symbolfile": Bp2BuildDefaultTrue,
"build/soong/licenses": Bp2BuildDefaultTrue,
"build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively, "build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively,
"build/soong/scripts": Bp2BuildDefaultTrueRecursively, "build/soong/scripts": Bp2BuildDefaultTrueRecursively,
@@ -98,6 +100,7 @@ var (
"external/aac": Bp2BuildDefaultTrueRecursively, "external/aac": Bp2BuildDefaultTrueRecursively,
"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively, "external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
"external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively, "external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively,
"external/auto": Bp2BuildDefaultTrue,
"external/auto/common": Bp2BuildDefaultTrueRecursively, "external/auto/common": Bp2BuildDefaultTrueRecursively,
"external/auto/service": Bp2BuildDefaultTrueRecursively, "external/auto/service": Bp2BuildDefaultTrueRecursively,
"external/boringssl": Bp2BuildDefaultTrueRecursively, "external/boringssl": Bp2BuildDefaultTrueRecursively,
@@ -232,6 +235,7 @@ var (
"prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively,
"prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue, "prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue,
"prebuilts/sdk/current/support": Bp2BuildDefaultTrue, "prebuilts/sdk/current/support": Bp2BuildDefaultTrue,
"prebuilts/tools": Bp2BuildDefaultTrue,
"prebuilts/tools/common/m2": Bp2BuildDefaultTrue, "prebuilts/tools/common/m2": Bp2BuildDefaultTrue,
"system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures "system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures
@@ -273,6 +277,7 @@ var (
"system/libprocinfo": Bp2BuildDefaultTrue, "system/libprocinfo": Bp2BuildDefaultTrue,
"system/libziparchive": Bp2BuildDefaultTrueRecursively, "system/libziparchive": Bp2BuildDefaultTrueRecursively,
"system/logging": Bp2BuildDefaultTrueRecursively, "system/logging": Bp2BuildDefaultTrueRecursively,
"system/media": Bp2BuildDefaultTrue,
"system/media/audio": Bp2BuildDefaultTrueRecursively, "system/media/audio": Bp2BuildDefaultTrueRecursively,
"system/media/audio_utils": Bp2BuildDefaultTrueRecursively, "system/media/audio_utils": Bp2BuildDefaultTrueRecursively,
"system/memory/libion": Bp2BuildDefaultTrueRecursively, "system/memory/libion": Bp2BuildDefaultTrueRecursively,
@@ -492,6 +497,7 @@ var (
} }
Bp2buildModuleTypeAlwaysConvertList = []string{ Bp2buildModuleTypeAlwaysConvertList = []string{
"license",
"linker_config", "linker_config",
"java_import", "java_import",
"java_import_host", "java_import_host",

View File

@@ -78,9 +78,11 @@ func (m *licenseModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
Visibility: m.properties.Visibility, Visibility: m.properties.Visibility,
} }
// TODO(asmundak): Soong supports multiple license texts while Bazel does not. // TODO(asmundak): Soong supports multiple license texts while Bazel's license
if len(m.properties.License_text) > 1 { // rule does not. Have android_license create a genrule to concatenate multiple
fmt.Fprintf(os.Stderr, "%s:%s: warning: using only the first license_text item\n", // 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()) ctx.ModuleDir(), m.Name())
} }
if len(m.properties.License_text) >= 1 { if len(m.properties.License_text) >= 1 {

View File

@@ -15,6 +15,7 @@
package android package android
import ( import (
"android/soong/bazel"
"github.com/google/blueprint" "github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
) )
@@ -37,12 +38,33 @@ type packageProperties struct {
Default_applicable_licenses []string Default_applicable_licenses []string
} }
type bazelPackageAttributes struct {
Default_visibility []string
Default_applicable_licenses bazel.LabelListAttribute
}
type packageModule struct { type packageModule struct {
ModuleBase ModuleBase
BazelModuleBase
properties packageProperties 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) { func (p *packageModule) GenerateAndroidBuildActions(ModuleContext) {
// Nothing to do. // Nothing to do.
} }
@@ -59,7 +81,7 @@ func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModule
func PackageFactory() Module { func PackageFactory() Module {
module := &packageModule{} 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 // 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 // module. Set that name at the earliest possible moment that information is available
@@ -76,5 +98,7 @@ func PackageFactory() Module {
// its checking and parsing phases so make it the primary licenses property. // its checking and parsing phases so make it the primary licenses property.
setPrimaryLicensesProperty(module, "default_applicable_licenses", &module.properties.Default_applicable_licenses) setPrimaryLicensesProperty(module, "default_applicable_licenses", &module.properties.Default_applicable_licenses)
InitBazelModule(module)
return module return module
} }

View File

@@ -67,6 +67,7 @@ bootstrap_go_package {
"license_kind_conversion_test.go", "license_kind_conversion_test.go",
"linker_config_conversion_test.go", "linker_config_conversion_test.go",
"ndk_headers_conversion_test.go", "ndk_headers_conversion_test.go",
"package_conversion_test.go",
"performance_test.go", "performance_test.go",
"prebuilt_etc_conversion_test.go", "prebuilt_etc_conversion_test.go",
"python_binary_conversion_test.go", "python_binary_conversion_test.go",

View File

@@ -64,7 +64,16 @@ func (t BazelTarget) Label() string {
// BazelTargets is a typedef for a slice of BazelTarget objects. // BazelTargets is a typedef for a slice of BazelTarget objects.
type BazelTargets []BazelTarget 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() { func (targets BazelTargets) sort() {
sort.Slice(targets, func(i, j int) bool { sort.Slice(targets, func(i, j int) bool {
return targets[i].name < targets[j].name return targets[i].name < targets[j].name
@@ -77,7 +86,9 @@ func (targets BazelTargets) sort() {
func (targets BazelTargets) String() string { func (targets BazelTargets) String() string {
var res string var res string
for i, target := range targets { for i, target := range targets {
res += target.content if target.ruleClass != "package" {
res += target.content
}
if i != len(targets)-1 { if i != len(targets)-1 {
res += "\n\n" res += "\n\n"
} }

View File

@@ -96,10 +96,14 @@ func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode)
# This file was automatically generated by bp2build for the Bazel migration project. # 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. # 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 += 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 { } else if mode == QueryView {
content = soongModuleLoad content = soongModuleLoad
} }
@@ -160,7 +164,7 @@ func shouldSkipStructField(field reflect.StructField) bool {
// internal to Soong only, and these fields do not have PkgPath. // internal to Soong only, and these fields do not have PkgPath.
return true 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 // but cannot be set in a .bp file
if proptools.HasTag(field, "blueprint", "mutated") { if proptools.HasTag(field, "blueprint", "mutated") {
return true return true

View File

@@ -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,
})
}
}

View File

@@ -123,6 +123,7 @@ function create_mock_bazel {
symlink_directory prebuilts/jdk symlink_directory prebuilts/jdk
symlink_directory external/bazel-skylib symlink_directory external/bazel-skylib
symlink_directory external/bazelbuild-rules_android symlink_directory external/bazelbuild-rules_android
symlink_directory external/bazelbuild-rules_license
symlink_directory external/bazelbuild-kotlin-rules symlink_directory external/bazelbuild-kotlin-rules
symlink_file WORKSPACE symlink_file WORKSPACE