Make it possible to call Blueprint from Go.
In addition to the command line interface, a new struct is created that holds all the information Blueprint needs to do its job. Test: Presubmits. Change-Id: I0d6c924e09e069b3c1ae2000722efb52fd561e79
This commit is contained in:
parent
5353744f1d
commit
7ea1c168fe
5 changed files with 117 additions and 96 deletions
|
@ -749,9 +749,11 @@ func (s *singleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
|
|||
filepath.Base(s.config.topLevelBlueprintsFile))
|
||||
ctx.SetNinjaBuildDir(pctx, "${ninjaBuildDir}")
|
||||
|
||||
buildDir := ctx.Config().(BootstrapConfig).BuildDir()
|
||||
|
||||
if s.config.stage == StagePrimary {
|
||||
mainNinjaFile := filepath.Join("$buildDir", "build.ninja")
|
||||
primaryBuilderNinjaGlobFile := absolutePath(filepath.Join(BuildDir, bootstrapSubDir, "build-globs.ninja"))
|
||||
primaryBuilderNinjaGlobFile := absolutePath(filepath.Join(buildDir, bootstrapSubDir, "build-globs.ninja"))
|
||||
|
||||
if _, err := os.Stat(primaryBuilderNinjaGlobFile); os.IsNotExist(err) {
|
||||
err = ioutil.WriteFile(primaryBuilderNinjaGlobFile, nil, 0666)
|
||||
|
|
|
@ -31,41 +31,58 @@ import (
|
|||
"github.com/google/blueprint/deptools"
|
||||
)
|
||||
|
||||
var (
|
||||
outFile string
|
||||
globFile string
|
||||
depFile string
|
||||
docFile string
|
||||
cpuprofile string
|
||||
memprofile string
|
||||
traceFile string
|
||||
runGoTests bool
|
||||
useValidations bool
|
||||
noGC bool
|
||||
emptyNinjaFile bool
|
||||
absSrcDir string
|
||||
|
||||
type Args struct {
|
||||
OutFile string
|
||||
GlobFile string
|
||||
DepFile string
|
||||
DocFile string
|
||||
Cpuprofile string
|
||||
Memprofile string
|
||||
TraceFile string
|
||||
RunGoTests bool
|
||||
UseValidations bool
|
||||
NoGC bool
|
||||
EmptyNinjaFile bool
|
||||
BuildDir string
|
||||
ModuleListFile string
|
||||
NinjaBuildDir string
|
||||
SrcDir string
|
||||
TopFile string
|
||||
}
|
||||
|
||||
var (
|
||||
cmdline Args
|
||||
absSrcDir string
|
||||
)
|
||||
|
||||
// Returns the build dir as parsed from the command line. This is necessary
|
||||
// because even though these flags are defined here, soong_build accesses them.
|
||||
// The plan is to move these flags to soong_build.
|
||||
func CmdlineBuildDir() string {
|
||||
return cmdline.BuildDir
|
||||
}
|
||||
|
||||
// Returns the module list file as parsed from the command line. This is necessary
|
||||
// because even though these flags are defined here, soong_build accesses them.
|
||||
// The plan is to move these flags to soong_build.
|
||||
func CmdlineModuleListFile() string {
|
||||
return cmdline.ModuleListFile
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&outFile, "o", "build.ninja", "the Ninja file to output")
|
||||
flag.StringVar(&globFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output")
|
||||
flag.StringVar(&BuildDir, "b", ".", "the build output directory")
|
||||
flag.StringVar(&NinjaBuildDir, "n", "", "the ninja builddir directory")
|
||||
flag.StringVar(&depFile, "d", "", "the dependency file to output")
|
||||
flag.StringVar(&docFile, "docs", "", "build documentation file to output")
|
||||
flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file")
|
||||
flag.StringVar(&traceFile, "trace", "", "write trace to file")
|
||||
flag.StringVar(&memprofile, "memprofile", "", "write memory profile to file")
|
||||
flag.BoolVar(&noGC, "nogc", false, "turn off GC for debugging")
|
||||
flag.BoolVar(&runGoTests, "t", false, "build and run go tests during bootstrap")
|
||||
flag.BoolVar(&useValidations, "use-validations", false, "use validations to depend on go tests")
|
||||
flag.StringVar(&ModuleListFile, "l", "", "file that lists filepaths to parse")
|
||||
flag.BoolVar(&emptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
|
||||
flag.StringVar(&cmdline.OutFile, "o", "build.ninja", "the Ninja file to output")
|
||||
flag.StringVar(&cmdline.GlobFile, "globFile", "build-globs.ninja", "the Ninja file of globs to output")
|
||||
flag.StringVar(&cmdline.BuildDir, "b", ".", "the build output directory")
|
||||
flag.StringVar(&cmdline.NinjaBuildDir, "n", "", "the ninja builddir directory")
|
||||
flag.StringVar(&cmdline.DepFile, "d", "", "the dependency file to output")
|
||||
flag.StringVar(&cmdline.DocFile, "docs", "", "build documentation file to output")
|
||||
flag.StringVar(&cmdline.Cpuprofile, "cpuprofile", "", "write cpu profile to file")
|
||||
flag.StringVar(&cmdline.TraceFile, "trace", "", "write trace to file")
|
||||
flag.StringVar(&cmdline.Memprofile, "memprofile", "", "write memory profile to file")
|
||||
flag.BoolVar(&cmdline.NoGC, "nogc", false, "turn off GC for debugging")
|
||||
flag.BoolVar(&cmdline.RunGoTests, "t", false, "build and run go tests during bootstrap")
|
||||
flag.BoolVar(&cmdline.UseValidations, "use-validations", false, "use validations to depend on go tests")
|
||||
flag.StringVar(&cmdline.ModuleListFile, "l", "", "file that lists filepaths to parse")
|
||||
flag.BoolVar(&cmdline.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
|
||||
}
|
||||
|
||||
func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...string) {
|
||||
|
@ -73,16 +90,25 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
flag.Parse()
|
||||
}
|
||||
|
||||
if flag.NArg() != 1 {
|
||||
fatalf("no Blueprints file specified")
|
||||
}
|
||||
|
||||
cmdline.TopFile = flag.Arg(0)
|
||||
RunBlueprint(cmdline, ctx, config, extraNinjaFileDeps...)
|
||||
}
|
||||
|
||||
func RunBlueprint(args Args, ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...string) {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
if noGC {
|
||||
if args.NoGC {
|
||||
debug.SetGCPercent(-1)
|
||||
}
|
||||
|
||||
absSrcDir = ctx.SrcDir()
|
||||
|
||||
if cpuprofile != "" {
|
||||
f, err := os.Create(absolutePath(cpuprofile))
|
||||
if args.Cpuprofile != "" {
|
||||
f, err := os.Create(absolutePath(args.Cpuprofile))
|
||||
if err != nil {
|
||||
fatalf("error opening cpuprofile: %s", err)
|
||||
}
|
||||
|
@ -91,8 +117,8 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
if traceFile != "" {
|
||||
f, err := os.Create(absolutePath(traceFile))
|
||||
if args.TraceFile != "" {
|
||||
f, err := os.Create(absolutePath(args.TraceFile))
|
||||
if err != nil {
|
||||
fatalf("error opening trace: %s", err)
|
||||
}
|
||||
|
@ -101,25 +127,20 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
defer trace.Stop()
|
||||
}
|
||||
|
||||
if flag.NArg() != 1 {
|
||||
fatalf("no Blueprints file specified")
|
||||
}
|
||||
srcDir := filepath.Dir(args.TopFile)
|
||||
|
||||
SrcDir = filepath.Dir(flag.Arg(0))
|
||||
if ModuleListFile != "" {
|
||||
ctx.SetModuleListFile(ModuleListFile)
|
||||
extraNinjaFileDeps = append(extraNinjaFileDeps, ModuleListFile)
|
||||
if args.ModuleListFile != "" {
|
||||
ctx.SetModuleListFile(args.ModuleListFile)
|
||||
extraNinjaFileDeps = append(extraNinjaFileDeps, args.ModuleListFile)
|
||||
} else {
|
||||
fatalf("-l <moduleListFile> is required and must be nonempty")
|
||||
}
|
||||
filesToParse, err := ctx.ListModulePaths(SrcDir)
|
||||
filesToParse, err := ctx.ListModulePaths(srcDir)
|
||||
if err != nil {
|
||||
fatalf("could not enumerate files: %v\n", err.Error())
|
||||
}
|
||||
|
||||
if NinjaBuildDir == "" {
|
||||
NinjaBuildDir = BuildDir
|
||||
}
|
||||
buildDir := args.BuildDir
|
||||
|
||||
stage := StageMain
|
||||
if c, ok := config.(interface{ GeneratingPrimaryBuilder() bool }); ok {
|
||||
|
@ -131,11 +152,11 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
bootstrapConfig := &Config{
|
||||
stage: stage,
|
||||
|
||||
topLevelBlueprintsFile: flag.Arg(0),
|
||||
emptyNinjaFile: emptyNinjaFile,
|
||||
runGoTests: runGoTests,
|
||||
useValidations: useValidations,
|
||||
moduleListFile: ModuleListFile,
|
||||
topLevelBlueprintsFile: args.TopFile,
|
||||
emptyNinjaFile: args.EmptyNinjaFile,
|
||||
runGoTests: args.RunGoTests,
|
||||
useValidations: args.UseValidations,
|
||||
moduleListFile: args.ModuleListFile,
|
||||
}
|
||||
|
||||
ctx.RegisterBottomUpMutator("bootstrap_plugin_deps", pluginDeps)
|
||||
|
@ -160,8 +181,8 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
}
|
||||
deps = append(deps, extraDeps...)
|
||||
|
||||
if docFile != "" {
|
||||
err := writeDocs(ctx, config, absolutePath(docFile))
|
||||
if args.DocFile != "" {
|
||||
err := writeDocs(ctx, config, absolutePath(args.DocFile))
|
||||
if err != nil {
|
||||
fatalErrors([]error{err})
|
||||
}
|
||||
|
@ -191,14 +212,14 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
var f *os.File
|
||||
var buf *bufio.Writer
|
||||
|
||||
if emptyNinjaFile {
|
||||
if err := ioutil.WriteFile(absolutePath(outFile), []byte(nil), outFilePermissions); err != nil {
|
||||
if args.EmptyNinjaFile {
|
||||
if err := ioutil.WriteFile(absolutePath(args.OutFile), []byte(nil), outFilePermissions); err != nil {
|
||||
fatalf("error writing empty Ninja file: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if stage != StageMain || !emptyNinjaFile {
|
||||
f, err = os.OpenFile(absolutePath(outFile), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, outFilePermissions)
|
||||
if stage != StageMain || !args.EmptyNinjaFile {
|
||||
f, err = os.OpenFile(absolutePath(args.OutFile), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, outFilePermissions)
|
||||
if err != nil {
|
||||
fatalf("error opening Ninja file: %s", err)
|
||||
}
|
||||
|
@ -208,20 +229,20 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
out = ioutil.Discard.(io.StringWriter)
|
||||
}
|
||||
|
||||
if globFile != "" {
|
||||
if args.GlobFile != "" {
|
||||
buffer, errs := generateGlobNinjaFile(config, ctx.Globs)
|
||||
if len(errs) > 0 {
|
||||
fatalErrors(errs)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(absolutePath(globFile), buffer, outFilePermissions)
|
||||
err = ioutil.WriteFile(absolutePath(args.GlobFile), buffer, outFilePermissions)
|
||||
if err != nil {
|
||||
fatalf("error writing %s: %s", globFile, err)
|
||||
fatalf("error writing %s: %s", args.GlobFile, err)
|
||||
}
|
||||
}
|
||||
|
||||
if depFile != "" {
|
||||
err := deptools.WriteDepFile(absolutePath(depFile), outFile, deps)
|
||||
if args.DepFile != "" {
|
||||
err := deptools.WriteDepFile(absolutePath(args.DepFile), args.OutFile, deps)
|
||||
if err != nil {
|
||||
fatalf("error writing depfile: %s", err)
|
||||
}
|
||||
|
@ -247,15 +268,15 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
}
|
||||
|
||||
if c, ok := config.(ConfigRemoveAbandonedFilesUnder); ok {
|
||||
under, except := c.RemoveAbandonedFilesUnder()
|
||||
err := removeAbandonedFilesUnder(ctx, SrcDir, BuildDir, under, except)
|
||||
under, except := c.RemoveAbandonedFilesUnder(buildDir)
|
||||
err := removeAbandonedFilesUnder(ctx, srcDir, buildDir, under, except)
|
||||
if err != nil {
|
||||
fatalf("error removing abandoned files: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if memprofile != "" {
|
||||
f, err := os.Create(absolutePath(memprofile))
|
||||
if args.Memprofile != "" {
|
||||
f, err := os.Create(absolutePath(args.Memprofile))
|
||||
if err != nil {
|
||||
fatalf("error opening memprofile: %s", err)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package bootstrap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
@ -23,25 +24,30 @@ import (
|
|||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
func bootstrapVariable(name string, value func() string) blueprint.Variable {
|
||||
func bootstrapVariable(name string, value func(BootstrapConfig) string) blueprint.Variable {
|
||||
return pctx.VariableFunc(name, func(config interface{}) (string, error) {
|
||||
return value(), nil
|
||||
c, ok := config.(BootstrapConfig)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Bootstrap rules were passed a configuration that does not include theirs, config=%q",
|
||||
config))
|
||||
}
|
||||
return value(c), nil
|
||||
})
|
||||
}
|
||||
|
||||
var (
|
||||
// These variables are the only configuration needed by the bootstrap
|
||||
// modules.
|
||||
srcDir = bootstrapVariable("srcDir", func() string {
|
||||
return SrcDir
|
||||
srcDirVariable = bootstrapVariable("srcDir", func(c BootstrapConfig) string {
|
||||
return c.SrcDir()
|
||||
})
|
||||
buildDir = bootstrapVariable("buildDir", func() string {
|
||||
return BuildDir
|
||||
buildDirVariable = bootstrapVariable("buildDir", func(c BootstrapConfig) string {
|
||||
return c.BuildDir()
|
||||
})
|
||||
ninjaBuildDir = bootstrapVariable("ninjaBuildDir", func() string {
|
||||
return NinjaBuildDir
|
||||
ninjaBuildDirVariable = bootstrapVariable("ninjaBuildDir", func(c BootstrapConfig) string {
|
||||
return c.NinjaBuildDir()
|
||||
})
|
||||
goRoot = bootstrapVariable("goRoot", func() string {
|
||||
goRootVariable = bootstrapVariable("goRoot", func(c BootstrapConfig) string {
|
||||
goroot := runtime.GOROOT()
|
||||
// Prefer to omit absolute paths from the ninja file
|
||||
if cwd, err := os.Getwd(); err == nil {
|
||||
|
@ -53,10 +59,10 @@ var (
|
|||
}
|
||||
return goroot
|
||||
})
|
||||
compileCmd = bootstrapVariable("compileCmd", func() string {
|
||||
compileCmdVariable = bootstrapVariable("compileCmd", func(c BootstrapConfig) string {
|
||||
return "$goRoot/pkg/tool/" + runtime.GOOS + "_" + runtime.GOARCH + "/compile"
|
||||
})
|
||||
linkCmd = bootstrapVariable("linkCmd", func() string {
|
||||
linkCmdVariable = bootstrapVariable("linkCmd", func(c BootstrapConfig) string {
|
||||
return "$goRoot/pkg/tool/" + runtime.GOOS + "_" + runtime.GOARCH + "/link"
|
||||
})
|
||||
)
|
||||
|
@ -78,7 +84,7 @@ type ConfigRemoveAbandonedFilesUnder interface {
|
|||
// - a slice of path prefixes that will be cleaned of files that are no
|
||||
// longer active targets, but are listed in the .ninja_log.
|
||||
// - a slice of paths that are exempt from cleaning
|
||||
RemoveAbandonedFilesUnder() (under, except []string)
|
||||
RemoveAbandonedFilesUnder(buildDir string) (under, except []string)
|
||||
}
|
||||
|
||||
type ConfigBlueprintToolLocation interface {
|
||||
|
|
|
@ -122,7 +122,7 @@ func globSingletonFactory(ctx *blueprint.Context) func() blueprint.Singleton {
|
|||
|
||||
func (s *globSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
|
||||
for _, g := range s.globLister() {
|
||||
fileListFile := filepath.Join(BuildDir, ".glob", g.Name)
|
||||
fileListFile := filepath.Join(ctx.Config().(BootstrapConfig).BuildDir(), ".glob", g.Name)
|
||||
|
||||
if s.writeRule {
|
||||
// We need to write the file list here so that it has an older modified date
|
||||
|
|
|
@ -30,29 +30,22 @@ func init() {
|
|||
}
|
||||
|
||||
type Config struct {
|
||||
buildDir string
|
||||
ninjaBuildDir string
|
||||
generatingPrimaryBuilder bool
|
||||
}
|
||||
|
||||
func (c Config) GeneratingPrimaryBuilder() bool {
|
||||
return true
|
||||
return c.generatingPrimaryBuilder
|
||||
}
|
||||
|
||||
func (c Config) SrcDir() string {
|
||||
return "."
|
||||
return bootstrap.CmdlineBuildDir()
|
||||
}
|
||||
|
||||
func (c Config) BuildDir() string {
|
||||
return c.buildDir
|
||||
}
|
||||
|
||||
func (c Config) NinjaBuildDir() string {
|
||||
return c.ninjaBuildDir
|
||||
}
|
||||
|
||||
func (c Config) RemoveAbandonedFilesUnder() (under, exempt []string) {
|
||||
under = []string{filepath.Join(bootstrap.BuildDir, ".bootstrap")}
|
||||
exempt = []string{filepath.Join(bootstrap.BuildDir, ".bootstrap", "build.ninja")}
|
||||
func (c Config) RemoveAbandonedFilesUnder(buildDir string) (under, exempt []string) {
|
||||
if c.generatingPrimaryBuilder {
|
||||
under = []string{filepath.Join(buildDir, ".bootstrap")}
|
||||
exempt = []string{filepath.Join(buildDir, ".bootstrap", "build.ninja")}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -65,8 +58,7 @@ func main() {
|
|||
}
|
||||
|
||||
config := Config{
|
||||
buildDir: bootstrap.BuildDir,
|
||||
ninjaBuildDir: bootstrap.NinjaBuildDir,
|
||||
generatingPrimaryBuilder: !runAsPrimaryBuilder,
|
||||
}
|
||||
|
||||
bootstrap.Main(ctx, config)
|
||||
|
|
Loading…
Reference in a new issue