Merge "Handle missing dependencies in mixed builds"
This commit is contained in:
@@ -46,6 +46,10 @@ const (
|
|||||||
// that is not a platform incompatibility. Example: the module-type is not
|
// that is not a platform incompatibility. Example: the module-type is not
|
||||||
// enabled, or is not bp2build-converted.
|
// enabled, or is not bp2build-converted.
|
||||||
ModuleIncompatibility
|
ModuleIncompatibility
|
||||||
|
|
||||||
|
// Missing dependencies. We can't query Bazel for modules if it has missing dependencies, there
|
||||||
|
// will be failures.
|
||||||
|
ModuleMissingDeps
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileGroupAsLibrary describes a filegroup module that is converted to some library
|
// FileGroupAsLibrary describes a filegroup module that is converted to some library
|
||||||
@@ -367,16 +371,26 @@ func GetBp2BuildAllowList() Bp2BuildConversionAllowlist {
|
|||||||
// As a side effect, calling this method will also log whether this module is
|
// As a side effect, calling this method will also log whether this module is
|
||||||
// mixed build enabled for metrics reporting.
|
// mixed build enabled for metrics reporting.
|
||||||
func MixedBuildsEnabled(ctx BaseModuleContext) MixedBuildEnabledStatus {
|
func MixedBuildsEnabled(ctx BaseModuleContext) MixedBuildEnabledStatus {
|
||||||
module := ctx.Module()
|
|
||||||
apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo)
|
|
||||||
withinApex := !apexInfo.IsForPlatform()
|
|
||||||
|
|
||||||
platformIncompatible := isPlatformIncompatible(ctx.Os(), ctx.Arch().ArchType)
|
platformIncompatible := isPlatformIncompatible(ctx.Os(), ctx.Arch().ArchType)
|
||||||
if platformIncompatible {
|
if platformIncompatible {
|
||||||
ctx.Config().LogMixedBuild(ctx, false)
|
ctx.Config().LogMixedBuild(ctx, false)
|
||||||
return TechnicalIncompatibility
|
return TechnicalIncompatibility
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.Config().AllowMissingDependencies() {
|
||||||
|
missingDeps := ctx.getMissingDependencies()
|
||||||
|
// If there are missing dependencies, querying Bazel will fail. Soong instead fails at execution
|
||||||
|
// time, not loading/analysis. disable mixed builds and fall back to Soong to maintain that
|
||||||
|
// behavior.
|
||||||
|
if len(missingDeps) > 0 {
|
||||||
|
ctx.Config().LogMixedBuild(ctx, false)
|
||||||
|
return ModuleMissingDeps
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module := ctx.Module()
|
||||||
|
apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo)
|
||||||
|
withinApex := !apexInfo.IsForPlatform()
|
||||||
mixedBuildEnabled := ctx.Config().IsMixedBuildsEnabled() &&
|
mixedBuildEnabled := ctx.Config().IsMixedBuildsEnabled() &&
|
||||||
module.Enabled() &&
|
module.Enabled() &&
|
||||||
convertedToBazel(ctx, module) &&
|
convertedToBazel(ctx, module) &&
|
||||||
|
@@ -74,14 +74,12 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func registerMixedBuildsMutator(ctx RegisterMutatorsContext) {
|
||||||
RegisterMixedBuildsMutator(InitRegistrationContext)
|
ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterMixedBuildsMutator(ctx RegistrationContext) {
|
func RegisterMixedBuildsMutator(ctx RegistrationContext) {
|
||||||
ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
|
ctx.FinalDepsMutators(registerMixedBuildsMutator)
|
||||||
ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mixedBuildsPrepareMutator(ctx BottomUpMutatorContext) {
|
func mixedBuildsPrepareMutator(ctx BottomUpMutatorContext) {
|
||||||
|
@@ -436,3 +436,150 @@ func TestShouldKeepExistingBuildFileForDir(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mixedBuildModule struct {
|
||||||
|
ModuleBase
|
||||||
|
BazelModuleBase
|
||||||
|
props struct {
|
||||||
|
Deps []string
|
||||||
|
Mixed_build_incompatible *bool
|
||||||
|
QueuedBazelCall bool `blueprint:"mutated"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mixedBuildModuleInfo struct {
|
||||||
|
QueuedBazelCall bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var mixedBuildModuleProvider = blueprint.NewProvider(mixedBuildModuleInfo{})
|
||||||
|
|
||||||
|
func mixedBuildModuleFactory() Module {
|
||||||
|
m := &mixedBuildModule{}
|
||||||
|
m.AddProperties(&m.props)
|
||||||
|
InitAndroidArchModule(m, HostAndDeviceDefault, MultilibBoth)
|
||||||
|
InitBazelModule(m)
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mixedBuildModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mixedBuildModule) DepsMutator(ctx BottomUpMutatorContext) {
|
||||||
|
ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mixedBuildModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mixedBuildModule) IsMixedBuildSupported(ctx BaseModuleContext) bool {
|
||||||
|
return !proptools.Bool(m.props.Mixed_build_incompatible)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mixedBuildModule) QueueBazelCall(ctx BaseModuleContext) {
|
||||||
|
m.props.QueuedBazelCall = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mixedBuildModule) ProcessBazelQueryResponse(ctx ModuleContext) {
|
||||||
|
ctx.SetProvider(mixedBuildModuleProvider, mixedBuildModuleInfo{
|
||||||
|
QueuedBazelCall: m.props.QueuedBazelCall,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var prepareForMixedBuildTests = FixtureRegisterWithContext(func(ctx RegistrationContext) {
|
||||||
|
ctx.RegisterModuleType("deps", mixedBuildModuleFactory)
|
||||||
|
RegisterMixedBuildsMutator(ctx)
|
||||||
|
})
|
||||||
|
|
||||||
|
func TestMixedBuildsEnabledForType(t *testing.T) {
|
||||||
|
baseBp := `
|
||||||
|
deps {
|
||||||
|
name: "foo",
|
||||||
|
deps: ["bar"],
|
||||||
|
target: { windows: { enabled: true } },
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
`
|
||||||
|
depBp := `
|
||||||
|
deps {
|
||||||
|
name: "bar",
|
||||||
|
target: {
|
||||||
|
windows: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`
|
||||||
|
testCases := []struct {
|
||||||
|
desc string
|
||||||
|
variant *string
|
||||||
|
missingDeps bool
|
||||||
|
extraBpInfo string
|
||||||
|
mixedBuildsEnabled bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
desc: "mixed builds works",
|
||||||
|
mixedBuildsEnabled: true,
|
||||||
|
extraBpInfo: `bazel_module: { bp2build_available: true },`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "missing deps",
|
||||||
|
missingDeps: true,
|
||||||
|
mixedBuildsEnabled: false,
|
||||||
|
extraBpInfo: `bazel_module: { bp2build_available: true },`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "windows no mixed builds",
|
||||||
|
mixedBuildsEnabled: false,
|
||||||
|
variant: proptools.StringPtr("windows_x86"),
|
||||||
|
extraBpInfo: `bazel_module: { bp2build_available: true },`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "mixed builds disabled by type",
|
||||||
|
mixedBuildsEnabled: false,
|
||||||
|
extraBpInfo: `mixed_build_incompatible: true,
|
||||||
|
bazel_module: { bp2build_available: true },`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "mixed builds not bp2build available",
|
||||||
|
mixedBuildsEnabled: false,
|
||||||
|
extraBpInfo: `bazel_module: { bp2build_available: false },`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
|
handlers := GroupFixturePreparers(
|
||||||
|
prepareForMixedBuildTests,
|
||||||
|
PrepareForTestWithArchMutator,
|
||||||
|
FixtureModifyConfig(func(config Config) {
|
||||||
|
config.BazelContext = MockBazelContext{
|
||||||
|
OutputBaseDir: "base",
|
||||||
|
}
|
||||||
|
config.Targets[Windows] = []Target{
|
||||||
|
{Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", true},
|
||||||
|
{Windows, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", true},
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
bp := fmt.Sprintf(baseBp, tc.extraBpInfo)
|
||||||
|
if tc.missingDeps {
|
||||||
|
handlers = GroupFixturePreparers(
|
||||||
|
handlers,
|
||||||
|
PrepareForTestWithAllowMissingDependencies,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
bp += depBp
|
||||||
|
}
|
||||||
|
result := handlers.RunTestWithBp(t, bp)
|
||||||
|
|
||||||
|
variant := proptools.StringDefault(tc.variant, "android_arm64_armv8-a")
|
||||||
|
|
||||||
|
m := result.ModuleForTests("foo", variant)
|
||||||
|
mixedBuildModuleInfo := result.TestContext.ModuleProvider(m.Module(), mixedBuildModuleProvider).(mixedBuildModuleInfo)
|
||||||
|
if w, g := tc.mixedBuildsEnabled, mixedBuildModuleInfo.QueuedBazelCall; w != g {
|
||||||
|
t.Errorf("Expected mixed builds enabled %t, got mixed builds enabled %t", w, g)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -354,6 +354,10 @@ type BaseModuleContext interface {
|
|||||||
|
|
||||||
AddMissingDependencies(missingDeps []string)
|
AddMissingDependencies(missingDeps []string)
|
||||||
|
|
||||||
|
// getMissingDependencies returns the list of missing dependencies.
|
||||||
|
// Calling this function prevents adding new dependencies.
|
||||||
|
getMissingDependencies() []string
|
||||||
|
|
||||||
// AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build
|
// AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build
|
||||||
AddUnconvertedBp2buildDep(dep string)
|
AddUnconvertedBp2buildDep(dep string)
|
||||||
|
|
||||||
@@ -939,7 +943,8 @@ type commonProperties struct {
|
|||||||
|
|
||||||
NamespaceExportedToMake bool `blueprint:"mutated"`
|
NamespaceExportedToMake bool `blueprint:"mutated"`
|
||||||
|
|
||||||
MissingDeps []string `blueprint:"mutated"`
|
MissingDeps []string `blueprint:"mutated"`
|
||||||
|
CheckedMissingDeps bool `blueprint:"mutated"`
|
||||||
|
|
||||||
// Name and variant strings stored by mutators to enable Module.String()
|
// Name and variant strings stored by mutators to enable Module.String()
|
||||||
DebugName string `blueprint:"mutated"`
|
DebugName string `blueprint:"mutated"`
|
||||||
@@ -2862,6 +2867,20 @@ func (b *baseModuleContext) AddMissingDependencies(deps []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *baseModuleContext) checkedMissingDeps() bool {
|
||||||
|
return b.Module().base().commonProperties.CheckedMissingDeps
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *baseModuleContext) getMissingDependencies() []string {
|
||||||
|
checked := &b.Module().base().commonProperties.CheckedMissingDeps
|
||||||
|
*checked = true
|
||||||
|
var missingDeps []string
|
||||||
|
missingDeps = append(missingDeps, b.Module().base().commonProperties.MissingDeps...)
|
||||||
|
missingDeps = append(missingDeps, b.bp.EarlyGetMissingDependencies()...)
|
||||||
|
missingDeps = FirstUniqueStrings(missingDeps)
|
||||||
|
return missingDeps
|
||||||
|
}
|
||||||
|
|
||||||
type AllowDisabledModuleDependency interface {
|
type AllowDisabledModuleDependency interface {
|
||||||
blueprint.DependencyTag
|
blueprint.DependencyTag
|
||||||
AllowDisabledModuleDependency(target Module) bool
|
AllowDisabledModuleDependency(target Module) bool
|
||||||
|
@@ -67,6 +67,8 @@ func registerMutatorsForBazelConversion(ctx *Context, bp2buildMutators []Registe
|
|||||||
// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
|
// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
|
||||||
// with the InitRegistrationContext and will be used at runtime.
|
// with the InitRegistrationContext and will be used at runtime.
|
||||||
func collateGloballyRegisteredMutators() sortableComponents {
|
func collateGloballyRegisteredMutators() sortableComponents {
|
||||||
|
// ensure mixed builds mutator is the last mutator
|
||||||
|
finalDeps = append(finalDeps, registerMixedBuildsMutator)
|
||||||
return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps)
|
return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,10 +887,16 @@ func (b *bottomUpMutatorContext) Rename(name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
|
func (b *bottomUpMutatorContext) AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module {
|
||||||
|
if b.baseModuleContext.checkedMissingDeps() {
|
||||||
|
panic("Adding deps not allowed after checking for missing deps")
|
||||||
|
}
|
||||||
return b.bp.AddDependency(module, tag, name...)
|
return b.bp.AddDependency(module, tag, name...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
|
func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) {
|
||||||
|
if b.baseModuleContext.checkedMissingDeps() {
|
||||||
|
panic("Adding deps not allowed after checking for missing deps")
|
||||||
|
}
|
||||||
b.bp.AddReverseDependency(module, tag, name)
|
b.bp.AddReverseDependency(module, tag, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,11 +946,17 @@ func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string
|
|||||||
|
|
||||||
func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
|
func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
|
||||||
names ...string) []blueprint.Module {
|
names ...string) []blueprint.Module {
|
||||||
|
if b.baseModuleContext.checkedMissingDeps() {
|
||||||
|
panic("Adding deps not allowed after checking for missing deps")
|
||||||
|
}
|
||||||
return b.bp.AddVariationDependencies(variations, tag, names...)
|
return b.bp.AddVariationDependencies(variations, tag, names...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
|
func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
|
||||||
tag blueprint.DependencyTag, names ...string) []blueprint.Module {
|
tag blueprint.DependencyTag, names ...string) []blueprint.Module {
|
||||||
|
if b.baseModuleContext.checkedMissingDeps() {
|
||||||
|
panic("Adding deps not allowed after checking for missing deps")
|
||||||
|
}
|
||||||
|
|
||||||
return b.bp.AddFarVariationDependencies(variations, tag, names...)
|
return b.bp.AddFarVariationDependencies(variations, tag, names...)
|
||||||
}
|
}
|
||||||
@@ -952,10 +966,16 @@ func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.Depende
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
|
func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
|
||||||
|
if b.baseModuleContext.checkedMissingDeps() {
|
||||||
|
panic("Adding deps not allowed after checking for missing deps")
|
||||||
|
}
|
||||||
b.bp.ReplaceDependencies(name)
|
b.bp.ReplaceDependencies(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) {
|
func (b *bottomUpMutatorContext) ReplaceDependenciesIf(name string, predicate blueprint.ReplaceDependencyPredicate) {
|
||||||
|
if b.baseModuleContext.checkedMissingDeps() {
|
||||||
|
panic("Adding deps not allowed after checking for missing deps")
|
||||||
|
}
|
||||||
b.bp.ReplaceDependenciesIf(name, predicate)
|
b.bp.ReplaceDependenciesIf(name, predicate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user