• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18	"github.com/google/blueprint"
19	"github.com/google/blueprint/pathtools"
20)
21
22// SingletonContext
23type SingletonContext interface {
24	Config() Config
25	DeviceConfig() DeviceConfig
26
27	ModuleName(module blueprint.Module) string
28	ModuleDir(module blueprint.Module) string
29	ModuleSubDir(module blueprint.Module) string
30	ModuleType(module blueprint.Module) string
31	BlueprintFile(module blueprint.Module) string
32
33	ModuleErrorf(module blueprint.Module, format string, args ...interface{})
34	Errorf(format string, args ...interface{})
35	Failed() bool
36
37	Variable(pctx PackageContext, name, value string)
38	Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
39	Build(pctx PackageContext, params BuildParams)
40	RequireNinjaVersion(major, minor, micro int)
41
42	// SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
43	// that controls where Ninja stores its build log files.  This value can be
44	// set at most one time for a single build, later calls are ignored.
45	SetNinjaBuildDir(pctx PackageContext, value string)
46
47	// Eval takes a string with embedded ninja variables, and returns a string
48	// with all of the variables recursively expanded. Any variables references
49	// are expanded in the scope of the PackageContext.
50	Eval(pctx PackageContext, ninjaStr string) (string, error)
51
52	VisitAllModulesBlueprint(visit func(blueprint.Module))
53	VisitAllModules(visit func(Module))
54	VisitAllModulesIf(pred func(Module) bool, visit func(Module))
55	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
56	VisitDepsDepthFirst(module Module, visit func(Module))
57	// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
58	VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
59		visit func(Module))
60
61	VisitAllModuleVariants(module Module, visit func(Module))
62
63	PrimaryModule(module Module) Module
64	FinalModule(module Module) Module
65
66	AddNinjaFileDeps(deps ...string)
67
68	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
69	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
70	// builder whenever a file matching the pattern as added or removed, without rerunning if a
71	// file that does not match the pattern is added to a searched directory.
72	GlobWithDeps(pattern string, excludes []string) ([]string, error)
73
74	Fs() pathtools.FileSystem
75}
76
77type singletonAdaptor struct {
78	Singleton
79
80	buildParams []BuildParams
81	ruleParams  map[blueprint.Rule]blueprint.RuleParams
82}
83
84var _ testBuildProvider = (*singletonAdaptor)(nil)
85
86func (s *singletonAdaptor) GenerateBuildActions(ctx blueprint.SingletonContext) {
87	sctx := &singletonContextAdaptor{SingletonContext: ctx}
88	if sctx.Config().captureBuild {
89		sctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
90	}
91
92	s.Singleton.GenerateBuildActions(sctx)
93
94	s.buildParams = sctx.buildParams
95	s.ruleParams = sctx.ruleParams
96}
97
98func (s *singletonAdaptor) BuildParamsForTests() []BuildParams {
99	return s.buildParams
100}
101
102func (s *singletonAdaptor) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
103	return s.ruleParams
104}
105
106type Singleton interface {
107	GenerateBuildActions(SingletonContext)
108}
109
110type singletonContextAdaptor struct {
111	blueprint.SingletonContext
112
113	buildParams []BuildParams
114	ruleParams  map[blueprint.Rule]blueprint.RuleParams
115}
116
117func (s *singletonContextAdaptor) Config() Config {
118	return s.SingletonContext.Config().(Config)
119}
120
121func (s *singletonContextAdaptor) DeviceConfig() DeviceConfig {
122	return DeviceConfig{s.Config().deviceConfig}
123}
124
125func (s *singletonContextAdaptor) Variable(pctx PackageContext, name, value string) {
126	s.SingletonContext.Variable(pctx.PackageContext, name, value)
127}
128
129func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
130	rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
131	if s.Config().captureBuild {
132		s.ruleParams[rule] = params
133	}
134	return rule
135}
136
137func (s *singletonContextAdaptor) Build(pctx PackageContext, params BuildParams) {
138	if s.Config().captureBuild {
139		s.buildParams = append(s.buildParams, params)
140	}
141	bparams := convertBuildParams(params)
142	s.SingletonContext.Build(pctx.PackageContext, bparams)
143
144}
145
146func (s *singletonContextAdaptor) SetNinjaBuildDir(pctx PackageContext, value string) {
147	s.SingletonContext.SetNinjaBuildDir(pctx.PackageContext, value)
148}
149
150func (s *singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (string, error) {
151	return s.SingletonContext.Eval(pctx.PackageContext, ninjaStr)
152}
153
154// visitAdaptor wraps a visit function that takes an android.Module parameter into
155// a function that takes an blueprint.Module parameter and only calls the visit function if the
156// blueprint.Module is an android.Module.
157func visitAdaptor(visit func(Module)) func(blueprint.Module) {
158	return func(module blueprint.Module) {
159		if aModule, ok := module.(Module); ok {
160			visit(aModule)
161		}
162	}
163}
164
165// predAdaptor wraps a pred function that takes an android.Module parameter
166// into a function that takes an blueprint.Module parameter and only calls the visit function if the
167// blueprint.Module is an android.Module, otherwise returns false.
168func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool {
169	return func(module blueprint.Module) bool {
170		if aModule, ok := module.(Module); ok {
171			return pred(aModule)
172		} else {
173			return false
174		}
175	}
176}
177
178func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) {
179	s.SingletonContext.VisitAllModules(visit)
180}
181
182func (s *singletonContextAdaptor) VisitAllModules(visit func(Module)) {
183	s.SingletonContext.VisitAllModules(visitAdaptor(visit))
184}
185
186func (s *singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) {
187	s.SingletonContext.VisitAllModulesIf(predAdaptor(pred), visitAdaptor(visit))
188}
189
190func (s *singletonContextAdaptor) VisitDepsDepthFirst(module Module, visit func(Module)) {
191	s.SingletonContext.VisitDepsDepthFirst(module, visitAdaptor(visit))
192}
193
194func (s *singletonContextAdaptor) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
195	s.SingletonContext.VisitDepsDepthFirstIf(module, predAdaptor(pred), visitAdaptor(visit))
196}
197
198func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit func(Module)) {
199	s.SingletonContext.VisitAllModuleVariants(module, visitAdaptor(visit))
200}
201
202func (s *singletonContextAdaptor) PrimaryModule(module Module) Module {
203	return s.SingletonContext.PrimaryModule(module).(Module)
204}
205
206func (s *singletonContextAdaptor) FinalModule(module Module) Module {
207	return s.SingletonContext.FinalModule(module).(Module)
208}
209