blob: d3527fa202d0181f39f88cfb463e5beea0566e83 [file] [log] [blame]
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001// Copyright 2015 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Dan Willemsen34cc69e2015-09-23 15:26:20 -070016
17import (
18 "fmt"
Colin Crossc6bbef32017-08-14 14:16:06 -070019 "strings"
Dan Willemsen34cc69e2015-09-23 15:26:20 -070020
21 "github.com/google/blueprint"
Colin Cross294941b2017-02-01 14:10:36 -080022 "github.com/google/blueprint/pathtools"
Dan Willemsen34cc69e2015-09-23 15:26:20 -070023)
24
Colin Cross0875c522017-11-28 17:34:01 -080025// PackageContext is a wrapper for blueprint.PackageContext that adds
Dan Willemsen34cc69e2015-09-23 15:26:20 -070026// some android-specific helper functions.
Colin Cross0875c522017-11-28 17:34:01 -080027type PackageContext struct {
Dan Willemsen34cc69e2015-09-23 15:26:20 -070028 blueprint.PackageContext
29}
30
Colin Cross0875c522017-11-28 17:34:01 -080031func NewPackageContext(pkgPath string) PackageContext {
32 return PackageContext{blueprint.NewPackageContext(pkgPath)}
Dan Willemsen34cc69e2015-09-23 15:26:20 -070033}
34
35// configErrorWrapper can be used with Path functions when a Context is not
36// available. A Config can be provided, and errors are stored as a list for
37// later retrieval.
38//
39// The most common use here will be with VariableFunc, where only a config is
40// provided, and an error should be returned.
41type configErrorWrapper struct {
Colin Cross0875c522017-11-28 17:34:01 -080042 pctx PackageContext
Dan Willemsen34cc69e2015-09-23 15:26:20 -070043 config Config
44 errors []error
45}
46
47var _ PathContext = &configErrorWrapper{}
48var _ errorfContext = &configErrorWrapper{}
Dan Willemsen54daaf02018-03-12 13:24:09 -070049var _ PackageVarContext = &configErrorWrapper{}
50var _ PackagePoolContext = &configErrorWrapper{}
51var _ PackageRuleContext = &configErrorWrapper{}
Dan Willemsen34cc69e2015-09-23 15:26:20 -070052
Colin Crossaabf6792017-11-29 00:27:14 -080053func (e *configErrorWrapper) Config() Config {
Dan Willemsen34cc69e2015-09-23 15:26:20 -070054 return e.config
55}
56func (e *configErrorWrapper) Errorf(format string, args ...interface{}) {
57 e.errors = append(e.errors, fmt.Errorf(format, args...))
58}
Dan Willemsen7b310ee2015-12-18 15:11:17 -080059func (e *configErrorWrapper) AddNinjaFileDeps(deps ...string) {
60 e.pctx.AddNinjaFileDeps(deps...)
61}
Dan Willemsen34cc69e2015-09-23 15:26:20 -070062
Colin Cross294941b2017-02-01 14:10:36 -080063func (e *configErrorWrapper) Fs() pathtools.FileSystem {
64 return nil
65}
66
Dan Willemsen54daaf02018-03-12 13:24:09 -070067type PackageVarContext interface {
68 PathContext
69 errorfContext
70}
71
72type PackagePoolContext PackageVarContext
73type PackageRuleContext PackageVarContext
74
Colin Cross0875c522017-11-28 17:34:01 -080075// VariableFunc wraps blueprint.PackageContext.VariableFunc, converting the interface{} config
Dan Willemsen54daaf02018-03-12 13:24:09 -070076// argument to a PackageVarContext.
Colin Cross0875c522017-11-28 17:34:01 -080077func (p PackageContext) VariableFunc(name string,
Dan Willemsen54daaf02018-03-12 13:24:09 -070078 f func(PackageVarContext) string) blueprint.Variable {
Colin Cross0875c522017-11-28 17:34:01 -080079
80 return p.PackageContext.VariableFunc(name, func(config interface{}) (string, error) {
Dan Willemsen54daaf02018-03-12 13:24:09 -070081 ctx := &configErrorWrapper{p, config.(Config), nil}
82 ret := f(ctx)
83 if len(ctx.errors) > 0 {
84 return "", ctx.errors[0]
85 }
86 return ret, nil
Colin Cross0875c522017-11-28 17:34:01 -080087 })
88}
89
90// PoolFunc wraps blueprint.PackageContext.PoolFunc, converting the interface{} config
Dan Willemsen54daaf02018-03-12 13:24:09 -070091// argument to a Context that supports Config().
Colin Cross0875c522017-11-28 17:34:01 -080092func (p PackageContext) PoolFunc(name string,
Dan Willemsen54daaf02018-03-12 13:24:09 -070093 f func(PackagePoolContext) blueprint.PoolParams) blueprint.Pool {
Colin Cross0875c522017-11-28 17:34:01 -080094
95 return p.PackageContext.PoolFunc(name, func(config interface{}) (blueprint.PoolParams, error) {
Dan Willemsen54daaf02018-03-12 13:24:09 -070096 ctx := &configErrorWrapper{p, config.(Config), nil}
97 params := f(ctx)
98 if len(ctx.errors) > 0 {
99 return params, ctx.errors[0]
100 }
101 return params, nil
Colin Cross0875c522017-11-28 17:34:01 -0800102 })
103}
104
105// RuleFunc wraps blueprint.PackageContext.RuleFunc, converting the interface{} config
Colin Cross2e2dbc22019-09-25 13:31:46 -0700106// argument to a Context that supports Config(), and provides a default Pool if none is
107// specified.
Colin Cross0875c522017-11-28 17:34:01 -0800108func (p PackageContext) RuleFunc(name string,
Dan Willemsen54daaf02018-03-12 13:24:09 -0700109 f func(PackageRuleContext) blueprint.RuleParams, argNames ...string) blueprint.Rule {
Colin Cross0875c522017-11-28 17:34:01 -0800110
111 return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700112 ctx := &configErrorWrapper{p, config.(Config), nil}
113 params := f(ctx)
114 if len(ctx.errors) > 0 {
115 return params, ctx.errors[0]
116 }
Ramy Medhatdd0418a2019-11-04 18:16:11 -0500117 if (ctx.Config().UseGoma() || ctx.Config().UseRBE()) && params.Pool == nil {
118 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by
119 // goma/RBE, restrict jobs to the local parallelism value
Colin Cross2e2dbc22019-09-25 13:31:46 -0700120 params.Pool = localPool
121 }
Dan Willemsen54daaf02018-03-12 13:24:09 -0700122 return params, nil
Colin Cross0875c522017-11-28 17:34:01 -0800123 }, argNames...)
124}
125
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700126// SourcePathVariable returns a Variable whose value is the source directory
127// appended with the supplied path. It may only be called during a Go package's
128// initialization - either from the init() function or as part of a
129// package-scoped variable's initialization.
Colin Cross0875c522017-11-28 17:34:01 -0800130func (p PackageContext) SourcePathVariable(name, path string) blueprint.Variable {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700131 return p.VariableFunc(name, func(ctx PackageVarContext) string {
Colin Crossfe4bc362018-09-12 10:02:13 -0700132 p, err := safePathForSource(ctx, path)
133 if err != nil {
134 ctx.Errorf("%s", err.Error())
135 }
136 return p.String()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700137 })
138}
139
Colin Crossc6bbef32017-08-14 14:16:06 -0700140// SourcePathsVariable returns a Variable whose value is the source directory
141// appended with the supplied paths, joined with separator. It may only be
142// called during a Go package's initialization - either from the init()
143// function or as part of a package-scoped variable's initialization.
Colin Cross0875c522017-11-28 17:34:01 -0800144func (p PackageContext) SourcePathsVariable(name, separator string, paths ...string) blueprint.Variable {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700145 return p.VariableFunc(name, func(ctx PackageVarContext) string {
Colin Crossc6bbef32017-08-14 14:16:06 -0700146 var ret []string
147 for _, path := range paths {
Colin Crossfe4bc362018-09-12 10:02:13 -0700148 p, err := safePathForSource(ctx, path)
149 if err != nil {
150 ctx.Errorf("%s", err.Error())
151 }
Colin Crossc6bbef32017-08-14 14:16:06 -0700152 ret = append(ret, p.String())
153 }
Dan Willemsen54daaf02018-03-12 13:24:09 -0700154 return strings.Join(ret, separator)
Colin Crossc6bbef32017-08-14 14:16:06 -0700155 })
156}
157
Colin Cross64162712017-08-08 13:17:59 -0700158// SourcePathVariableWithEnvOverride returns a Variable whose value is the source directory
159// appended with the supplied path, or the value of the given environment variable if it is set.
160// The environment variable is not required to point to a path inside the source tree.
161// It may only be called during a Go package's initialization - either from the init() function or
162// as part of a package-scoped variable's initialization.
Colin Cross0875c522017-11-28 17:34:01 -0800163func (p PackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700164 return p.VariableFunc(name, func(ctx PackageVarContext) string {
Colin Crossfe4bc362018-09-12 10:02:13 -0700165 p, err := safePathForSource(ctx, path)
166 if err != nil {
167 ctx.Errorf("%s", err.Error())
168 }
Dan Willemsen54daaf02018-03-12 13:24:09 -0700169 return ctx.Config().GetenvWithDefault(env, p.String())
Colin Cross64162712017-08-08 13:17:59 -0700170 })
171}
172
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800173// HostBinToolVariable returns a Variable whose value is the path to a host tool
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700174// in the bin directory for host targets. It may only be called during a Go
175// package's initialization - either from the init() function or as part of a
176// package-scoped variable's initialization.
Colin Cross0875c522017-11-28 17:34:01 -0800177func (p PackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700178 return p.VariableFunc(name, func(ctx PackageVarContext) string {
Martin Stjernholm7260d062019-12-09 21:47:14 +0000179 return ctx.Config().HostToolPath(ctx, path).String()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700180 })
181}
182
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800183// HostJNIToolVariable returns a Variable whose value is the path to a host tool
184// in the lib directory for host targets. It may only be called during a Go
185// package's initialization - either from the init() function or as part of a
186// package-scoped variable's initialization.
187func (p PackageContext) HostJNIToolVariable(name, path string) blueprint.Variable {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700188 return p.VariableFunc(name, func(ctx PackageVarContext) string {
Martin Stjernholm7260d062019-12-09 21:47:14 +0000189 return ctx.Config().HostJNIToolPath(ctx, path).String()
Colin Cross5ab4e6d2017-11-22 16:20:45 -0800190 })
191}
192
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700193// HostJavaToolVariable returns a Variable whose value is the path to a host
194// tool in the frameworks directory for host targets. It may only be called
195// during a Go package's initialization - either from the init() function or as
196// part of a package-scoped variable's initialization.
Colin Cross0875c522017-11-28 17:34:01 -0800197func (p PackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700198 return p.VariableFunc(name, func(ctx PackageVarContext) string {
Martin Stjernholm7260d062019-12-09 21:47:14 +0000199 return ctx.Config().HostJavaToolPath(ctx, path).String()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700200 })
201}
202
203// IntermediatesPathVariable returns a Variable whose value is the intermediate
204// directory appended with the supplied path. It may only be called during a Go
205// package's initialization - either from the init() function or as part of a
206// package-scoped variable's initialization.
Colin Cross0875c522017-11-28 17:34:01 -0800207func (p PackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700208 return p.VariableFunc(name, func(ctx PackageVarContext) string {
209 return PathForIntermediates(ctx, path).String()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700210 })
211}
212
Jeff Gaston734e3802017-04-10 15:47:24 -0700213// PrefixedExistentPathsForSourcesVariable returns a Variable whose value is the
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800214// list of present source paths prefixed with the supplied prefix. It may only
215// be called during a Go package's initialization - either from the init()
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700216// function or as part of a package-scoped variable's initialization.
Colin Cross0875c522017-11-28 17:34:01 -0800217func (p PackageContext) PrefixedExistentPathsForSourcesVariable(
Dan Willemsen7b310ee2015-12-18 15:11:17 -0800218 name, prefix string, paths []string) blueprint.Variable {
219
Dan Willemsen54daaf02018-03-12 13:24:09 -0700220 return p.VariableFunc(name, func(ctx PackageVarContext) string {
Colin Cross32f38982018-02-22 11:47:25 -0800221 paths := ExistentPathsForSources(ctx, paths)
Dan Willemsen54daaf02018-03-12 13:24:09 -0700222 return JoinWithPrefix(paths.Strings(), prefix)
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700223 })
224}
Colin Cross9d45bb72016-08-29 16:14:13 -0700225
Colin Cross2e2dbc22019-09-25 13:31:46 -0700226// AndroidStaticRule is an alias for StaticRule.
Colin Cross0875c522017-11-28 17:34:01 -0800227func (p PackageContext) AndroidStaticRule(name string, params blueprint.RuleParams,
Colin Cross9d45bb72016-08-29 16:14:13 -0700228 argNames ...string) blueprint.Rule {
Colin Cross2e2dbc22019-09-25 13:31:46 -0700229 return p.StaticRule(name, params, argNames...)
230}
231
232// StaticRule wraps blueprint.StaticRule and provides a default Pool if none is specified.
233func (p PackageContext) StaticRule(name string, params blueprint.RuleParams,
234 argNames ...string) blueprint.Rule {
235 return p.RuleFunc(name, func(PackageRuleContext) blueprint.RuleParams {
Dan Willemsen54daaf02018-03-12 13:24:09 -0700236 return params
Colin Cross9d45bb72016-08-29 16:14:13 -0700237 }, argNames...)
238}
239
Ramy Medhatdd0418a2019-11-04 18:16:11 -0500240// RemoteRuleSupports selects if a AndroidRemoteStaticRule supports goma, RBE, or both.
241type RemoteRuleSupports int
242
243const (
244 SUPPORTS_NONE = 0
245 SUPPORTS_GOMA = 1 << iota
246 SUPPORTS_RBE = 1 << iota
247 SUPPORTS_BOTH = SUPPORTS_GOMA | SUPPORTS_RBE
248)
249
250// AndroidRemoteStaticRule wraps blueprint.StaticRule but uses goma or RBE's parallelism if goma or RBE are enabled
251// and the appropriate SUPPORTS_* flag is set.
252func (p PackageContext) AndroidRemoteStaticRule(name string, supports RemoteRuleSupports, params blueprint.RuleParams,
Colin Cross9d45bb72016-08-29 16:14:13 -0700253 argNames ...string) blueprint.Rule {
Ramy Medhatdd0418a2019-11-04 18:16:11 -0500254
255 return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) {
256 ctx := &configErrorWrapper{p, config.(Config), nil}
257 if ctx.Config().UseGoma() && supports&SUPPORTS_GOMA == 0 {
258 // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
259 // local parallelism value
260 params.Pool = localPool
261 }
262
263 if ctx.Config().UseRBE() && supports&SUPPORTS_RBE == 0 {
264 // When USE_RBE=true is set and the rule is not supported by RBE, restrict jobs to the
265 // local parallelism value
266 params.Pool = localPool
267 }
268
269 return params, nil
270 }, argNames...)
Colin Cross9d45bb72016-08-29 16:14:13 -0700271}