Merge "Add sortableComponent abstraction" am: 4160a071d6

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1622499

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I50766f00403249ae3c506bdbbda86e85150e8dc1
This commit is contained in:
Paul Duffin
2021-03-08 22:19:32 +00:00
committed by Automerger Merge Worker
3 changed files with 94 additions and 36 deletions

View File

@@ -33,22 +33,8 @@ import (
// run FinalDeps mutators (CreateVariations disallowed in this phase) // run FinalDeps mutators (CreateVariations disallowed in this phase)
// continue on to GenerateAndroidBuildActions // continue on to GenerateAndroidBuildActions
func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
for _, t := range mutators {
var handle blueprint.MutatorHandle
if t.bottomUpMutator != nil {
handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
} else if t.topDownMutator != nil {
handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
}
if t.parallel {
handle.Parallel()
}
}
}
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing. // RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) { func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) {
mctx := &registerMutatorsContext{ mctx := &registerMutatorsContext{
bazelConversionMode: true, bazelConversionMode: true,
} }
@@ -80,10 +66,10 @@ func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, preArchMutators,
f(mctx) f(mctx)
} }
registerMutatorsToContext(ctx, mctx.mutators) mctx.mutators.registerAll(ctx)
} }
func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) { func registerMutators(ctx *Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
mctx := &registerMutatorsContext{} mctx := &registerMutatorsContext{}
register := func(funcs []RegisterMutatorFunc) { register := func(funcs []RegisterMutatorFunc) {
@@ -103,11 +89,11 @@ func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalD
mctx.finalPhase = true mctx.finalPhase = true
register(finalDeps) register(finalDeps)
registerMutatorsToContext(ctx, mctx.mutators) mctx.mutators.registerAll(ctx)
} }
type registerMutatorsContext struct { type registerMutatorsContext struct {
mutators []*mutator mutators sortableComponents
finalPhase bool finalPhase bool
bazelConversionMode bool bazelConversionMode bool
} }
@@ -473,6 +459,23 @@ func (x *registerMutatorsContext) TopDown(name string, m TopDownMutator) Mutator
return mutator return mutator
} }
func (mutator *mutator) componentName() string {
return mutator.name
}
func (mutator *mutator) register(ctx *Context) {
blueprintCtx := ctx.Context
var handle blueprint.MutatorHandle
if mutator.bottomUpMutator != nil {
handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator)
} else if mutator.topDownMutator != nil {
handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
}
if mutator.parallel {
handle.Parallel()
}
}
type MutatorHandle interface { type MutatorHandle interface {
Parallel() MutatorHandle Parallel() MutatorHandle
} }

View File

