diff options
author | Colin Cross <ccross@google.com> | 2015-01-23 13:38:48 -0800 |
---|---|---|
committer | Colin Cross <ccross@google.com> | 2015-01-23 14:23:27 -0800 |
commit | 3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2 (patch) | |
tree | 2599d6ac3c3810a41a87a709a004fc1fab4a7b74 /bootstrap/command.go | |
parent | 6bb4af9e208ea9769ae52933e8d9f42a4e75938e (diff) | |
download | android_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.tar.gz android_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.tar.bz2 android_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.zip |
Move blueprint/* up a directory
Make integrating with go tools easier by putting the blueprint package
files in the top level directory of the git project instead of in a
subdirectory called blueprint.
Change-Id: I35c144c5fe7ddf34e478d0c47c50b2f6c92c2a03
Diffstat (limited to 'bootstrap/command.go')
-rw-r--r-- | bootstrap/command.go | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/bootstrap/command.go b/bootstrap/command.go new file mode 100644 index 0000000..2d3cd2f --- /dev/null +++ b/bootstrap/command.go @@ -0,0 +1,149 @@ +package bootstrap + +import ( + "blueprint" + "blueprint/deptools" + "bytes" + "flag" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "runtime/pprof" +) + +var ( + outFile string + depFile string + checkFile string + manifestFile string + cpuprofile string +) + +// topLevelBlueprintsFile is set by Main as a way to pass this information on to +// the bootstrap build manifest generators. This information was not passed via +// the config object so as to allow the caller of Main to use whatever Config +// object it wants. +var topLevelBlueprintsFile string + +func init() { + flag.StringVar(&outFile, "o", "build.ninja.in", "the Ninja file to output") + flag.StringVar(&depFile, "d", "", "the dependency file to output") + flag.StringVar(&checkFile, "c", "", "the existing file to check against") + flag.StringVar(&manifestFile, "m", "", "the bootstrap manifest file") + flag.StringVar(&cpuprofile, "cpuprofile", "", "write cpu profile to file") +} + +func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...string) { + if !flag.Parsed() { + flag.Parse() + } + + if cpuprofile != "" { + f, err := os.Create(cpuprofile) + if err != nil { + fatalf("error opening cpuprofile: %s", err) + } + pprof.StartCPUProfile(f) + defer f.Close() + defer pprof.StopCPUProfile() + } + + ctx.RegisterModuleType("bootstrap_go_package", newGoPackageModule) + ctx.RegisterModuleType("bootstrap_go_binary", newGoBinaryModule) + ctx.RegisterSingletonType("bootstrap", newSingleton) + + if flag.NArg() != 1 { + fatalf("no Blueprints file specified") + } + + topLevelBlueprintsFile = flag.Arg(0) + + deps, errs := ctx.ParseBlueprintsFiles(topLevelBlueprintsFile) + if len(errs) > 0 { + fatalErrors(errs) + } + + // Add extra ninja file dependencies + deps = append(deps, extraNinjaFileDeps...) + + extraDeps, errs := ctx.PrepareBuildActions(config) + if len(errs) > 0 { + fatalErrors(errs) + } + deps = append(deps, extraDeps...) + + buf := bytes.NewBuffer(nil) + err := ctx.WriteBuildFile(buf) + if err != nil { + fatalf("error generating Ninja file contents: %s", err) + } + + const outFilePermissions = 0666 + err = ioutil.WriteFile(outFile, buf.Bytes(), outFilePermissions) + if err != nil { + fatalf("error writing %s: %s", outFile, err) + } + + if checkFile != "" { + checkData, err := ioutil.ReadFile(checkFile) + if err != nil { + fatalf("error reading %s: %s", checkFile, err) + } + + matches := buf.Len() == len(checkData) + if matches { + for i, value := range buf.Bytes() { + if value != checkData[i] { + matches = false + break + } + } + } + + if matches { + // The new file content matches the check-file content, so we set + // the new file's mtime and atime to match that of the check-file. + checkFileInfo, err := os.Stat(checkFile) + if err != nil { + fatalf("error stat'ing %s: %s", checkFile, err) + } + + time := checkFileInfo.ModTime() + err = os.Chtimes(outFile, time, time) + if err != nil { + fatalf("error setting timestamps for %s: %s", outFile, err) + } + } + } + + if depFile != "" { + err := deptools.WriteDepFile(depFile, outFile, deps) + if err != nil { + fatalf("error writing depfile: %s", err) + } + } + + srcDir := filepath.Dir(topLevelBlueprintsFile) + err = removeAbandonedFiles(ctx, config, srcDir, manifestFile) + if err != nil { + fatalf("error removing abandoned files: %s", err) + } +} + +func fatalf(format string, args ...interface{}) { + fmt.Printf(format, args...) + os.Exit(1) +} + +func fatalErrors(errs []error) { + for _, err := range errs { + switch err.(type) { + case *blueprint.Error: + _, _ = fmt.Printf("%s\n", err.Error()) + default: + _, _ = fmt.Printf("internal error: %s\n", err) + } + } + os.Exit(1) +} |