Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 04a1809d authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Handle missing dependencies in mixed builds"

parents 4aed3703 c13f7850
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -46,6 +46,10 @@ const (
	// that is not a platform incompatibility. Example: the module-type is not
	// enabled, or is not bp2build-converted.
	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
@@ -367,16 +371,26 @@ func GetBp2BuildAllowList() Bp2BuildConversionAllowlist {
// As a side effect, calling this method will also log whether this module is
// mixed build enabled for metrics reporting.
func MixedBuildsEnabled(ctx BaseModuleContext) MixedBuildEnabledStatus {
	module := ctx.Module()
	apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo)
	withinApex := !apexInfo.IsForPlatform()

	platformIncompatible := isPlatformIncompatible(ctx.Os(), ctx.Arch().ArchType)
	if platformIncompatible {
		ctx.Config().LogMixedBuild(ctx, false)
		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() &&
		module.Enabled() &&
		convertedToBazel(ctx, module) &&
+3 −5
Original line number Diff line number Diff line
@@ -74,14 +74,12 @@ var (
	}
)

func init() {
	RegisterMixedBuildsMutator(InitRegistrationContext)
func registerMixedBuildsMutator(ctx RegisterMutatorsContext) {
	ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
}

func RegisterMixedBuildsMutator(ctx RegistrationContext) {
	ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
		ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
	})
	ctx.FinalDepsMutators(registerMixedBuildsMutator)
}

func mixedBuildsPrepareMutator(ctx BottomUpMutatorContext) {
+147 −0
Original line number Diff line number Diff line
@@ -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)
			}
		})
	}
}
+20 −1
Original line number Diff line number Diff line
@@ -354,6 +354,10 @@ type BaseModuleContext interface {

	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(dep string)

@@ -940,6 +944,7 @@ type commonProperties struct {
	NamespaceExportedToMake bool `blueprint:"mutated"`

	MissingDeps        []string `blueprint:"mutated"`
	CheckedMissingDeps bool     `blueprint:"mutated"`

	// Name and variant strings stored by mutators to enable Module.String()
	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 {
	blueprint.DependencyTag
	AllowDisabledModuleDependency(target Module) bool
+20 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ func registerMutatorsForBazelConversion(ctx *Context, bp2buildMutators []Registe
// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
// with the InitRegistrationContext and will be used at runtime.
func collateGloballyRegisteredMutators() sortableComponents {
	// ensure mixed builds mutator is the last mutator
	finalDeps = append(finalDeps, registerMixedBuildsMutator)
	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 {
	if b.baseModuleContext.checkedMissingDeps() {
		panic("Adding deps not allowed after checking for missing deps")
	}
	return b.bp.AddDependency(module, tag, name...)
}

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

@@ -938,11 +946,17 @@ func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string

func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
	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...)
}

func (b *bottomUpMutatorContext) AddFarVariationDependencies(variations []blueprint.Variation,
	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...)
}
@@ -952,10 +966,16 @@ func (b *bottomUpMutatorContext) AddInterVariantDependency(tag blueprint.Depende
}

func (b *bottomUpMutatorContext) ReplaceDependencies(name string) {
	if b.baseModuleContext.checkedMissingDeps() {
		panic("Adding deps not allowed after checking for missing deps")
	}
	b.bp.ReplaceDependencies(name)
}

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