@@ -21,21 +21,78 @@ import (
"github.com/google/blueprint" "github.com/google/blueprint"
) )
// A sortable component is one whose registration order affects the order in which it is executed
// and so affects the behavior of the build system. As a result it is important for the order in
// which they are registered during tests to match the order used at runtime and so the test
// infrastructure will sort them to match.
//
// The sortable components are mutators, singletons and pre-singletons. Module types are not
// sortable because their order of registration does not affect the runtime behavior.
type sortableComponent interface {
// componentName returns the name of the component.
//
// Uniquely identifies the components within the set of components used at runtimr and during
// tests.
componentName() string
// register registers this component in the supplied context.
register(ctx *Context)
}
type sortableComponents []sortableComponent
// registerAll registers all components in this slice with the supplied context.
func (r sortableComponents) registerAll(ctx *Context) {
for _, c := range r {
c.register(ctx)
}
}
type moduleType struct { type moduleType struct {
name string name string
factory ModuleFactory factory ModuleFactory
} }
func (t moduleType) register(ctx *Context) {
ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
}
var moduleTypes []moduleType var moduleTypes []moduleType
var moduleTypesForDocs = map[string]reflect.Value{} var moduleTypesForDocs = map[string]reflect.Value{}
type singleton struct { type singleton struct {
// True if this should be registered as a pre-singleton, false otherwise.
pre bool
name string name string
factory SingletonFactory factory SingletonFactory
} }
var singletons []singleton func newSingleton(name string, factory SingletonFactory) singleton {
var preSingletons []singleton return singleton{false, name, factory}
}
func newPreSingleton(name string, factory SingletonFactory) singleton {
return singleton{true, name, factory}
}
func (s singleton) componentName() string {
return s.name
}
func (s singleton) register(ctx *Context) {
adaptor := SingletonFactoryAdaptor(ctx, s.factory)
if s.pre {
ctx.RegisterPreSingletonType(s.name, adaptor)
} else {
ctx.RegisterSingletonType(s.name, adaptor)
}
}
var _ sortableComponent = singleton{}
var singletons sortableComponents
var preSingletons sortableComponents
type mutator struct { type mutator struct {
name string name string
@@ -44,6 +101,8 @@ type mutator struct {
parallel bool parallel bool
} }
var _ sortableComponent = &mutator{}
type ModuleFactory func() Module type ModuleFactory func() Module
// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module // ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
@@ -84,11 +143,11 @@ func RegisterModuleTypeForDocs(name string, factory reflect.Value) {
} }
func RegisterSingletonType(name string, factory SingletonFactory) { func RegisterSingletonType(name string, factory SingletonFactory) {
singletons = append(singletons, singleton{name, factory}) singletons = append(singletons, newSingleton(name, factory))
} }
func RegisterPreSingletonType(name string, factory SingletonFactory) { func RegisterPreSingletonType(name string, factory SingletonFactory) {
preSingletons = append(preSingletons, singleton{name, factory}) preSingletons = append(preSingletons, newPreSingleton(name, factory))
} }
type Context struct { type Context struct {
@@ -107,33 +166,29 @@ func NewContext(config Config) *Context {
// files to semantically equivalent BUILD files. // files to semantically equivalent BUILD files.
func (ctx *Context) RegisterForBazelConversion() { func (ctx *Context) RegisterForBazelConversion() {
for _, t := range moduleTypes { for _, t := range moduleTypes {
ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory)) t.register(ctx)
} }
// Required for SingletonModule types, even though we are not using them. // Required for SingletonModule types, even though we are not using them.
for _, t := range singletons { for _, t := range singletons {
ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory)) t.register(ctx)
} }
RegisterMutatorsForBazelConversion(ctx.Context, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators) RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators)
} }
// Register the pipeline of singletons, module types, and mutators for // Register the pipeline of singletons, module types, and mutators for
// generating build.ninja and other files for Kati, from Android.bp files. // generating build.ninja and other files for Kati, from Android.bp files.
func (ctx *Context) Register() { func (ctx *Context) Register() {
for _, t := range preSingletons { preSingletons.registerAll(ctx)
ctx.RegisterPreSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
}
for _, t := range moduleTypes { for _, t := range moduleTypes {
ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory)) t.register(ctx)
} }
for _, t := range singletons { singletons.registerAll(ctx)
ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
}
registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps) registerMutators(ctx, preArch, preDeps, postDeps, finalDeps)
ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(ctx, BazelSingleton)) ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(ctx, BazelSingleton))

View File

@@ -141,14 +141,14 @@ func (ctx *TestContext) DepsBp2BuildMutators(f RegisterMutatorFunc) {
} }
func (ctx *TestContext) Register() { func (ctx *TestContext) Register() {
registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps) registerMutators(ctx.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
ctx.RegisterSingletonType("env", EnvSingleton) ctx.RegisterSingletonType("env", EnvSingleton)
} }
// RegisterForBazelConversion prepares a test context for bp2build conversion. // RegisterForBazelConversion prepares a test context for bp2build conversion.
func (ctx *TestContext) RegisterForBazelConversion() { func (ctx *TestContext) RegisterForBazelConversion() {
RegisterMutatorsForBazelConversion(ctx.Context.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators) RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators)
} }
func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) { func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {