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:
@@ -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",
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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",
|
||||||
|
@@ -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"
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
85
bp2build/package_conversion_test.go
Normal file
85
bp2build/package_conversion_test.go
Normal 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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user