Refactor mixed build allowlist handling
This refactoring prepares for introduction of bazel prod mode, an alternative mechanism for mixed builds allowlist handling. * Decide bazel-mode as close to soong_build main as possible * BazelContext itself decides whether a module is allowlisted * Separate bp2build and mixed build allowlist Test: m nothing, manually verified all modules are mixed build disabled (via metrics) Test: USE_BAZEL_ANALYSIS=1 m nothing, manually verified that mixed build disabled/enabled modules are identical before and after change. Change-Id: I0f55d8b85000cb4a871a099edc6d7d868d7df509
This commit is contained in:
@@ -231,16 +231,18 @@ type bp2BuildConversionAllowlist struct {
|
|||||||
// when they have the same type as one listed.
|
// when they have the same type as one listed.
|
||||||
moduleTypeAlwaysConvert map[string]bool
|
moduleTypeAlwaysConvert map[string]bool
|
||||||
|
|
||||||
// Per-module denylist to always opt modules out of both bp2build and mixed builds.
|
// Per-module denylist to always opt modules out of bp2build conversion.
|
||||||
moduleDoNotConvert map[string]bool
|
moduleDoNotConvert map[string]bool
|
||||||
|
|
||||||
// Per-module denylist of cc_library modules to only generate the static
|
// Per-module denylist of cc_library modules to only generate the static
|
||||||
// variant if their shared variant isn't ready or buildable by Bazel.
|
// variant if their shared variant isn't ready or buildable by Bazel.
|
||||||
ccLibraryStaticOnly map[string]bool
|
ccLibraryStaticOnly map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
// Per-module denylist to opt modules out of mixed builds. Such modules will
|
// GenerateCcLibraryStaticOnly returns whether a cc_library module should only
|
||||||
// still be generated via bp2build.
|
// generate a static version of itself based on the current global configuration.
|
||||||
mixedBuildsDisabled map[string]bool
|
func (a bp2BuildConversionAllowlist) GenerateCcLibraryStaticOnly(moduleName string) bool {
|
||||||
|
return a.ccLibraryStaticOnly[moduleName]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBp2BuildAllowlist creates a new, empty bp2BuildConversionAllowlist
|
// NewBp2BuildAllowlist creates a new, empty bp2BuildConversionAllowlist
|
||||||
@@ -253,7 +255,6 @@ func NewBp2BuildAllowlist() bp2BuildConversionAllowlist {
|
|||||||
map[string]bool{},
|
map[string]bool{},
|
||||||
map[string]bool{},
|
map[string]bool{},
|
||||||
map[string]bool{},
|
map[string]bool{},
|
||||||
map[string]bool{},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,43 +330,24 @@ func (a bp2BuildConversionAllowlist) SetCcLibraryStaticOnlyList(ccLibraryStaticO
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMixedBuildsDisabledList copies the entries from mixedBuildsDisabled into the allowlist
|
|
||||||
func (a bp2BuildConversionAllowlist) SetMixedBuildsDisabledList(mixedBuildsDisabled []string) bp2BuildConversionAllowlist {
|
|
||||||
if a.mixedBuildsDisabled == nil {
|
|
||||||
a.mixedBuildsDisabled = map[string]bool{}
|
|
||||||
}
|
|
||||||
for _, m := range mixedBuildsDisabled {
|
|
||||||
a.mixedBuildsDisabled[m] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
|
var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
|
||||||
var bp2buildAllowlist OncePer
|
var bp2buildAllowlist OncePer
|
||||||
|
|
||||||
func getBp2BuildAllowList() bp2BuildConversionAllowlist {
|
func GetBp2BuildAllowList() bp2BuildConversionAllowlist {
|
||||||
return bp2buildAllowlist.Once(bp2BuildAllowListKey, func() interface{} {
|
return bp2buildAllowlist.Once(bp2BuildAllowListKey, func() interface{} {
|
||||||
return NewBp2BuildAllowlist().SetDefaultConfig(allowlists.Bp2buildDefaultConfig).
|
return NewBp2BuildAllowlist().SetDefaultConfig(allowlists.Bp2buildDefaultConfig).
|
||||||
SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
|
SetKeepExistingBuildFile(allowlists.Bp2buildKeepExistingBuildFile).
|
||||||
SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
|
SetModuleAlwaysConvertList(allowlists.Bp2buildModuleAlwaysConvertList).
|
||||||
SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
|
SetModuleTypeAlwaysConvertList(allowlists.Bp2buildModuleTypeAlwaysConvertList).
|
||||||
SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList).
|
SetModuleDoNotConvertList(allowlists.Bp2buildModuleDoNotConvertList).
|
||||||
SetCcLibraryStaticOnlyList(allowlists.Bp2buildCcLibraryStaticOnlyList).
|
SetCcLibraryStaticOnlyList(allowlists.Bp2buildCcLibraryStaticOnlyList)
|
||||||
SetMixedBuildsDisabledList(allowlists.MixedBuildsDisabledList)
|
|
||||||
}).(bp2BuildConversionAllowlist)
|
}).(bp2BuildConversionAllowlist)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateCcLibraryStaticOnly returns whether a cc_library module should only
|
|
||||||
// generate a static version of itself based on the current global configuration.
|
|
||||||
func GenerateCcLibraryStaticOnly(moduleName string) bool {
|
|
||||||
return getBp2BuildAllowList().ccLibraryStaticOnly[moduleName]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 ShouldKeepExistingBuildFileForDir(dir string) bool {
|
||||||
return shouldKeepExistingBuildFileForDir(getBp2BuildAllowList(), dir)
|
return shouldKeepExistingBuildFileForDir(GetBp2BuildAllowList(), dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldKeepExistingBuildFileForDir(allowlist bp2BuildConversionAllowlist, dir string) bool {
|
func shouldKeepExistingBuildFileForDir(allowlist bp2BuildConversionAllowlist, dir string) bool {
|
||||||
@@ -405,20 +387,10 @@ func mixedBuildPossible(ctx BaseModuleContext) bool {
|
|||||||
if !ctx.Module().Enabled() {
|
if !ctx.Module().Enabled() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !ctx.Config().BazelContext.BazelEnabled() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !convertedToBazel(ctx, ctx.Module()) {
|
if !convertedToBazel(ctx, ctx.Module()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return ctx.Config().BazelContext.BazelAllowlisted(ctx.Module().Name())
|
||||||
if GenerateCcLibraryStaticOnly(ctx.Module().Name()) {
|
|
||||||
// Don't use partially-converted cc_library targets in mixed builds,
|
|
||||||
// since mixed builds would generally rely on both static and shared
|
|
||||||
// variants of a cc_library.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return !getBp2BuildAllowList().mixedBuildsDisabled[ctx.Module().Name()]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertedToBazel returns whether this module has been converted (with bp2build or manually) to Bazel.
|
// ConvertedToBazel returns whether this module has been converted (with bp2build or manually) to Bazel.
|
||||||
|
@@ -27,6 +27,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"android/soong/android/allowlists"
|
||||||
"android/soong/bazel/cquery"
|
"android/soong/bazel/cquery"
|
||||||
"android/soong/shared"
|
"android/soong/shared"
|
||||||
|
|
||||||
@@ -142,8 +143,11 @@ type BazelContext interface {
|
|||||||
// queued in the BazelContext.
|
// queued in the BazelContext.
|
||||||
InvokeBazel(config Config) error
|
InvokeBazel(config Config) error
|
||||||
|
|
||||||
// Returns true if bazel is enabled for the given configuration.
|
// Returns true if Bazel handling is enabled for the module with the given name.
|
||||||
BazelEnabled() bool
|
// Note that this only implies "bazel mixed build" allowlisting. The caller
|
||||||
|
// should independently verify the module is eligible for Bazel handling
|
||||||
|
// (for example, that it is MixedBuildBuildable).
|
||||||
|
BazelAllowlisted(moduleName string) bool
|
||||||
|
|
||||||
// Returns the bazel output base (the root directory for all bazel intermediate outputs).
|
// Returns the bazel output base (the root directory for all bazel intermediate outputs).
|
||||||
OutputBase() string
|
OutputBase() string
|
||||||
@@ -183,6 +187,17 @@ type bazelContext struct {
|
|||||||
|
|
||||||
// Depsets which should be used for Bazel's build statements.
|
// Depsets which should be used for Bazel's build statements.
|
||||||
depsets []bazel.AqueryDepset
|
depsets []bazel.AqueryDepset
|
||||||
|
|
||||||
|
// Per-module allowlist/denylist functionality to control whether analysis of
|
||||||
|
// modules are handled by Bazel. For modules which do not have a Bazel definition
|
||||||
|
// (or do not sufficiently support bazel handling via MixedBuildBuildable),
|
||||||
|
// this allowlist will have no effect, even if the module is explicitly allowlisted here.
|
||||||
|
// Per-module denylist to opt modules out of bazel handling.
|
||||||
|
bazelDisabledModules map[string]bool
|
||||||
|
// Per-module allowlist to opt modules in to bazel handling.
|
||||||
|
bazelEnabledModules map[string]bool
|
||||||
|
// If true, modules are bazel-enabled by default, unless present in bazelDisabledModules.
|
||||||
|
modulesDefaultToBazel bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ BazelContext = &bazelContext{}
|
var _ BazelContext = &bazelContext{}
|
||||||
@@ -229,7 +244,7 @@ func (m MockBazelContext) InvokeBazel(_ Config) error {
|
|||||||
panic("unimplemented")
|
panic("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m MockBazelContext) BazelEnabled() bool {
|
func (m MockBazelContext) BazelAllowlisted(moduleName string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +330,7 @@ func (m noopBazelContext) OutputBase() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n noopBazelContext) BazelEnabled() bool {
|
func (n noopBazelContext) BazelAllowlisted(moduleName string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,9 +343,7 @@ func (m noopBazelContext) AqueryDepsets() []bazel.AqueryDepset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewBazelContext(c *config) (BazelContext, error) {
|
func NewBazelContext(c *config) (BazelContext, error) {
|
||||||
// TODO(cparsons): Assess USE_BAZEL=1 instead once "mixed Soong/Bazel builds"
|
if !c.IsMixedBuildsEnabled() {
|
||||||
// are production ready.
|
|
||||||
if !c.IsEnvTrue("USE_BAZEL_ANALYSIS") {
|
|
||||||
return noopBazelContext{}, nil
|
return noopBazelContext{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,10 +351,26 @@ func NewBazelContext(c *config) (BazelContext, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(cparsons): Use a different allowlist depending on prod vs. dev
|
||||||
|
// bazel mode.
|
||||||
|
disabledModules := map[string]bool{}
|
||||||
|
// Don't use partially-converted cc_library targets in mixed builds,
|
||||||
|
// since mixed builds would generally rely on both static and shared
|
||||||
|
// variants of a cc_library.
|
||||||
|
for staticOnlyModule, _ := range GetBp2BuildAllowList().ccLibraryStaticOnly {
|
||||||
|
disabledModules[staticOnlyModule] = true
|
||||||
|
}
|
||||||
|
for _, disabledDevModule := range allowlists.MixedBuildsDisabledList {
|
||||||
|
disabledModules[disabledDevModule] = true
|
||||||
|
}
|
||||||
|
|
||||||
return &bazelContext{
|
return &bazelContext{
|
||||||
bazelRunner: &builtinBazelRunner{},
|
bazelRunner: &builtinBazelRunner{},
|
||||||
paths: p,
|
paths: p,
|
||||||
requests: make(map[cqueryKey]bool),
|
requests: make(map[cqueryKey]bool),
|
||||||
|
modulesDefaultToBazel: true,
|
||||||
|
bazelDisabledModules: disabledModules,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,8 +415,14 @@ func (p *bazelPaths) BazelMetricsDir() string {
|
|||||||
return p.metricsDir
|
return p.metricsDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *bazelContext) BazelEnabled() bool {
|
func (context *bazelContext) BazelAllowlisted(moduleName string) bool {
|
||||||
|
if context.bazelDisabledModules[moduleName] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if context.bazelEnabledModules[moduleName] {
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
|
return context.modulesDefaultToBazel
|
||||||
}
|
}
|
||||||
|
|
||||||
func pwdPrefix() string {
|
func pwdPrefix() string {
|
||||||
@@ -851,7 +886,7 @@ type bazelSingleton struct{}
|
|||||||
|
|
||||||
func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
|
func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
|
||||||
// bazelSingleton is a no-op if mixed-soong-bazel-builds are disabled.
|
// bazelSingleton is a no-op if mixed-soong-bazel-builds are disabled.
|
||||||
if !ctx.Config().BazelContext.BazelEnabled() {
|
if !ctx.Config().IsMixedBuildsEnabled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -389,7 +389,7 @@ func TestBp2BuildAllowlist(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBp2buildAllowList(t *testing.T) {
|
func TestBp2buildAllowList(t *testing.T) {
|
||||||
allowlist := getBp2BuildAllowList()
|
allowlist := GetBp2BuildAllowList()
|
||||||
for k, v := range allowlists.Bp2buildDefaultConfig {
|
for k, v := range allowlists.Bp2buildDefaultConfig {
|
||||||
if allowlist.defaultConfig[k] != v {
|
if allowlist.defaultConfig[k] != v {
|
||||||
t.Errorf("bp2build default config of %s: expected: %v, got: %v", k, v, allowlist.defaultConfig[k])
|
t.Errorf("bp2build default config of %s: expected: %v, got: %v", k, v, allowlist.defaultConfig[k])
|
||||||
@@ -415,9 +415,4 @@ func TestBp2buildAllowList(t *testing.T) {
|
|||||||
t.Errorf("bp2build cc library static only of %s: expected: true, got: %v", k, allowlist.ccLibraryStaticOnly[k])
|
t.Errorf("bp2build cc library static only of %s: expected: true, got: %v", k, allowlist.ccLibraryStaticOnly[k])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, k := range allowlists.MixedBuildsDisabledList {
|
|
||||||
if !allowlist.mixedBuildsDisabled[k] {
|
|
||||||
t.Errorf("bp2build mix build disabled of %s: expected: true, got: %v", k, allowlist.mixedBuildsDisabled[k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -68,6 +68,38 @@ type Config struct {
|
|||||||
*config
|
*config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SoongBuildMode int
|
||||||
|
|
||||||
|
// Build modes that soong_build can run as.
|
||||||
|
const (
|
||||||
|
// Don't use bazel at all during module analysis.
|
||||||
|
AnalysisNoBazel SoongBuildMode = iota
|
||||||
|
|
||||||
|
// Bp2build mode: Generate BUILD files from blueprint files and exit.
|
||||||
|
Bp2build
|
||||||
|
|
||||||
|
// Generate BUILD files which faithfully represent the dependency graph of
|
||||||
|
// blueprint modules. Individual BUILD targets will not, however, faitfhully
|
||||||
|
// express build semantics.
|
||||||
|
GenerateQueryView
|
||||||
|
|
||||||
|
// Create a JSON representation of the module graph and exit.
|
||||||
|
GenerateModuleGraph
|
||||||
|
|
||||||
|
// Generate a documentation file for module type definitions and exit.
|
||||||
|
GenerateDocFile
|
||||||
|
|
||||||
|
// Use bazel during analysis of many allowlisted build modules. The allowlist
|
||||||
|
// is considered a "developer mode" allowlist, as some modules may be
|
||||||
|
// allowlisted on an experimental basis.
|
||||||
|
BazelDevMode
|
||||||
|
|
||||||
|
// Use bazel during analysis of build modules from an allowlist carefully
|
||||||
|
// curated by the build team to be proven stable.
|
||||||
|
// TODO(cparsons): Implement this mode.
|
||||||
|
BazelProdMode
|
||||||
|
)
|
||||||
|
|
||||||
// SoongOutDir returns the build output directory for the configuration.
|
// SoongOutDir returns the build output directory for the configuration.
|
||||||
func (c Config) SoongOutDir() string {
|
func (c Config) SoongOutDir() string {
|
||||||
return c.soongOutDir
|
return c.soongOutDir
|
||||||
@@ -157,7 +189,7 @@ type config struct {
|
|||||||
fs pathtools.FileSystem
|
fs pathtools.FileSystem
|
||||||
mockBpList string
|
mockBpList string
|
||||||
|
|
||||||
runningAsBp2Build bool
|
BuildMode SoongBuildMode
|
||||||
bp2buildPackageConfig bp2BuildConversionAllowlist
|
bp2buildPackageConfig bp2BuildConversionAllowlist
|
||||||
Bp2buildSoongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions
|
Bp2buildSoongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions
|
||||||
|
|
||||||
@@ -171,6 +203,12 @@ type config struct {
|
|||||||
|
|
||||||
OncePer
|
OncePer
|
||||||
|
|
||||||
|
// These fields are only used for metrics collection. A module should be added
|
||||||
|
// to these maps only if its implementation supports Bazel handling in mixed
|
||||||
|
// builds. A module being in the "enabled" list indicates that there is a
|
||||||
|
// variant of that module for which bazel-handling actually took place.
|
||||||
|
// A module being in the "disabled" list indicates that there is a variant of
|
||||||
|
// that module for which bazel-handling was denied.
|
||||||
mixedBuildsLock sync.Mutex
|
mixedBuildsLock sync.Mutex
|
||||||
mixedBuildEnabledModules map[string]struct{}
|
mixedBuildEnabledModules map[string]struct{}
|
||||||
mixedBuildDisabledModules map[string]struct{}
|
mixedBuildDisabledModules map[string]struct{}
|
||||||
@@ -346,7 +384,7 @@ func NullConfig(outDir, soongOutDir string) Config {
|
|||||||
|
|
||||||
// NewConfig creates a new Config object. The srcDir argument specifies the path
|
// NewConfig creates a new Config object. The srcDir argument specifies the path
|
||||||
// to the root source directory. It also loads the config file, if found.
|
// to the root source directory. It also loads the config file, if found.
|
||||||
func NewConfig(moduleListFile string, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string) (Config, error) {
|
func NewConfig(moduleListFile string, buildMode SoongBuildMode, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string) (Config, error) {
|
||||||
// Make a config with default options.
|
// Make a config with default options.
|
||||||
config := &config{
|
config := &config{
|
||||||
ProductVariablesFileName: filepath.Join(soongOutDir, productVariablesFileName),
|
ProductVariablesFileName: filepath.Join(soongOutDir, productVariablesFileName),
|
||||||
@@ -443,8 +481,17 @@ func NewConfig(moduleListFile string, runGoTests bool, outDir, soongOutDir strin
|
|||||||
config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
|
config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checking USE_BAZEL_ANALYSIS must be done here instead of in the caller, so
|
||||||
|
// that we can invoke IsEnvTrue (which also registers the env var as a
|
||||||
|
// dependency of the build).
|
||||||
|
// TODO(cparsons): Remove this hack once USE_BAZEL_ANALYSIS is removed.
|
||||||
|
if buildMode == AnalysisNoBazel && config.IsEnvTrue("USE_BAZEL_ANALYSIS") {
|
||||||
|
buildMode = BazelDevMode
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
@@ -479,6 +526,12 @@ func (c *config) mockFileSystem(bp string, fs map[string][]byte) {
|
|||||||
c.mockBpList = blueprint.MockModuleListFile
|
c.mockBpList = blueprint.MockModuleListFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if "Bazel builds" is enabled. In this mode, part of build
|
||||||
|
// analysis is handled by Bazel.
|
||||||
|
func (c *config) IsMixedBuildsEnabled() bool {
|
||||||
|
return c.BuildMode == BazelProdMode || c.BuildMode == BazelDevMode
|
||||||
|
}
|
||||||
|
|
||||||
func (c *config) SetAllowMissingDependencies() {
|
func (c *config) SetAllowMissingDependencies() {
|
||||||
c.productVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
|
c.productVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
|
||||||
}
|
}
|
||||||
|
@@ -448,7 +448,7 @@ func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContex
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, defaults := range defaultsList {
|
for _, defaults := range defaultsList {
|
||||||
if ctx.Config().runningAsBp2Build {
|
if ctx.Config().BuildMode == Bp2build {
|
||||||
applyNamespacedVariableDefaults(defaults, ctx)
|
applyNamespacedVariableDefaults(defaults, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2367,9 +2367,6 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModuleBase) isHandledByBazel(ctx ModuleContext) (MixedBuildBuildable, bool) {
|
func (m *ModuleBase) isHandledByBazel(ctx ModuleContext) (MixedBuildBuildable, bool) {
|
||||||
if !ctx.Config().BazelContext.BazelEnabled() {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
if mixedBuildMod, ok := m.module.(MixedBuildBuildable); ok {
|
if mixedBuildMod, ok := m.module.(MixedBuildBuildable); ok {
|
||||||
if mixedBuildMod.IsMixedBuildSupported(ctx) && MixedBuildsEnabled(ctx) {
|
if mixedBuildMod.IsMixedBuildSupported(ctx) && MixedBuildsEnabled(ctx) {
|
||||||
return mixedBuildMod, true
|
return mixedBuildMod, true
|
||||||
|
@@ -164,10 +164,6 @@ func NewContext(config Config) *Context {
|
|||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) SetRunningAsBp2build() {
|
|
||||||
ctx.config.runningAsBp2Build = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterForBazelConversion registers an alternate shadow pipeline of
|
// RegisterForBazelConversion registers an alternate shadow pipeline of
|
||||||
// singletons, module types and mutators to register for converting Blueprint
|
// singletons, module types and mutators to register for converting Blueprint
|
||||||
// files to semantically equivalent BUILD files.
|
// files to semantically equivalent BUILD files.
|
||||||
|
@@ -382,7 +382,7 @@ func loadSoongConfigModuleTypeDefinition(ctx LoadHookContext, from string) map[s
|
|||||||
defer r.Close()
|
defer r.Close()
|
||||||
|
|
||||||
mtDef, errs := soongconfig.Parse(r, from)
|
mtDef, errs := soongconfig.Parse(r, from)
|
||||||
if ctx.Config().runningAsBp2Build {
|
if ctx.Config().BuildMode == Bp2build {
|
||||||
ctx.Config().Bp2buildSoongConfigDefinitions.AddVars(*mtDef)
|
ctx.Config().Bp2buildSoongConfigDefinitions.AddVars(*mtDef)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@ func loadSoongConfigModuleTypeDefinition(ctx LoadHookContext, from string) map[s
|
|||||||
for name, moduleType := range mtDef.ModuleTypes {
|
for name, moduleType := range mtDef.ModuleTypes {
|
||||||
factory := globalModuleTypes[moduleType.BaseModuleType]
|
factory := globalModuleTypes[moduleType.BaseModuleType]
|
||||||
if factory != nil {
|
if factory != nil {
|
||||||
factories[name] = configModuleFactory(factory, moduleType, ctx.Config().runningAsBp2Build)
|
factories[name] = configModuleFactory(factory, moduleType, ctx.Config().BuildMode == Bp2build)
|
||||||
} else {
|
} else {
|
||||||
reportErrors(ctx, from,
|
reportErrors(ctx, from,
|
||||||
fmt.Errorf("missing global module type factory for %q", moduleType.BaseModuleType))
|
fmt.Errorf("missing global module type factory for %q", moduleType.BaseModuleType))
|
||||||
|
@@ -457,7 +457,7 @@ func (ctx *TestContext) Register() {
|
|||||||
|
|
||||||
// RegisterForBazelConversion prepares a test context for bp2build conversion.
|
// RegisterForBazelConversion prepares a test context for bp2build conversion.
|
||||||
func (ctx *TestContext) RegisterForBazelConversion() {
|
func (ctx *TestContext) RegisterForBazelConversion() {
|
||||||
ctx.SetRunningAsBp2build()
|
ctx.config.BuildMode = Bp2build
|
||||||
RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch)
|
RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -983,7 +983,7 @@ func bp2BuildParseExportedIncludes(ctx android.BazelConversionPathContext, modul
|
|||||||
|
|
||||||
func bazelLabelForStaticModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
|
func bazelLabelForStaticModule(ctx android.BazelConversionPathContext, m blueprint.Module) string {
|
||||||
label := android.BazelModuleLabel(ctx, m)
|
label := android.BazelModuleLabel(ctx, m)
|
||||||
if ccModule, ok := m.(*Module); ok && ccModule.typ() == fullLibrary && !android.GenerateCcLibraryStaticOnly(m.Name()) {
|
if ccModule, ok := m.(*Module); ok && ccModule.typ() == fullLibrary && !android.GetBp2BuildAllowList().GenerateCcLibraryStaticOnly(m.Name()) {
|
||||||
label += "_bp2build_cc_library_static"
|
label += "_bp2build_cc_library_static"
|
||||||
}
|
}
|
||||||
return label
|
return label
|
||||||
|
@@ -282,7 +282,7 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) {
|
|||||||
// For some cc_library modules, their static variants are ready to be
|
// For some cc_library modules, their static variants are ready to be
|
||||||
// converted, but not their shared variants. For these modules, delegate to
|
// converted, but not their shared variants. For these modules, delegate to
|
||||||
// the cc_library_static bp2build converter temporarily instead.
|
// the cc_library_static bp2build converter temporarily instead.
|
||||||
if android.GenerateCcLibraryStaticOnly(ctx.Module().Name()) {
|
if android.GetBp2BuildAllowList().GenerateCcLibraryStaticOnly(ctx.Module().Name()) {
|
||||||
sharedOrStaticLibraryBp2Build(ctx, m, true)
|
sharedOrStaticLibraryBp2Build(ctx, m, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -121,7 +121,21 @@ func newContext(configuration android.Config) *android.Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newConfig(availableEnv map[string]string) android.Config {
|
func newConfig(availableEnv map[string]string) android.Config {
|
||||||
configuration, err := android.NewConfig(cmdlineArgs.ModuleListFile, runGoTests, outDir, soongOutDir, availableEnv)
|
var buildMode android.SoongBuildMode
|
||||||
|
|
||||||
|
if bp2buildMarker != "" {
|
||||||
|
buildMode = android.Bp2build
|
||||||
|
} else if bazelQueryViewDir != "" {
|
||||||
|
buildMode = android.GenerateQueryView
|
||||||
|
} else if moduleGraphFile != "" {
|
||||||
|
buildMode = android.GenerateModuleGraph
|
||||||
|
} else if docFile != "" {
|
||||||
|
buildMode = android.GenerateDocFile
|
||||||
|
} else {
|
||||||
|
buildMode = android.AnalysisNoBazel
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration, err := android.NewConfig(cmdlineArgs.ModuleListFile, buildMode, runGoTests, outDir, soongOutDir, availableEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%s", err)
|
fmt.Fprintf(os.Stderr, "%s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -221,52 +235,40 @@ func writeDepFile(outputFile string, eventHandler metrics.EventHandler, ninjaDep
|
|||||||
// or the actual Soong build for the build.ninja file. Returns the top level
|
// or the actual Soong build for the build.ninja file. Returns the top level
|
||||||
// output file of the specific activity.
|
// output file of the specific activity.
|
||||||
func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string, logDir string) string {
|
func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string, logDir string) string {
|
||||||
mixedModeBuild := configuration.BazelContext.BazelEnabled()
|
if configuration.BuildMode == android.Bp2build {
|
||||||
generateBazelWorkspace := bp2buildMarker != ""
|
|
||||||
generateQueryView := bazelQueryViewDir != ""
|
|
||||||
generateModuleGraphFile := moduleGraphFile != ""
|
|
||||||
generateDocFile := docFile != ""
|
|
||||||
|
|
||||||
if generateBazelWorkspace {
|
|
||||||
// Run the alternate pipeline of bp2build mutators and singleton to convert
|
// Run the alternate pipeline of bp2build mutators and singleton to convert
|
||||||
// Blueprint to BUILD files before everything else.
|
// Blueprint to BUILD files before everything else.
|
||||||
runBp2Build(configuration, extraNinjaDeps)
|
runBp2Build(configuration, extraNinjaDeps)
|
||||||
return bp2buildMarker
|
return bp2buildMarker
|
||||||
}
|
} else if configuration.IsMixedBuildsEnabled() {
|
||||||
|
|
||||||
blueprintArgs := cmdlineArgs
|
|
||||||
|
|
||||||
if mixedModeBuild {
|
|
||||||
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
|
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
|
||||||
} else {
|
} else {
|
||||||
var stopBefore bootstrap.StopBefore
|
var stopBefore bootstrap.StopBefore
|
||||||
if generateModuleGraphFile {
|
if configuration.BuildMode == android.GenerateModuleGraph {
|
||||||
stopBefore = bootstrap.StopBeforeWriteNinja
|
stopBefore = bootstrap.StopBeforeWriteNinja
|
||||||
} else if generateQueryView {
|
} else if configuration.BuildMode == android.GenerateQueryView || configuration.BuildMode == android.GenerateDocFile {
|
||||||
stopBefore = bootstrap.StopBeforePrepareBuildActions
|
|
||||||
} else if generateDocFile {
|
|
||||||
stopBefore = bootstrap.StopBeforePrepareBuildActions
|
stopBefore = bootstrap.StopBeforePrepareBuildActions
|
||||||
} else {
|
} else {
|
||||||
stopBefore = bootstrap.DoEverything
|
stopBefore = bootstrap.DoEverything
|
||||||
}
|
}
|
||||||
|
|
||||||
ninjaDeps := bootstrap.RunBlueprint(blueprintArgs, stopBefore, ctx.Context, configuration)
|
ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs, stopBefore, ctx.Context, configuration)
|
||||||
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
|
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
|
||||||
|
|
||||||
globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
|
globListFiles := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
|
||||||
ninjaDeps = append(ninjaDeps, globListFiles...)
|
ninjaDeps = append(ninjaDeps, globListFiles...)
|
||||||
|
|
||||||
// Convert the Soong module graph into Bazel BUILD files.
|
// Convert the Soong module graph into Bazel BUILD files.
|
||||||
if generateQueryView {
|
if configuration.BuildMode == android.GenerateQueryView {
|
||||||
queryviewMarkerFile := bazelQueryViewDir + ".marker"
|
queryviewMarkerFile := bazelQueryViewDir + ".marker"
|
||||||
runQueryView(bazelQueryViewDir, queryviewMarkerFile, configuration, ctx)
|
runQueryView(bazelQueryViewDir, queryviewMarkerFile, configuration, ctx)
|
||||||
writeDepFile(queryviewMarkerFile, *ctx.EventHandler, ninjaDeps)
|
writeDepFile(queryviewMarkerFile, *ctx.EventHandler, ninjaDeps)
|
||||||
return queryviewMarkerFile
|
return queryviewMarkerFile
|
||||||
} else if generateModuleGraphFile {
|
} else if configuration.BuildMode == android.GenerateModuleGraph {
|
||||||
writeJsonModuleGraphAndActions(ctx, moduleGraphFile, moduleActionsFile)
|
writeJsonModuleGraphAndActions(ctx, moduleGraphFile, moduleActionsFile)
|
||||||
writeDepFile(moduleGraphFile, *ctx.EventHandler, ninjaDeps)
|
writeDepFile(moduleGraphFile, *ctx.EventHandler, ninjaDeps)
|
||||||
return moduleGraphFile
|
return moduleGraphFile
|
||||||
} else if generateDocFile {
|
} else if configuration.BuildMode == android.GenerateDocFile {
|
||||||
// TODO: we could make writeDocs() return the list of documentation files
|
// TODO: we could make writeDocs() return the list of documentation files
|
||||||
// written and add them to the .d file. Then soong_docs would be re-run
|
// written and add them to the .d file. Then soong_docs would be re-run
|
||||||
// whenever one is deleted.
|
// whenever one is deleted.
|
||||||
@@ -491,11 +493,6 @@ func runBp2Build(configuration android.Config, extraNinjaDeps []string) {
|
|||||||
// conversion for Bazel conversion.
|
// conversion for Bazel conversion.
|
||||||
bp2buildCtx := android.NewContext(configuration)
|
bp2buildCtx := android.NewContext(configuration)
|
||||||
|
|
||||||
// Soong internals like LoadHooks behave differently when running as
|
|
||||||
// bp2build. This is the bit to differentiate between Soong-as-Soong and
|
|
||||||
// Soong-as-bp2build.
|
|
||||||
bp2buildCtx.SetRunningAsBp2build()
|
|
||||||
|
|
||||||
// Propagate "allow misssing dependencies" bit. This is normally set in
|
// Propagate "allow misssing dependencies" bit. This is normally set in
|
||||||
// newContext(), but we create bp2buildCtx without calling that method.
|
// newContext(), but we create bp2buildCtx without calling that method.
|
||||||
bp2buildCtx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
|
bp2buildCtx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
|
||||||
|
Reference in New Issue
Block a user