diff --git a/android/makevars.go b/android/makevars.go index 3ca7792d4..f78439596 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -139,15 +139,24 @@ type SingletonMakeVarsProvider interface { MakeVars(ctx MakeVarsContext) } -// registerSingletonMakeVarsProvider adds a singleton that implements SingletonMakeVarsProvider to the list of -// MakeVarsProviders to run. -func registerSingletonMakeVarsProvider(singleton SingletonMakeVarsProvider) { - singletonMakeVarsProviders = append(singletonMakeVarsProviders, - makeVarsProvider{pctx, SingletonmakeVarsProviderAdapter(singleton)}) +var singletonMakeVarsProvidersKey = NewOnceKey("singletonMakeVarsProvidersKey") + +// registerSingletonMakeVarsProvider adds a singleton that implements SingletonMakeVarsProvider to +// the list of MakeVarsProviders to run. +func registerSingletonMakeVarsProvider(config Config, singleton SingletonMakeVarsProvider) { + // Singletons are registered on the Context and may be different between different Contexts, + // for example when running multiple tests. Store the SingletonMakeVarsProviders in the + // Config so they are attached to the Context. + singletonMakeVarsProviders := config.Once(singletonMakeVarsProvidersKey, func() interface{} { + return &[]makeVarsProvider{} + }).(*[]makeVarsProvider) + + *singletonMakeVarsProviders = append(*singletonMakeVarsProviders, + makeVarsProvider{pctx, singletonMakeVarsProviderAdapter(singleton)}) } -// SingletonmakeVarsProviderAdapter converts a SingletonMakeVarsProvider to a MakeVarsProvider. -func SingletonmakeVarsProviderAdapter(singleton SingletonMakeVarsProvider) MakeVarsProvider { +// singletonMakeVarsProviderAdapter converts a SingletonMakeVarsProvider to a MakeVarsProvider. +func singletonMakeVarsProviderAdapter(singleton SingletonMakeVarsProvider) MakeVarsProvider { return func(ctx MakeVarsContext) { singleton.MakeVars(ctx) } } @@ -175,9 +184,6 @@ type makeVarsProvider struct { // Collection of makevars providers that are registered in init() methods. var makeVarsInitProviders []makeVarsProvider -// Collection of singleton makevars providers that are not registered as part of init() methods. -var singletonMakeVarsProviders []makeVarsProvider - type makeVarsContext struct { SingletonContext config Config @@ -224,7 +230,11 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { var vars []makeVarsVariable var dists []dist var phonies []phony - for _, provider := range append(makeVarsInitProviders) { + + providers := append([]makeVarsProvider(nil), makeVarsInitProviders...) + providers = append(providers, *ctx.Config().Get(singletonMakeVarsProvidersKey).(*[]makeVarsProvider)...) + + for _, provider := range providers { mctx := &makeVarsContext{ SingletonContext: ctx, pctx: provider.pctx, @@ -237,25 +247,6 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { dists = append(dists, mctx.dists...) } - for _, provider := range append(singletonMakeVarsProviders) { - mctx := &makeVarsContext{ - SingletonContext: ctx, - pctx: provider.pctx, - } - - provider.call(mctx) - - vars = append(vars, mctx.vars...) - phonies = append(phonies, mctx.phonies...) - dists = append(dists, mctx.dists...) - } - - // Clear singleton makevars providers after use. Since these are in-memory - // singletons, this ensures state is reset if the build tree is processed - // multiple times. - // TODO(cparsons): Clean up makeVarsProviders to be part of the context. - singletonMakeVarsProviders = nil - ctx.VisitAllModules(func(m Module) { if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled() { mctx := &makeVarsContext{ diff --git a/android/register.go b/android/register.go index bd824c9c1..b33ad40b1 100644 --- a/android/register.go +++ b/android/register.go @@ -29,7 +29,7 @@ var moduleTypes []moduleType type singleton struct { name string - factory blueprint.SingletonFactory + factory SingletonFactory } var singletons []singleton @@ -57,11 +57,11 @@ type SingletonFactory func() Singleton // SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting // a Singleton into a blueprint.Singleton -func SingletonFactoryAdaptor(factory SingletonFactory) blueprint.SingletonFactory { +func SingletonFactoryAdaptor(ctx *Context, factory SingletonFactory) blueprint.SingletonFactory { return func() blueprint.Singleton { singleton := factory() if makevars, ok := singleton.(SingletonMakeVarsProvider); ok { - registerSingletonMakeVarsProvider(makevars) + registerSingletonMakeVarsProvider(ctx.config, makevars) } return &singletonAdaptor{Singleton: singleton} } @@ -72,11 +72,11 @@ func RegisterModuleType(name string, factory ModuleFactory) { } func RegisterSingletonType(name string, factory SingletonFactory) { - singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)}) + singletons = append(singletons, singleton{name, factory}) } func RegisterPreSingletonType(name string, factory SingletonFactory) { - preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)}) + preSingletons = append(preSingletons, singleton{name, factory}) } type Context struct { @@ -92,7 +92,7 @@ func NewContext(config Config) *Context { func (ctx *Context) Register() { for _, t := range preSingletons { - ctx.RegisterPreSingletonType(t.name, t.factory) + ctx.RegisterPreSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory)) } for _, t := range moduleTypes { @@ -100,21 +100,21 @@ func (ctx *Context) Register() { } for _, t := range singletons { - ctx.RegisterSingletonType(t.name, t.factory) + ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory)) } registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps) - ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(BazelSingleton)) + ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(ctx, BazelSingleton)) // Register phony just before makevars so it can write out its phony rules as Make rules - ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory)) + ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(ctx, phonySingletonFactory)) // Register makevars after other singletons so they can export values through makevars - ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc)) + ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(ctx, makeVarsSingletonFunc)) // Register env last so that it can track all used environment variables - ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton)) + ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(ctx, EnvSingleton)) } func ModuleTypeFactories() map[string]ModuleFactory { diff --git a/android/testing.go b/android/testing.go index d83cecc43..1e2ae130a 100644 --- a/android/testing.go +++ b/android/testing.go @@ -104,7 +104,7 @@ func (ctx *TestContext) RegisterModuleType(name string, factory ModuleFactory) { } func (ctx *TestContext) RegisterSingletonType(name string, factory SingletonFactory) { - ctx.Context.RegisterSingletonType(name, SingletonFactoryAdaptor(factory)) + ctx.Context.RegisterSingletonType(name, SingletonFactoryAdaptor(ctx.Context, factory)) } func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule { diff --git a/java/java_test.go b/java/java_test.go index 87d6ebbd4..5cc97b38e 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -92,8 +92,8 @@ func testContext(config android.Config) *android.TestContext { ctx.PreDepsMutators(python.RegisterPythonPreDepsMutators) ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators) - ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory)) - ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(sdkPreSingletonFactory)) + ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(ctx.Context, OverlaySingletonFactory)) + ctx.RegisterPreSingletonType("sdk_versions", android.SingletonFactoryAdaptor(ctx.Context, sdkPreSingletonFactory)) android.RegisterPrebuiltMutators(ctx)