1bc967ed43
Blueprint is a build system component that reads Blueprints files defining modules to be built, and generates a Ninja build manifest that can be used to perform all the build actions. It does not dictate or implement much build policy itself, but rather provides a framework to ease the process of defining build logic in Go. The "blueprint" and "blueprint/parser" Go packages contain the functionality for reading Blueprint files and invoking build logic functions defined in other Go packages. The "blueprint/bootstrap" Go package contains just enough build logic to build a binary that includes Blueprint and any pure-Go (i.e. no cgo) build logic defined in external Go packages. This can be used to create a minimal Ninja file that's capable of bootstrapping a Blueprint-based build system from source. The "blueprint/bootstrap/minibp" Go package contains code for a minimal binary that includes the build logic defined in the "blueprint/bootstrap" package. This binary can then create the Ninja file for the bootstrapping process. Change-Id: I8d8390042372a72d225785cda738525001b009f1
116 lines
2.4 KiB
Go
116 lines
2.4 KiB
Go
package blueprint
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
)
|
|
|
|
type Module interface {
|
|
GenerateBuildActions(ModuleContext)
|
|
}
|
|
|
|
type ModuleContext interface {
|
|
ModuleName() string
|
|
ModuleDir() string
|
|
Config() Config
|
|
|
|
ModuleErrorf(fmt string, args ...interface{})
|
|
PropertyErrorf(property, fmt string, args ...interface{})
|
|
|
|
Variable(name, value string)
|
|
Rule(name string, params RuleParams) Rule
|
|
Build(params BuildParams)
|
|
|
|
VisitDepsDepthFirst(visit func(Module))
|
|
VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
|
|
}
|
|
|
|
var _ ModuleContext = (*moduleContext)(nil)
|
|
|
|
type moduleContext struct {
|
|
context *Context
|
|
config Config
|
|
module Module
|
|
scope *localScope
|
|
info *moduleInfo
|
|
|
|
errs []error
|
|
|
|
actionDefs localBuildActions
|
|
}
|
|
|
|
func (m *moduleContext) ModuleName() string {
|
|
return m.info.properties.Name
|
|
}
|
|
|
|
func (m *moduleContext) ModuleDir() string {
|
|
return filepath.Dir(m.info.relBlueprintFile)
|
|
}
|
|
|
|
func (m *moduleContext) Config() Config {
|
|
return m.config
|
|
}
|
|
|
|
func (m *moduleContext) ModuleErrorf(format string, args ...interface{}) {
|
|
m.errs = append(m.errs, &Error{
|
|
Err: fmt.Errorf(format, args...),
|
|
Pos: m.info.pos,
|
|
})
|
|
}
|
|
|
|
func (m *moduleContext) PropertyErrorf(property, format string,
|
|
args ...interface{}) {
|
|
|
|
pos, ok := m.info.propertyPos[property]
|
|
if !ok {
|
|
panic(fmt.Errorf("property %q was not set for this module", property))
|
|
}
|
|
|
|
m.errs = append(m.errs, &Error{
|
|
Err: fmt.Errorf(format, args...),
|
|
Pos: pos,
|
|
})
|
|
}
|
|
|
|
func (m *moduleContext) Variable(name, value string) {
|
|
v, err := m.scope.AddLocalVariable(name, value)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
m.actionDefs.variables = append(m.actionDefs.variables, v)
|
|
}
|
|
|
|
func (m *moduleContext) Rule(name string, params RuleParams) Rule {
|
|
// TODO: Verify that params.Pool is accessible in this module's scope.
|
|
|
|
r, err := m.scope.AddLocalRule(name, ¶ms)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
m.actionDefs.rules = append(m.actionDefs.rules, r)
|
|
|
|
return r
|
|
}
|
|
|
|
func (m *moduleContext) Build(params BuildParams) {
|
|
// TODO: Verify that params.Rule is accessible in this module's scope.
|
|
|
|
def, err := parseBuildParams(m.scope, ¶ms)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
m.actionDefs.buildDefs = append(m.actionDefs.buildDefs, def)
|
|
}
|
|
|
|
func (m *moduleContext) VisitDepsDepthFirst(visit func(Module)) {
|
|
m.context.visitDepsDepthFirst(m.module, visit)
|
|
}
|
|
|
|
func (m *moduleContext) VisitDepsDepthFirstIf(pred func(Module) bool,
|
|
visit func(Module)) {
|
|
|
|
m.context.visitDepsDepthFirstIf(m.module, pred, visit)
|
|
}
|