Always merge build files
Previous behavior: - Packge not listed in bp2buildKeepExistingBuildFile: - Use bp2build generated build file - Package listed in bp2buildKeepExistingBuildFile: - Use handcrafted build file even if there were allowlisted bp2build modules in the same package. - Package listed in bp2buildKeepExistingBuildFile and a soong module has a bp2build: { label } attribute: - Merge the handcrafted and bp2build generated build files New behavior: - Packge not listed in bp2buildKeepExistingBuildFile: - Use bp2build generated build file - Package listed in bp2buildKeepExistingBuildFile: - Merge with bp2build generated build file. Bug: 234167862 Test: ./build/bazel/ci/bp2build.sh Change-Id: Ifbaf4f8f0f5158b5b2bd6d534eb2311e2e5f399b
This commit is contained in:
@@ -46,19 +46,16 @@ var (
|
|||||||
"bionic": Bp2BuildDefaultTrueRecursively,
|
"bionic": Bp2BuildDefaultTrueRecursively,
|
||||||
"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
|
"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
|
||||||
|
|
||||||
"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
|
"build/bazel": Bp2BuildDefaultTrueRecursively,
|
||||||
"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
|
"build/make/target/product/security": Bp2BuildDefaultTrue,
|
||||||
"build/bazel/examples/python": Bp2BuildDefaultTrueRecursively,
|
"build/make/tools/signapk": Bp2BuildDefaultTrue,
|
||||||
"build/bazel/examples/gensrcs": Bp2BuildDefaultTrueRecursively,
|
"build/make/tools/zipalign": Bp2BuildDefaultTrueRecursively,
|
||||||
"build/make/target/product/security": Bp2BuildDefaultTrue,
|
"build/soong": Bp2BuildDefaultTrue,
|
||||||
"build/make/tools/signapk": Bp2BuildDefaultTrue,
|
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
|
||||||
"build/make/tools/zipalign": Bp2BuildDefaultTrueRecursively,
|
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
|
||||||
"build/soong": Bp2BuildDefaultTrue,
|
"build/soong/cc/symbolfile": Bp2BuildDefaultTrue,
|
||||||
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
|
"build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively,
|
||||||
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
|
"build/soong/scripts": Bp2BuildDefaultTrueRecursively,
|
||||||
"build/soong/cc/symbolfile": Bp2BuildDefaultTrue,
|
|
||||||
"build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively,
|
|
||||||
"build/soong/scripts": Bp2BuildDefaultTrueRecursively,
|
|
||||||
|
|
||||||
"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
|
"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
|
||||||
"development/apps/DevelopmentSettings": Bp2BuildDefaultTrue,
|
"development/apps/DevelopmentSettings": Bp2BuildDefaultTrue,
|
||||||
@@ -282,24 +279,7 @@ var (
|
|||||||
// This is actually build/bazel/build.BAZEL symlinked to ./BUILD
|
// This is actually build/bazel/build.BAZEL symlinked to ./BUILD
|
||||||
".":/*recursive = */ false,
|
".":/*recursive = */ false,
|
||||||
|
|
||||||
// build/bazel/examples/apex/... BUILD files should be generated, so
|
"build/bazel":/* recursive = */ true,
|
||||||
// build/bazel is not recursive. Instead list each subdirectory under
|
|
||||||
// build/bazel explicitly.
|
|
||||||
"build/bazel":/* recursive = */ false,
|
|
||||||
"build/bazel/ci/dist":/* recursive = */ false,
|
|
||||||
"build/bazel/examples/android_app":/* recursive = */ true,
|
|
||||||
"build/bazel/examples/cc":/* recursive = */ true,
|
|
||||||
"build/bazel/examples/java":/* recursive = */ true,
|
|
||||||
"build/bazel/examples/partitions":/* recursive = */ true,
|
|
||||||
"build/bazel/bazel_skylib":/* recursive = */ true,
|
|
||||||
"build/bazel/rules":/* recursive = */ true,
|
|
||||||
"build/bazel/rules_cc":/* recursive = */ true,
|
|
||||||
"build/bazel/scripts":/* recursive = */ true,
|
|
||||||
"build/bazel/tests":/* recursive = */ true,
|
|
||||||
"build/bazel/platforms":/* recursive = */ true,
|
|
||||||
"build/bazel/product_config":/* recursive = */ true,
|
|
||||||
"build/bazel/product_variables":/* recursive = */ true,
|
|
||||||
"build/bazel/vendor/google":/* recursive = */ true,
|
|
||||||
"build/bazel_common_rules":/* recursive = */ true,
|
"build/bazel_common_rules":/* recursive = */ true,
|
||||||
// build/make/tools/signapk BUILD file is generated, so build/make/tools is not recursive.
|
// build/make/tools/signapk BUILD file is generated, so build/make/tools is not recursive.
|
||||||
"build/make/tools":/* recursive = */ false,
|
"build/make/tools":/* recursive = */ false,
|
||||||
|
@@ -211,7 +211,7 @@ func (b *BazelModuleBase) GetBazelLabel(ctx BazelConversionPathContext, module b
|
|||||||
return "" // no label for unconverted module
|
return "" // no label for unconverted module
|
||||||
}
|
}
|
||||||
|
|
||||||
type bp2BuildConversionAllowlist struct {
|
type Bp2BuildConversionAllowlist struct {
|
||||||
// Configure modules in these directories to enable bp2build_available: true or false by default.
|
// Configure modules in these directories to enable bp2build_available: true or false by default.
|
||||||
defaultConfig allowlists.Bp2BuildConfig
|
defaultConfig allowlists.Bp2BuildConfig
|
||||||
|
|
||||||
@@ -241,14 +241,14 @@ type bp2BuildConversionAllowlist struct {
|
|||||||
|
|
||||||
// GenerateCcLibraryStaticOnly returns whether a cc_library module should only
|
// GenerateCcLibraryStaticOnly returns whether a cc_library module should only
|
||||||
// generate a static version of itself based on the current global configuration.
|
// generate a static version of itself based on the current global configuration.
|
||||||
func (a bp2BuildConversionAllowlist) GenerateCcLibraryStaticOnly(moduleName string) bool {
|
func (a Bp2BuildConversionAllowlist) GenerateCcLibraryStaticOnly(moduleName string) bool {
|
||||||
return a.ccLibraryStaticOnly[moduleName]
|
return a.ccLibraryStaticOnly[moduleName]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBp2BuildAllowlist creates a new, empty bp2BuildConversionAllowlist
|
// NewBp2BuildAllowlist creates a new, empty Bp2BuildConversionAllowlist
|
||||||
// which can be populated using builder pattern Set* methods
|
// which can be populated using builder pattern Set* methods
|
||||||
func NewBp2BuildAllowlist() bp2BuildConversionAllowlist {
|
func NewBp2BuildAllowlist() Bp2BuildConversionAllowlist {
|
||||||
return bp2BuildConversionAllowlist{
|
return Bp2BuildConversionAllowlist{
|
||||||
allowlists.Bp2BuildConfig{},
|
allowlists.Bp2BuildConfig{},
|
||||||
map[string]bool{},
|
map[string]bool{},
|
||||||
map[string]bool{},
|
map[string]bool{},
|
||||||
@@ -259,7 +259,7 @@ func NewBp2BuildAllowlist() bp2BuildConversionAllowlist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaultConfig copies the entries from defaultConfig into the allowlist
|
// SetDefaultConfig copies the entries from defaultConfig into the allowlist
|
||||||
func (a bp2BuildConversionAllowlist) SetDefaultConfig(defaultConfig allowlists.Bp2BuildConfig) bp2BuildConversionAllowlist {
|
func (a Bp2BuildConversionAllowlist) SetDefaultConfig(defaultConfig allowlists.Bp2BuildConfig) Bp2BuildConversionAllowlist {
|
||||||
if a.defaultConfig == nil {
|
if a.defaultConfig == nil {
|
||||||
a.defaultConfig = allowlists.Bp2BuildConfig{}
|
a.defaultConfig = allowlists.Bp2BuildConfig{}
|
||||||
}
|
}
|
||||||
@@ -271,7 +271,7 @@ func (a bp2BuildConversionAllowlist) SetDefaultConfig(defaultConfig allowlists.B
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetKeepExistingBuildFile copies the entries from keepExistingBuildFile into the allowlist
|
// SetKeepExistingBuildFile copies the entries from keepExistingBuildFile into the allowlist
|
||||||
func (a bp2BuildConversionAllowlist) SetKeepExistingBuildFile(keepExistingBuildFile map[string]bool) bp2BuildConversionAllowlist {
|
func (a Bp2BuildConversionAllowlist) SetKeepExistingBuildFile(keepExistingBuildFile map[string]bool) Bp2BuildConversionAllowlist {
|
||||||
if a.keepExistingBuildFile == nil {
|
if a.keepExistingBuildFile == nil {
|
||||||
a.keepExistingBuildFile = map[string]bool{}
|
a.keepExistingBuildFile = map[string]bool{}
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ func (a bp2BuildConversionAllowlist) SetKeepExistingBuildFile(keepExistingBuildF
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetModuleAlwaysConvertList copies the entries from moduleAlwaysConvert into the allowlist
|
// SetModuleAlwaysConvertList copies the entries from moduleAlwaysConvert into the allowlist
|
||||||
func (a bp2BuildConversionAllowlist) SetModuleAlwaysConvertList(moduleAlwaysConvert []string) bp2BuildConversionAllowlist {
|
func (a Bp2BuildConversionAllowlist) SetModuleAlwaysConvertList(moduleAlwaysConvert []string) Bp2BuildConversionAllowlist {
|
||||||
if a.moduleAlwaysConvert == nil {
|
if a.moduleAlwaysConvert == nil {
|
||||||
a.moduleAlwaysConvert = map[string]bool{}
|
a.moduleAlwaysConvert = map[string]bool{}
|
||||||
}
|
}
|
||||||
@@ -295,7 +295,7 @@ func (a bp2BuildConversionAllowlist) SetModuleAlwaysConvertList(moduleAlwaysConv
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetModuleTypeAlwaysConvertList copies the entries from moduleTypeAlwaysConvert into the allowlist
|
// SetModuleTypeAlwaysConvertList copies the entries from moduleTypeAlwaysConvert into the allowlist
|
||||||
func (a bp2BuildConversionAllowlist) SetModuleTypeAlwaysConvertList(moduleTypeAlwaysConvert []string) bp2BuildConversionAllowlist {
|
func (a Bp2BuildConversionAllowlist) SetModuleTypeAlwaysConvertList(moduleTypeAlwaysConvert []string) Bp2BuildConversionAllowlist {
|
||||||
if a.moduleTypeAlwaysConvert == nil {
|
if a.moduleTypeAlwaysConvert == nil {
|
||||||
a.moduleTypeAlwaysConvert = map[string]bool{}
|
a.moduleTypeAlwaysConvert = map[string]bool{}
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ func (a bp2BuildConversionAllowlist) SetModuleTypeAlwaysConvertList(moduleTypeAl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetModuleDoNotConvertList copies the entries from moduleDoNotConvert into the allowlist
|
// SetModuleDoNotConvertList copies the entries from moduleDoNotConvert into the allowlist
|
||||||
func (a bp2BuildConversionAllowlist) SetModuleDoNotConvertList(moduleDoNotConvert []string) bp2BuildConversionAllowlist {
|
func (a Bp2BuildConversionAllowlist) SetModuleDoNotConvertList(moduleDoNotConvert []string) Bp2BuildConversionAllowlist {
|
||||||
if a.moduleDoNotConvert == nil {
|
if a.moduleDoNotConvert == nil {
|
||||||
a.moduleDoNotConvert = map[string]bool{}
|
a.moduleDoNotConvert = map[string]bool{}
|
||||||
}
|
}
|
||||||
@@ -319,7 +319,7 @@ func (a bp2BuildConversionAllowlist) SetModuleDoNotConvertList(moduleDoNotConver
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetCcLibraryStaticOnlyList copies the entries from ccLibraryStaticOnly into the allowlist
|
// SetCcLibraryStaticOnlyList copies the entries from ccLibraryStaticOnly into the allowlist
|
||||||
func (a bp2BuildConversionAllowlist) SetCcLibraryStaticOnlyList(ccLibraryStaticOnly []string) bp2BuildConversionAllowlist {
|
func (a Bp2BuildConversionAllowlist) SetCcLibraryStaticOnlyList(ccLibraryStaticOnly []string) Bp2BuildConversionAllowlist {
|
||||||
if a.ccLibraryStaticOnly == nil {
|
if a.ccLibraryStaticOnly == nil {
|
||||||
a.ccLibraryStaticOnly = map[string]bool{}
|
a.ccLibraryStaticOnly = map[string]bool{}
|
||||||
}
|
}
|
||||||
@@ -330,33 +330,15 @@ func (a bp2BuildConversionAllowlist) SetCcLibraryStaticOnlyList(ccLibraryStaticO
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
|
|
||||||
var bp2buildAllowlist OncePer
|
|
||||||
|
|
||||||
func GetBp2BuildAllowList() bp2BuildConversionAllowlist {
|
|
||||||
return bp2buildAllowlist.Once(bp2BuildAllowListKey, func() interface{} {
|
|
||||||
return NewBp2BuildAllowlist().SetDefaultConfig(allowlists.Bp2buildDefaultConfig).
|
|
||||||
SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
|
|
||||||
SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
|
|
||||||
SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
|
|
||||||
SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList).
|
|
||||||
SetCcLibraryStaticOnlyList(allowlists.Bp2buildCcLibraryStaticOnlyList)
|
|
||||||
}).(bp2BuildConversionAllowlist)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldKeepExistingBuildFileForDir returns whether an existing BUILD file should be
|
// ShouldKeepExistingBuildFileForDir returns whether an existing BUILD file should be
|
||||||
// added to the build symlink forest based on the current global configuration.
|
// added to the build symlink forest based on the current global configuration.
|
||||||
func ShouldKeepExistingBuildFileForDir(dir string) bool {
|
func (a Bp2BuildConversionAllowlist) ShouldKeepExistingBuildFileForDir(dir string) bool {
|
||||||
return shouldKeepExistingBuildFileForDir(GetBp2BuildAllowList(), dir)
|
if _, ok := a.keepExistingBuildFile[dir]; ok {
|
||||||
}
|
|
||||||
|
|
||||||
func shouldKeepExistingBuildFileForDir(allowlist bp2BuildConversionAllowlist, dir string) bool {
|
|
||||||
if _, ok := allowlist.keepExistingBuildFile[dir]; ok {
|
|
||||||
// Exact dir match
|
// Exact dir match
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Check if subtree match
|
// Check if subtree match
|
||||||
for prefix, recursive := range allowlist.keepExistingBuildFile {
|
for prefix, recursive := range a.keepExistingBuildFile {
|
||||||
if recursive {
|
if recursive {
|
||||||
if strings.HasPrefix(dir, prefix+"/") {
|
if strings.HasPrefix(dir, prefix+"/") {
|
||||||
return true
|
return true
|
||||||
@@ -367,6 +349,20 @@ func shouldKeepExistingBuildFileForDir(allowlist bp2BuildConversionAllowlist, di
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
|
||||||
|
var bp2buildAllowlist OncePer
|
||||||
|
|
||||||
|
func GetBp2BuildAllowList() Bp2BuildConversionAllowlist {
|
||||||
|
return bp2buildAllowlist.Once(bp2BuildAllowListKey, func() interface{} {
|
||||||
|
return NewBp2BuildAllowlist().SetDefaultConfig(allowlists.Bp2buildDefaultConfig).
|
||||||
|
SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
|
||||||
|
SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
|
||||||
|
SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
|
||||||
|
SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList).
|
||||||
|
SetCcLibraryStaticOnlyList(allowlists.Bp2buildCcLibraryStaticOnlyList)
|
||||||
|
}).(Bp2BuildConversionAllowlist)
|
||||||
|
}
|
||||||
|
|
||||||
// MixedBuildsEnabled returns true if a module is ready to be replaced by a
|
// MixedBuildsEnabled returns true if a module is ready to be replaced by a
|
||||||
// converted or handcrafted Bazel target. As a side effect, calling this
|
// converted or handcrafted Bazel target. As a side effect, calling this
|
||||||
// method will also log whether this module is mixed build enabled for
|
// method will also log whether this module is mixed build enabled for
|
||||||
@@ -431,7 +427,7 @@ func (b *BazelModuleBase) shouldConvertWithBp2build(ctx bazelOtherModuleContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
moduleName := module.Name()
|
moduleName := module.Name()
|
||||||
allowlist := ctx.Config().bp2buildPackageConfig
|
allowlist := ctx.Config().Bp2buildPackageConfig
|
||||||
moduleNameAllowed := allowlist.moduleAlwaysConvert[moduleName]
|
moduleNameAllowed := allowlist.moduleAlwaysConvert[moduleName]
|
||||||
moduleTypeAllowed := allowlist.moduleTypeAlwaysConvert[ctx.OtherModuleType(module)]
|
moduleTypeAllowed := allowlist.moduleTypeAlwaysConvert[ctx.OtherModuleType(module)]
|
||||||
allowlistConvert := moduleNameAllowed || moduleTypeAllowed
|
allowlistConvert := moduleNameAllowed || moduleTypeAllowed
|
||||||
@@ -447,14 +443,6 @@ func (b *BazelModuleBase) shouldConvertWithBp2build(ctx bazelOtherModuleContext,
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if allowlistConvert && shouldKeepExistingBuildFileForDir(allowlist, packagePath) {
|
|
||||||
if moduleNameAllowed {
|
|
||||||
ctx.ModuleErrorf("A module cannot be in a directory listed in keepExistingBuildFile"+
|
|
||||||
" and also be in moduleAlwaysConvert. Directory: '%s'", packagePath)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a tristate value: true, false, or unset.
|
// This is a tristate value: true, false, or unset.
|
||||||
if ok, directoryPath := bp2buildDefaultTrueRecursively(packagePath, allowlist.defaultConfig); ok {
|
if ok, directoryPath := bp2buildDefaultTrueRecursively(packagePath, allowlist.defaultConfig); ok {
|
||||||
if moduleNameAllowed {
|
if moduleNameAllowed {
|
||||||
|
@@ -158,7 +158,7 @@ func (m TestBazelModule) GenerateBuildActions(blueprint.ModuleContext) {
|
|||||||
|
|
||||||
type TestBazelConversionContext struct {
|
type TestBazelConversionContext struct {
|
||||||
omc bazel.OtherModuleTestContext
|
omc bazel.OtherModuleTestContext
|
||||||
allowlist bp2BuildConversionAllowlist
|
allowlist Bp2BuildConversionAllowlist
|
||||||
errors []string
|
errors []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ func (bcc *TestBazelConversionContext) ModuleErrorf(format string, args ...inter
|
|||||||
func (bcc *TestBazelConversionContext) Config() Config {
|
func (bcc *TestBazelConversionContext) Config() Config {
|
||||||
return Config{
|
return Config{
|
||||||
&config{
|
&config{
|
||||||
bp2buildPackageConfig: bcc.allowlist,
|
Bp2buildPackageConfig: bcc.allowlist,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
shouldConvert bool
|
shouldConvert bool
|
||||||
expectedErrors []string
|
expectedErrors []string
|
||||||
module TestBazelModule
|
module TestBazelModule
|
||||||
allowlist bp2BuildConversionAllowlist
|
allowlist Bp2BuildConversionAllowlist
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
description: "allowlist enables module",
|
description: "allowlist enables module",
|
||||||
@@ -215,7 +215,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
BazelModuleBase: bazelableBazelModuleBase,
|
BazelModuleBase: bazelableBazelModuleBase,
|
||||||
},
|
},
|
||||||
allowlist: bp2BuildConversionAllowlist{
|
allowlist: Bp2BuildConversionAllowlist{
|
||||||
moduleAlwaysConvert: map[string]bool{
|
moduleAlwaysConvert: map[string]bool{
|
||||||
"foo": true,
|
"foo": true,
|
||||||
},
|
},
|
||||||
@@ -233,7 +233,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
BazelModuleBase: bazelableBazelModuleBase,
|
BazelModuleBase: bazelableBazelModuleBase,
|
||||||
},
|
},
|
||||||
allowlist: bp2BuildConversionAllowlist{
|
allowlist: Bp2BuildConversionAllowlist{
|
||||||
moduleAlwaysConvert: map[string]bool{
|
moduleAlwaysConvert: map[string]bool{
|
||||||
"foo": true,
|
"foo": true,
|
||||||
},
|
},
|
||||||
@@ -254,7 +254,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
BazelModuleBase: bazelableBazelModuleBase,
|
BazelModuleBase: bazelableBazelModuleBase,
|
||||||
},
|
},
|
||||||
allowlist: bp2BuildConversionAllowlist{
|
allowlist: Bp2BuildConversionAllowlist{
|
||||||
moduleAlwaysConvert: map[string]bool{
|
moduleAlwaysConvert: map[string]bool{
|
||||||
"foo": true,
|
"foo": true,
|
||||||
},
|
},
|
||||||
@@ -263,27 +263,6 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
description: "module in allowlist and existing BUILD file",
|
|
||||||
shouldConvert: false,
|
|
||||||
expectedErrors: []string{"A module cannot be in a directory listed in keepExistingBuildFile and also be in moduleAlwaysConvert. Directory: 'existing/build/dir'"},
|
|
||||||
module: TestBazelModule{
|
|
||||||
TestModuleInfo: bazel.TestModuleInfo{
|
|
||||||
ModuleName: "foo",
|
|
||||||
Typ: "rule1",
|
|
||||||
Dir: "existing/build/dir",
|
|
||||||
},
|
|
||||||
BazelModuleBase: bazelableBazelModuleBase,
|
|
||||||
},
|
|
||||||
allowlist: bp2BuildConversionAllowlist{
|
|
||||||
moduleAlwaysConvert: map[string]bool{
|
|
||||||
"foo": true,
|
|
||||||
},
|
|
||||||
keepExistingBuildFile: map[string]bool{
|
|
||||||
"existing/build/dir": true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
description: "module allowlist and enabled directory",
|
description: "module allowlist and enabled directory",
|
||||||
shouldConvert: false,
|
shouldConvert: false,
|
||||||
@@ -296,7 +275,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
BazelModuleBase: bazelableBazelModuleBase,
|
BazelModuleBase: bazelableBazelModuleBase,
|
||||||
},
|
},
|
||||||
allowlist: bp2BuildConversionAllowlist{
|
allowlist: Bp2BuildConversionAllowlist{
|
||||||
moduleAlwaysConvert: map[string]bool{
|
moduleAlwaysConvert: map[string]bool{
|
||||||
"foo": true,
|
"foo": true,
|
||||||
},
|
},
|
||||||
@@ -317,7 +296,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
BazelModuleBase: bazelableBazelModuleBase,
|
BazelModuleBase: bazelableBazelModuleBase,
|
||||||
},
|
},
|
||||||
allowlist: bp2BuildConversionAllowlist{
|
allowlist: Bp2BuildConversionAllowlist{
|
||||||
moduleAlwaysConvert: map[string]bool{
|
moduleAlwaysConvert: map[string]bool{
|
||||||
"foo": true,
|
"foo": true,
|
||||||
},
|
},
|
||||||
@@ -344,7 +323,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
allowlist: bp2BuildConversionAllowlist{
|
allowlist: Bp2BuildConversionAllowlist{
|
||||||
moduleAlwaysConvert: map[string]bool{
|
moduleAlwaysConvert: map[string]bool{
|
||||||
"foo": true,
|
"foo": true,
|
||||||
},
|
},
|
||||||
|
@@ -189,7 +189,7 @@ type config struct {
|
|||||||
mockBpList string
|
mockBpList string
|
||||||
|
|
||||||
BuildMode SoongBuildMode
|
BuildMode SoongBuildMode
|
||||||
bp2buildPackageConfig bp2BuildConversionAllowlist
|
Bp2buildPackageConfig Bp2BuildConversionAllowlist
|
||||||
Bp2buildSoongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions
|
Bp2buildSoongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions
|
||||||
|
|
||||||
// If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
|
// If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
|
||||||
@@ -482,7 +482,7 @@ func NewConfig(moduleListFile string, buildMode SoongBuildMode, runGoTests bool,
|
|||||||
|
|
||||||
config.BuildMode = buildMode
|
config.BuildMode = buildMode
|
||||||
config.BazelContext, err = NewBazelContext(config)
|
config.BazelContext, err = NewBazelContext(config)
|
||||||
config.bp2buildPackageConfig = GetBp2BuildAllowList()
|
config.Bp2buildPackageConfig = GetBp2BuildAllowList()
|
||||||
|
|
||||||
return Config{config}, err
|
return Config{config}, err
|
||||||
}
|
}
|
||||||
|
@@ -213,8 +213,8 @@ func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) {
|
|||||||
ctx.finalDeps = append(ctx.finalDeps, f)
|
ctx.finalDeps = append(ctx.finalDeps, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *TestContext) RegisterBp2BuildConfig(config bp2BuildConversionAllowlist) {
|
func (ctx *TestContext) RegisterBp2BuildConfig(config Bp2BuildConversionAllowlist) {
|
||||||
ctx.config.bp2buildPackageConfig = config
|
ctx.config.Bp2buildPackageConfig = config
|
||||||
}
|
}
|
||||||
|
|
||||||
// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
|
// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
|
||||||
|
@@ -373,6 +373,15 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
|
|||||||
if generateFilegroups {
|
if generateFilegroups {
|
||||||
// Add a filegroup target that exposes all sources in the subtree of this package
|
// Add a filegroup target that exposes all sources in the subtree of this package
|
||||||
// NOTE: This also means we generate a BUILD file for every Android.bp file (as long as it has at least one module)
|
// NOTE: This also means we generate a BUILD file for every Android.bp file (as long as it has at least one module)
|
||||||
|
//
|
||||||
|
// This works because: https://bazel.build/reference/be/functions#exports_files
|
||||||
|
// "As a legacy behaviour, also files mentioned as input to a rule are exported with the
|
||||||
|
// default visibility until the flag --incompatible_no_implicit_file_export is flipped. However, this behavior
|
||||||
|
// should not be relied upon and actively migrated away from."
|
||||||
|
//
|
||||||
|
// TODO(b/198619163): We should change this to export_files(glob(["**/*"])) instead, but doing that causes these errors:
|
||||||
|
// "Error in exports_files: generated label '//external/avb:avbtool' conflicts with existing py_binary rule"
|
||||||
|
// So we need to solve all the "target ... is both a rule and a file" warnings first.
|
||||||
for dir, _ := range dirs {
|
for dir, _ := range dirs {
|
||||||
buildFileToTargets[dir] = append(buildFileToTargets[dir], BazelTarget{
|
buildFileToTargets[dir] = append(buildFileToTargets[dir], BazelTarget{
|
||||||
name: "bp2build_all_srcs",
|
name: "bp2build_all_srcs",
|
||||||
|
@@ -2,7 +2,6 @@ package bp2build
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -80,21 +79,14 @@ func CreateBazelFiles(
|
|||||||
files = append(files, newFile(bazelRulesSubDir, "soong_module.bzl", generateSoongModuleBzl(ruleShims)))
|
files = append(files, newFile(bazelRulesSubDir, "soong_module.bzl", generateSoongModuleBzl(ruleShims)))
|
||||||
}
|
}
|
||||||
|
|
||||||
files = append(files, createBuildFiles(cfg, buildToTargets, mode)...)
|
files = append(files, createBuildFiles(buildToTargets, mode)...)
|
||||||
|
|
||||||
return files
|
return files
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBuildFiles(cfg android.Config, buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
|
func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
|
||||||
files := make([]BazelFile, 0, len(buildToTargets))
|
files := make([]BazelFile, 0, len(buildToTargets))
|
||||||
warnNotWriting := cfg.IsEnvTrue("BP2BUILD_VERBOSE")
|
|
||||||
for _, dir := range android.SortedStringKeys(buildToTargets) {
|
for _, dir := range android.SortedStringKeys(buildToTargets) {
|
||||||
if mode == Bp2Build && android.ShouldKeepExistingBuildFileForDir(dir) {
|
|
||||||
if warnNotWriting {
|
|
||||||
fmt.Printf("[bp2build] Not writing generated BUILD file for dir: '%s'\n", dir)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
targets := buildToTargets[dir]
|
targets := buildToTargets[dir]
|
||||||
targets.sort()
|
targets.sort()
|
||||||
|
|
||||||
|
@@ -1,12 +1,27 @@
|
|||||||
|
// 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
|
package bp2build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"android/soong/android"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"android/soong/android"
|
||||||
"android/soong/shared"
|
"android/soong/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -58,6 +73,57 @@ func treeFromExcludePathList(paths []string) *node {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mergeBuildFiles(output string, srcBuildFile string, generatedBuildFile string, verbose bool) error {
|
||||||
|
|
||||||
|
srcBuildFileContent, err := os.ReadFile(srcBuildFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
generatedBuildFileContent, err := os.ReadFile(generatedBuildFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// There can't be a package() call in both the source and generated BUILD files.
|
||||||
|
// bp2build will generate a package() call for licensing information, but if
|
||||||
|
// there's no licensing information, it will still generate a package() call
|
||||||
|
// that just sets default_visibility=public. If the handcrafted build file
|
||||||
|
// also has a package() call, we'll allow it to override the bp2build
|
||||||
|
// generated one if it doesn't have any licensing information. If the bp2build
|
||||||
|
// one has licensing information and the handcrafted one exists, we'll leave
|
||||||
|
// them both in for bazel to throw an error.
|
||||||
|
packageRegex := regexp.MustCompile(`(?m)^package\s*\(`)
|
||||||
|
packageDefaultVisibilityRegex := regexp.MustCompile(`(?m)^package\s*\(\s*default_visibility\s*=\s*\[\s*"//visibility:public",?\s*]\s*\)`)
|
||||||
|
if packageRegex.Find(srcBuildFileContent) != nil {
|
||||||
|
if verbose && packageDefaultVisibilityRegex.Find(generatedBuildFileContent) != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Both '%s' and '%s' have a package() target, removing the first one\n",
|
||||||
|
generatedBuildFile, srcBuildFile)
|
||||||
|
}
|
||||||
|
generatedBuildFileContent = packageDefaultVisibilityRegex.ReplaceAll(generatedBuildFileContent, []byte{})
|
||||||
|
}
|
||||||
|
|
||||||
|
outFile, err := os.Create(output)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = outFile.Write(generatedBuildFileContent)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if generatedBuildFileContent[len(generatedBuildFileContent)-1] != '\n' {
|
||||||
|
_, err = outFile.WriteString("\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = outFile.Write(srcBuildFileContent)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Calls readdir() and returns it as a map from the basename of the files in dir
|
// Calls readdir() and returns it as a map from the basename of the files in dir
|
||||||
// to os.FileInfo.
|
// to os.FileInfo.
|
||||||
func readdirToMap(dir string) map[string]os.FileInfo {
|
func readdirToMap(dir string) map[string]os.FileInfo {
|
||||||
@@ -125,6 +191,17 @@ func plantSymlinkForestRecursive(cfg android.Config, topdir string, forestDir st
|
|||||||
srcDirMap := readdirToMap(shared.JoinPath(topdir, srcDir))
|
srcDirMap := readdirToMap(shared.JoinPath(topdir, srcDir))
|
||||||
buildFilesMap := readdirToMap(shared.JoinPath(topdir, buildFilesDir))
|
buildFilesMap := readdirToMap(shared.JoinPath(topdir, buildFilesDir))
|
||||||
|
|
||||||
|
renamingBuildFile := false
|
||||||
|
if _, ok := srcDirMap["BUILD"]; ok {
|
||||||
|
if _, ok := srcDirMap["BUILD.bazel"]; !ok {
|
||||||
|
if _, ok := buildFilesMap["BUILD.bazel"]; ok {
|
||||||
|
renamingBuildFile = true
|
||||||
|
srcDirMap["BUILD.bazel"] = srcDirMap["BUILD"]
|
||||||
|
delete(srcDirMap, "BUILD")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
allEntries := make(map[string]bool)
|
allEntries := make(map[string]bool)
|
||||||
for n := range srcDirMap {
|
for n := range srcDirMap {
|
||||||
allEntries[n] = true
|
allEntries[n] = true
|
||||||
@@ -148,21 +225,28 @@ func plantSymlinkForestRecursive(cfg android.Config, topdir string, forestDir st
|
|||||||
// The full paths of children in the input trees and in the output tree
|
// The full paths of children in the input trees and in the output tree
|
||||||
forestChild := shared.JoinPath(forestDir, f)
|
forestChild := shared.JoinPath(forestDir, f)
|
||||||
srcChild := shared.JoinPath(srcDir, f)
|
srcChild := shared.JoinPath(srcDir, f)
|
||||||
|
if f == "BUILD.bazel" && renamingBuildFile {
|
||||||
|
srcChild = shared.JoinPath(srcDir, "BUILD")
|
||||||
|
}
|
||||||
buildFilesChild := shared.JoinPath(buildFilesDir, f)
|
buildFilesChild := shared.JoinPath(buildFilesDir, f)
|
||||||
|
|
||||||
// Descend in the exclusion tree, if there are any excludes left
|
// Descend in the exclusion tree, if there are any excludes left
|
||||||
var excludeChild *node
|
var excludeChild *node = nil
|
||||||
if exclude == nil {
|
if exclude != nil {
|
||||||
excludeChild = nil
|
if f == "BUILD.bazel" && renamingBuildFile {
|
||||||
} else {
|
excludeChild = exclude.children["BUILD"]
|
||||||
excludeChild = exclude.children[f]
|
} else {
|
||||||
|
excludeChild = exclude.children[f]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srcChildEntry, sExists := srcDirMap[f]
|
srcChildEntry, sExists := srcDirMap[f]
|
||||||
buildFilesChildEntry, bExists := buildFilesMap[f]
|
buildFilesChildEntry, bExists := buildFilesMap[f]
|
||||||
excluded := excludeChild != nil && excludeChild.excluded
|
|
||||||
|
|
||||||
if excluded {
|
if excludeChild != nil && excludeChild.excluded {
|
||||||
|
if bExists {
|
||||||
|
symlinkIntoForest(topdir, forestChild, buildFilesChild)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,13 +282,15 @@ func plantSymlinkForestRecursive(cfg android.Config, topdir string, forestDir st
|
|||||||
// Both are directories. Descend.
|
// Both are directories. Descend.
|
||||||
plantSymlinkForestRecursive(cfg, topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
|
plantSymlinkForestRecursive(cfg, topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
|
||||||
} else if !sDir && !bDir {
|
} else if !sDir && !bDir {
|
||||||
// Neither is a directory. Prioritize BUILD files generated by bp2build
|
// Neither is a directory. Merge them.
|
||||||
// over any BUILD file imported into external/.
|
srcBuildFile := shared.JoinPath(topdir, srcChild)
|
||||||
if cfg.IsEnvTrue("BP2BUILD_VERBOSE") {
|
generatedBuildFile := shared.JoinPath(topdir, buildFilesChild)
|
||||||
fmt.Fprintf(os.Stderr, "Both '%s' and '%s' exist, symlinking the former to '%s'\n",
|
err = mergeBuildFiles(shared.JoinPath(topdir, forestChild), srcBuildFile, generatedBuildFile, cfg.IsEnvTrue("BP2BUILD_VERBOSE"))
|
||||||
buildFilesChild, srcChild, forestChild)
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error merging %s and %s: %s",
|
||||||
|
srcBuildFile, generatedBuildFile, err)
|
||||||
|
*okay = false
|
||||||
}
|
}
|
||||||
symlinkIntoForest(topdir, forestChild, buildFilesChild)
|
|
||||||
} else {
|
} else {
|
||||||
// Both exist and one is a file. This is an error.
|
// Both exist and one is a file. This is an error.
|
||||||
fmt.Fprintf(os.Stderr,
|
fmt.Fprintf(os.Stderr,
|
||||||
|
@@ -406,14 +406,10 @@ func touch(path string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find BUILD files in the srcDir which...
|
// Find BUILD files in the srcDir which are not in the allowlist
|
||||||
//
|
// (android.Bp2BuildConversionAllowlist#ShouldKeepExistingBuildFileForDir)
|
||||||
// - are not on the allow list (android/bazel.go#ShouldKeepExistingBuildFileForDir())
|
// and return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
|
||||||
//
|
func getPathsToIgnoredBuildFiles(config android.Bp2BuildConversionAllowlist, topDir string, srcDirBazelFiles []string, verbose bool) []string {
|
||||||
// - won't be overwritten by corresponding bp2build generated files
|
|
||||||
//
|
|
||||||
// And return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
|
|
||||||
func getPathsToIgnoredBuildFiles(topDir string, generatedRoot string, srcDirBazelFiles []string, verbose bool) []string {
|
|
||||||
paths := make([]string, 0)
|
paths := make([]string, 0)
|
||||||
|
|
||||||
for _, srcDirBazelFileRelativePath := range srcDirBazelFiles {
|
for _, srcDirBazelFileRelativePath := range srcDirBazelFiles {
|
||||||
@@ -428,21 +424,14 @@ func getPathsToIgnoredBuildFiles(topDir string, generatedRoot string, srcDirBaze
|
|||||||
// Don't ignore entire directories
|
// Don't ignore entire directories
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !(fileInfo.Name() == "BUILD" || fileInfo.Name() == "BUILD.bazel") {
|
if fileInfo.Name() != "BUILD" && fileInfo.Name() != "BUILD.bazel" {
|
||||||
// Don't ignore this file - it is not a build file
|
// Don't ignore this file - it is not a build file
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
srcDirBazelFileDir := filepath.Dir(srcDirBazelFileRelativePath)
|
if config.ShouldKeepExistingBuildFileForDir(filepath.Dir(srcDirBazelFileRelativePath)) {
|
||||||
if android.ShouldKeepExistingBuildFileForDir(srcDirBazelFileDir) {
|
|
||||||
// Don't ignore this existing build file
|
// Don't ignore this existing build file
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
correspondingBp2BuildFile := shared.JoinPath(topDir, generatedRoot, srcDirBazelFileRelativePath)
|
|
||||||
if _, err := os.Stat(correspondingBp2BuildFile); err == nil {
|
|
||||||
// If bp2build generated an alternate BUILD file, don't exclude this workspace path
|
|
||||||
// BUILD file clash resolution happens later in the symlink forest creation
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if verbose {
|
if verbose {
|
||||||
fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
|
fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
|
||||||
}
|
}
|
||||||
@@ -553,7 +542,7 @@ func runBp2Build(configuration android.Config, extraNinjaDeps []string) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(topDir, generatedRoot, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
|
pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(configuration.Bp2buildPackageConfig, topDir, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
|
||||||
excludes = append(excludes, pathsToIgnoredBuildFiles...)
|
excludes = append(excludes, pathsToIgnoredBuildFiles...)
|
||||||
|
|
||||||
excludes = append(excludes, getTemporaryExcludes()...)
|
excludes = append(excludes, getTemporaryExcludes()...)
|
||||||
|
Reference in New Issue
Block a user