Merge pull request #100 from danw/blueprint_tools
Add blueprint_go_binary for user-run tools
diff --git a/Blueprints b/Blueprints
index 84345a3..74db5c1 100644
--- a/Blueprints
+++ b/Blueprints
@@ -117,13 +117,13 @@
srcs = ["bootstrap/minibp/main.go"],
)
-bootstrap_go_binary(
+blueprint_go_binary(
name = "bpfmt",
deps = ["blueprint-parser"],
srcs = ["bpfmt/bpfmt.go"],
)
-bootstrap_go_binary(
+blueprint_go_binary(
name = "bpmodify",
deps = ["blueprint-parser"],
srcs = ["bpmodify/bpmodify.go"],
diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go
index c05f799..c4ec3cf 100644
--- a/bootstrap/bootstrap.go
+++ b/bootstrap/bootstrap.go
@@ -118,6 +118,12 @@
minibpFile = filepath.Join("$BinDir", "minibp")
docsDir = filepath.Join(bootstrapDir, "docs")
+ toolDir = pctx.VariableFunc("ToolDir", func(config interface{}) (string, error) {
+ if c, ok := config.(ConfigBlueprintToolLocation); ok {
+ return c.BlueprintToolLocation(), nil
+ }
+ return filepath.Join("$buildDir", "bin"), nil
+ })
bootstrapDir = filepath.Join("$buildDir", bootstrapSubDir)
miniBootstrapDir = filepath.Join("$buildDir", miniBootstrapSubDir)
@@ -129,15 +135,15 @@
}
func propagateStageBootstrap(mctx blueprint.TopDownMutatorContext) {
- if mod, ok := mctx.Module().(bootstrapGoCore); !ok || mod.BuildStage() != StageBootstrap {
- return
- }
+ if mod, ok := mctx.Module().(bootstrapGoCore); ok {
+ stage := mod.BuildStage()
- mctx.VisitDirectDeps(func(mod blueprint.Module) {
- if m, ok := mod.(bootstrapGoCore); ok {
- m.SetBuildStage(StageBootstrap)
- }
- })
+ mctx.VisitDirectDeps(func(mod blueprint.Module) {
+ if m, ok := mod.(bootstrapGoCore); ok && m.BuildStage() > stage {
+ m.SetBuildStage(stage)
+ }
+ })
+ }
}
func pluginDeps(ctx blueprint.BottomUpMutatorContext) {
@@ -226,7 +232,7 @@
module := &goPackage{
config: config,
}
- module.properties.BuildStage = StagePrimary
+ module.properties.BuildStage = StageMain
return module, []interface{}{&module.properties}
}
}
@@ -312,7 +318,7 @@
buildGoPackage(ctx, g.pkgRoot, g.properties.PkgPath, g.archiveFile,
g.properties.Srcs, genSrcs, deps)
- } else if g.config.stage != StageBootstrap {
+ } else if g.config.stage > g.BuildStage() {
if len(g.properties.TestSrcs) > 0 && g.config.runGoTests {
phonyGoTarget(ctx, g.testArchiveFile, g.properties.TestSrcs, nil, nil)
}
@@ -360,13 +366,20 @@
g.properties.BuildStage = buildStage
}
+func (g *goBinary) InstallPath() string {
+ if g.BuildStage() == StageMain {
+ return "$ToolDir"
+ }
+ return "$BinDir"
+}
+
func (g *goBinary) GenerateBuildActions(ctx blueprint.ModuleContext) {
var (
name = ctx.ModuleName()
objDir = moduleObjDir(ctx)
archiveFile = filepath.Join(objDir, name+".a")
aoutFile = filepath.Join(objDir, "a.out")
- binaryFile = filepath.Join("$BinDir", name)
+ binaryFile = filepath.Join(g.InstallPath(), name)
hasPlugins = false
pluginSrc = ""
genSrcs = []string{}
@@ -427,7 +440,7 @@
Outputs: []string{binaryFile},
Inputs: []string{aoutFile},
})
- } else if g.config.stage != StageBootstrap {
+ } else if g.config.stage > g.BuildStage() {
if len(g.properties.TestSrcs) > 0 && g.config.runGoTests {
phonyGoTarget(ctx, g.testArchiveFile, g.properties.TestSrcs, nil, nil)
}
@@ -637,16 +650,21 @@
var rebootstrapDeps []string
// primaryRebootstrapDeps contains modules that will be built in StagePrimary
var primaryRebootstrapDeps []string
+ // blueprintTools contains blueprint go binaries that will be built in StageMain
+ var blueprintTools []string
ctx.VisitAllModulesIf(isBootstrapBinaryModule,
func(module blueprint.Module) {
binaryModule := module.(*goBinary)
binaryModuleName := ctx.ModuleName(binaryModule)
- binaryModulePath := filepath.Join("$BinDir", binaryModuleName)
+ installPath := filepath.Join(binaryModule.InstallPath(), binaryModuleName)
- if binaryModule.BuildStage() == StageBootstrap {
- rebootstrapDeps = append(rebootstrapDeps, binaryModulePath)
- } else {
- primaryRebootstrapDeps = append(primaryRebootstrapDeps, binaryModulePath)
+ switch binaryModule.BuildStage() {
+ case StageBootstrap:
+ rebootstrapDeps = append(rebootstrapDeps, installPath)
+ case StagePrimary:
+ primaryRebootstrapDeps = append(primaryRebootstrapDeps, installPath)
+ case StageMain:
+ blueprintTools = append(blueprintTools, installPath)
}
if binaryModule.properties.PrimaryBuilder {
primaryBuilders = append(primaryBuilders, binaryModule)
@@ -707,10 +725,13 @@
testModule := module.(goTestProducer)
target := testModule.GoTestTarget()
if target != "" {
- if testModule.BuildStage() == StageBootstrap {
+ switch testModule.BuildStage() {
+ case StageBootstrap:
rebootstrapDeps = append(rebootstrapDeps, target)
- } else {
+ case StagePrimary:
primaryRebootstrapDeps = append(primaryRebootstrapDeps, target)
+ case StageMain:
+ blueprintTools = append(blueprintTools, target)
}
}
})
@@ -961,6 +982,12 @@
Outputs: []string{finalMinibp},
})
}
+
+ ctx.Build(pctx, blueprint.BuildParams{
+ Rule: blueprint.Phony,
+ Outputs: []string{"blueprint_tools"},
+ Inputs: blueprintTools,
+ })
}
ctx.Build(pctx, blueprint.BuildParams{
diff --git a/bootstrap/command.go b/bootstrap/command.go
index 69b2271..2689a42 100644
--- a/bootstrap/command.go
+++ b/bootstrap/command.go
@@ -94,6 +94,7 @@
ctx.RegisterModuleType("bootstrap_go_package", newGoPackageModuleFactory(bootstrapConfig))
ctx.RegisterModuleType("bootstrap_core_go_binary", newGoBinaryModuleFactory(bootstrapConfig, StageBootstrap))
ctx.RegisterModuleType("bootstrap_go_binary", newGoBinaryModuleFactory(bootstrapConfig, StagePrimary))
+ ctx.RegisterModuleType("blueprint_go_binary", newGoBinaryModuleFactory(bootstrapConfig, StageMain))
ctx.RegisterTopDownMutator("bootstrap_stage", propagateStageBootstrap)
ctx.RegisterSingletonType("bootstrap", newSingletonFactory(bootstrapConfig))
diff --git a/bootstrap/config.go b/bootstrap/config.go
index 7730ce9..2e30718 100644
--- a/bootstrap/config.go
+++ b/bootstrap/config.go
@@ -44,6 +44,13 @@
RemoveAbandonedFiles() bool
}
+type ConfigBlueprintToolLocation interface {
+ // BlueprintToolLocation can return a path name to install blueprint tools
+ // designed for end users (bpfmt, bpmodify, and anything else using
+ // blueprint_go_binary).
+ BlueprintToolLocation() string
+}
+
type Stage int
const (