Add VariableFuncContext argument to VariableFuncs
Add a VariableFuncContext argument to VariableFuncs that implements GlobWithDeps. This will allow Soong to use optimized glob dependencies in VariableFuncs. Bug: 257079828 Test: no dependencies on directories in build.ninja.d Change-Id: Iee5fc9c9ae3087662a5d1a3d7323a87462299205
This commit is contained in:
parent
2a9208713e
commit
1b457a5e10
7 changed files with 41 additions and 17 deletions
|
@ -149,7 +149,7 @@ var (
|
|||
},
|
||||
"depfile")
|
||||
|
||||
_ = pctx.VariableFunc("ToolDir", func(config interface{}) (string, error) {
|
||||
_ = pctx.VariableFunc("ToolDir", func(ctx blueprint.VariableFuncContext, config interface{}) (string, error) {
|
||||
return config.(BootstrapConfig).HostToolDir(), nil
|
||||
})
|
||||
)
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func bootstrapVariable(name string, value func(BootstrapConfig) string) blueprint.Variable {
|
||||
return pctx.VariableFunc(name, func(config interface{}) (string, error) {
|
||||
return pctx.VariableFunc(name, func(ctx blueprint.VariableFuncContext, config interface{}) (string, error) {
|
||||
c, ok := config.(BootstrapConfig)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Bootstrap rules were passed a configuration that does not include theirs, config=%q",
|
||||
|
|
|
@ -44,7 +44,7 @@ import (
|
|||
// in a build failure with a "missing and no known rule to make it" error.
|
||||
|
||||
var (
|
||||
_ = pctx.VariableFunc("globCmd", func(config interface{}) (string, error) {
|
||||
_ = pctx.VariableFunc("globCmd", func(ctx blueprint.VariableFuncContext, config interface{}) (string, error) {
|
||||
return filepath.Join(config.(BootstrapConfig).SoongOutDir(), "bpglob"), nil
|
||||
})
|
||||
|
||||
|
|
|
@ -1798,7 +1798,7 @@ func (c *Context) resolveDependencies(ctx context.Context, config interface{}) (
|
|||
pprof.Do(ctx, pprof.Labels("blueprint", "ResolveDependencies"), func(ctx context.Context) {
|
||||
c.initProviders()
|
||||
|
||||
c.liveGlobals = newLiveTracker(config)
|
||||
c.liveGlobals = newLiveTracker(c, config)
|
||||
|
||||
deps, errs = c.generateSingletonBuildActions(config, c.preSingletonInfo, c.liveGlobals)
|
||||
if len(errs) > 0 {
|
||||
|
@ -4413,7 +4413,7 @@ func (c *Context) writeLocalBuildActions(nw *ninjaWriter,
|
|||
// A localVariable doesn't need the package names or config to
|
||||
// determine its name or value.
|
||||
name := v.fullName(nil)
|
||||
value, err := v.value(nil)
|
||||
value, err := v.value(nil, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -23,14 +23,16 @@ import "sync"
|
|||
type liveTracker struct {
|
||||
sync.Mutex
|
||||
config interface{} // Used to evaluate variable, rule, and pool values.
|
||||
ctx *Context // Used to evaluate globs
|
||||
|
||||
variables map[Variable]ninjaString
|
||||
pools map[Pool]*poolDef
|
||||
rules map[Rule]*ruleDef
|
||||
}
|
||||
|
||||
func newLiveTracker(config interface{}) *liveTracker {
|
||||
func newLiveTracker(ctx *Context, config interface{}) *liveTracker {
|
||||
return &liveTracker{
|
||||
ctx: ctx,
|
||||
config: config,
|
||||
variables: make(map[Variable]ninjaString),
|
||||
pools: make(map[Pool]*poolDef),
|
||||
|
@ -153,7 +155,9 @@ func (l *liveTracker) addPool(p Pool) error {
|
|||
func (l *liveTracker) addVariable(v Variable) error {
|
||||
_, ok := l.variables[v]
|
||||
if !ok {
|
||||
value, err := v.value(l.config)
|
||||
ctx := &variableFuncContext{l.ctx}
|
||||
|
||||
value, err := v.value(ctx, l.config)
|
||||
if err == errVariableIsArg {
|
||||
// This variable is a placeholder for an argument that can be passed
|
||||
// to a rule. It has no value and thus doesn't reference any other
|
||||
|
|
|
@ -59,7 +59,7 @@ type PackageContext interface {
|
|||
ImportAs(as, pkgPath string)
|
||||
|
||||
StaticVariable(name, value string) Variable
|
||||
VariableFunc(name string, f func(config interface{}) (string, error)) Variable
|
||||
VariableFunc(name string, f func(ctx VariableFuncContext, config interface{}) (string, error)) Variable
|
||||
VariableConfigMethod(name string, method interface{}) Variable
|
||||
|
||||
StaticPool(name string, params PoolParams) Pool
|
||||
|
@ -304,7 +304,7 @@ func (v *staticVariable) memoizeFullName(pkgNames map[*packageContext]string) {
|
|||
v.fullName_ = v.fullName(pkgNames)
|
||||
}
|
||||
|
||||
func (v *staticVariable) value(interface{}) (ninjaString, error) {
|
||||
func (v *staticVariable) value(VariableFuncContext, interface{}) (ninjaString, error) {
|
||||
ninjaStr, err := parseNinjaString(v.pctx.scope, v.value_)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error parsing variable %s value: %s", v, err)
|
||||
|
@ -320,10 +320,30 @@ func (v *staticVariable) String() string {
|
|||
type variableFunc struct {
|
||||
pctx *packageContext
|
||||
name_ string
|
||||
value_ func(interface{}) (string, error)
|
||||
value_ func(VariableFuncContext, interface{}) (string, error)
|
||||
fullName_ string
|
||||
}
|
||||
|
||||
// VariableFuncContext is passed to VariableFunc functions.
|
||||
type VariableFuncContext interface {
|
||||
// GlobWithDeps returns a list of files and directories that match the
|
||||
// specified pattern but do not match any of the patterns in excludes.
|
||||
// Any directories will have a '/' suffix. It also adds efficient
|
||||
// dependencies to rerun the primary builder whenever a file matching
|
||||
// the pattern as added or removed, without rerunning if a file that
|
||||
// does not match the pattern is added to a searched directory.
|
||||
GlobWithDeps(globPattern string, excludes []string) ([]string, error)
|
||||
}
|
||||
|
||||
type variableFuncContext struct {
|
||||
context *Context
|
||||
}
|
||||
|
||||
func (v *variableFuncContext) GlobWithDeps(pattern string,
|
||||
excludes []string) ([]string, error) {
|
||||
return v.context.glob(pattern, excludes)
|
||||
}
|
||||
|
||||
// VariableFunc returns a Variable whose value is determined by a function that
|
||||
// takes a config object as input and returns either the variable value or an
|
||||
// error. It may only be called during a Go package's initialization - either
|
||||
|
@ -336,7 +356,7 @@ type variableFunc struct {
|
|||
// reference other Ninja variables that are visible within the calling Go
|
||||
// package.
|
||||
func (p *packageContext) VariableFunc(name string,
|
||||
f func(config interface{}) (string, error)) Variable {
|
||||
f func(ctx VariableFuncContext, config interface{}) (string, error)) Variable {
|
||||
|
||||
checkCalledFromInit()
|
||||
|
||||
|
@ -382,7 +402,7 @@ func (p *packageContext) VariableConfigMethod(name string,
|
|||
methodValue := reflect.ValueOf(method)
|
||||
validateVariableMethod(name, methodValue)
|
||||
|
||||
fun := func(config interface{}) (string, error) {
|
||||
fun := func(ctx VariableFuncContext, config interface{}) (string, error) {
|
||||
result := methodValue.Call([]reflect.Value{reflect.ValueOf(config)})
|
||||
resultStr := result[0].Interface().(string)
|
||||
return resultStr, nil
|
||||
|
@ -420,8 +440,8 @@ func (v *variableFunc) memoizeFullName(pkgNames map[*packageContext]string) {
|
|||
v.fullName_ = v.fullName(pkgNames)
|
||||
}
|
||||
|
||||
func (v *variableFunc) value(config interface{}) (ninjaString, error) {
|
||||
value, err := v.value_(config)
|
||||
func (v *variableFunc) value(ctx VariableFuncContext, config interface{}) (ninjaString, error) {
|
||||
value, err := v.value_(ctx, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -484,7 +504,7 @@ func (v *argVariable) memoizeFullName(pkgNames map[*packageContext]string) {
|
|||
// Nothing to do, full name is known at initialization.
|
||||
}
|
||||
|
||||
func (v *argVariable) value(config interface{}) (ninjaString, error) {
|
||||
func (v *argVariable) value(ctx VariableFuncContext, config interface{}) (ninjaString, error) {
|
||||
return nil, errVariableIsArg
|
||||
}
|
||||
|
||||
|
|
4
scope.go
4
scope.go
|
@ -29,7 +29,7 @@ type Variable interface {
|
|||
name() string // "foo"
|
||||
fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
|
||||
memoizeFullName(pkgNames map[*packageContext]string) // precompute fullName if desired
|
||||
value(config interface{}) (ninjaString, error)
|
||||
value(ctx VariableFuncContext, config interface{}) (ninjaString, error)
|
||||
String() string
|
||||
}
|
||||
|
||||
|
@ -373,7 +373,7 @@ func (l *localVariable) memoizeFullName(pkgNames map[*packageContext]string) {
|
|||
// Nothing to do, full name is known at initialization.
|
||||
}
|
||||
|
||||
func (l *localVariable) value(interface{}) (ninjaString, error) {
|
||||
func (l *localVariable) value(VariableFuncContext, interface{}) (ninjaString, error) {
|
||||
return l.value_, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue