aboutsummaryrefslogtreecommitdiffstats
path: root/bootstrap/command.go
diff options
context:
space:
mode:
authorColin Cross <ccross@google.com>2015-01-23 13:38:48 -0800
committerColin Cross <ccross@google.com>2015-01-23 14:23:27 -0800
commit3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2 (patch)
tree2599d6ac3c3810a41a87a709a004fc1fab4a7b74 /bootstrap/command.go
parent6bb4af9e208ea9769ae52933e8d9f42a4e75938e (diff)
downloadandroid_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.go149
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)
+}