Support a separate build directory

To provide a consistent __FILE__ behavior with cpp, we want to be able
to run with SRCDIR="." and the outputs be saved elsewhere. Other tools
within android also expect to be run from $TOP.

Change-Id: I572bce5c9086b0c3310b42065ae98cbf5a1c6399
diff --git a/bootstrap.bash b/bootstrap.bash
index ee5ddb7..d474cc4 100755
--- a/bootstrap.bash
+++ b/bootstrap.bash
@@ -11,6 +11,7 @@
 #
 #   BOOTSTRAP
 #   SRCDIR
+#   BUILDDIR
 #   BOOTSTRAP_MANIFEST
 #   GOROOT
 #   GOOS
@@ -36,6 +37,10 @@
 # the bootstrap script.
 [ -z "$SRCDIR" ] && SRCDIR=`dirname "${BOOTSTRAP}"`
 
+# BUILDDIR should be set to the path to store build results. By default, this
+# is the current directory, but it may be set to an absolute or relative path.
+[ -z "$BUILDDIR" ] && BUILDDIR=.
+
 # TOPNAME should be set to the name of the top-level Blueprints file
 [ -z "$TOPNAME" ] && TOPNAME="Blueprints"
 
@@ -64,8 +69,9 @@
 # Parse the command line flags.
 IN="$BOOTSTRAP_MANIFEST"
 REGEN_BOOTSTRAP_MANIFEST=false
-while getopts ":hi:rt" opt; do
+while getopts ":b:hi:rt" opt; do
     case $opt in
+        b) BUILDDIR="$OPTARG";;
         h)
             usage
             exit 1
@@ -88,20 +94,23 @@
 if [ $REGEN_BOOTSTRAP_MANIFEST = true ]; then
     # This assumes that the script is being run from a build output directory
     # that has been built in the past.
-    if [ -x .bootstrap/bin/minibp ]; then
+    if [ -x $BUILDDIR/.bootstrap/bin/minibp ]; then
         echo "Regenerating $BOOTSTRAP_MANIFEST"
-        ./.bootstrap/bin/minibp $EXTRA_ARGS -o $BOOTSTRAP_MANIFEST $SRCDIR/$TOPNAME
+        $BUILDDIR/.bootstrap/bin/minibp $EXTRA_ARGS -o $BOOTSTRAP_MANIFEST $SRCDIR/$TOPNAME
     else
-        echo "Executable minibp not found at .bootstrap/bin/minibp" >&2
+        echo "Executable minibp not found at $BUILDDIR/.bootstrap/bin/minibp" >&2
         exit 1
     fi
 fi
 
+mkdir -p $BUILDDIR
+
 sed -e "s|@@SrcDir@@|$SRCDIR|g"                        \
+    -e "s|@@BuildDir@@|$BUILDDIR|g"                    \
     -e "s|@@GoRoot@@|$GOROOT|g"                        \
     -e "s|@@GoOS@@|$GOOS|g"                            \
     -e "s|@@GoArch@@|$GOARCH|g"                        \
     -e "s|@@GoChar@@|$GOCHAR|g"                        \
     -e "s|@@Bootstrap@@|$BOOTSTRAP|g"                  \
     -e "s|@@BootstrapManifest@@|$BOOTSTRAP_MANIFEST|g" \
-    $IN > build.ninja
+    $IN > $BUILDDIR/build.ninja
diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go
index 8f31af2..77427c0 100644
--- a/bootstrap/bootstrap.go
+++ b/bootstrap/bootstrap.go
@@ -23,8 +23,8 @@
 	"github.com/google/blueprint/pathtools"
 )
 
-const bootstrapDir = ".bootstrap"
-const miniBootstrapDir = ".minibootstrap"
+const bootstrapDir = "$buildDir/.bootstrap"
+const miniBootstrapDir = "$buildDir/.minibootstrap"
 
 var (
 	pctx = blueprint.NewPackageContext("github.com/google/blueprint/bootstrap")
@@ -72,7 +72,7 @@
 
 	bootstrap = pctx.StaticRule("bootstrap",
 		blueprint.RuleParams{
-			Command:     "$bootstrapCmd -i $in",
+			Command:     "$bootstrapCmd -i $in -b $buildDir",
 			Description: "bootstrap $in",
 			Generator:   true,
 		})
@@ -621,7 +621,7 @@
 			blueprint.RuleParams{
 				Command: fmt.Sprintf("%s --build-primary $runTests -m $bootstrapManifest "+
 					"--timestamp $timestamp --timestampdep $timestampdep "+
-					"-d $outfile.d -o $outfile $in", minibpFile),
+					"-b $buildDir -d $outfile.d -o $outfile $in", minibpFile),
 				Description: "minibp $outfile",
 				Depfile:     "$outfile.d",
 			},
@@ -650,7 +650,7 @@
 		minibp := ctx.Rule(pctx, "minibp",
 			blueprint.RuleParams{
 				Command: fmt.Sprintf("%s $runTests -m $bootstrapManifest "+
-					"-d $out.d -o $out $in", minibpFile),
+					"-b $buildDir -d $out.d -o $out $in", minibpFile),
 				Description: "minibp $out",
 				Generator:   true,
 				Depfile:     "$out.d",
@@ -712,7 +712,7 @@
 			blueprint.RuleParams{
 				Command: fmt.Sprintf("%s %s -m $bootstrapManifest "+
 					"--timestamp $timestamp --timestampdep $timestampdep "+
-					"-d $outfile.d -o $outfile $in", primaryBuilderFile,
+					"-b $buildDir -d $outfile.d -o $outfile $in", primaryBuilderFile,
 					primaryBuilderExtraFlags),
 				Description: fmt.Sprintf("%s $outfile", primaryBuilderName),
 				Depfile:     "$outfile.d",
@@ -738,7 +738,7 @@
 		// a rebuild of the primary builder.
 		bigbpDocs := ctx.Rule(pctx, "bigbpDocs",
 			blueprint.RuleParams{
-				Command: fmt.Sprintf("%s %s --docs $out %s", primaryBuilderFile,
+				Command: fmt.Sprintf("%s %s -b $buildDir --docs $out %s", primaryBuilderFile,
 					primaryBuilderExtraFlags, topLevelBlueprints),
 				Description: fmt.Sprintf("%s docs $out", primaryBuilderName),
 			})
@@ -791,6 +791,8 @@
 		})
 
 	case StageMain:
+		ctx.SetBuildDir(pctx, "${buildDir}")
+
 		// We're generating a non-bootstrapper Ninja file, so we need to set it
 		// up to re-bootstrap if necessary. We do this by making build.ninja.in
 		// depend on the various Ninja files, the source build.ninja.in, and
@@ -842,7 +844,7 @@
 		if primaryBuilderName == "minibp" {
 			// This is a standalone Blueprint build, so we copy the minibp
 			// binary to the "bin" directory to make it easier to find.
-			finalMinibp := filepath.Join("bin", primaryBuilderName)
+			finalMinibp := filepath.Join("$buildDir", "bin", primaryBuilderName)
 			ctx.Build(pctx, blueprint.BuildParams{
 				Rule:    cp,
 				Inputs:  []string{primaryBuilderFile},
@@ -853,7 +855,7 @@
 
 	ctx.Build(pctx, blueprint.BuildParams{
 		Rule:      bootstrap,
-		Outputs:   []string{"build.ninja"},
+		Outputs:   []string{"$buildDir/build.ninja"},
 		Inputs:    []string{filepath.Join(bootstrapDir, "build.ninja.in")},
 		Implicits: []string{"$bootstrapCmd"},
 	})
diff --git a/bootstrap/cleanup.go b/bootstrap/cleanup.go
index dd698f4..1e1fc03 100644
--- a/bootstrap/cleanup.go
+++ b/bootstrap/cleanup.go
@@ -47,11 +47,12 @@
 
 	replacer := strings.NewReplacer(
 		"@@SrcDir@@", srcDir,
+		"@@BuildDir@@", BuildDir,
 		"@@BootstrapManifest@@", manifestFile)
 	targets := make(map[string]bool)
 	for target := range targetRules {
 		replacedTarget := replacer.Replace(target)
-		targets[replacedTarget] = true
+		targets[filepath.Clean(replacedTarget)] = true
 	}
 
 	filePaths, err := parseNinjaLog(buildDir)
diff --git a/bootstrap/command.go b/bootstrap/command.go
index 33c4227..63f07ec 100644
--- a/bootstrap/command.go
+++ b/bootstrap/command.go
@@ -37,10 +37,13 @@
 	docFile          string
 	cpuprofile       string
 	runGoTests       bool
+
+	BuildDir string
 )
 
 func init() {
 	flag.StringVar(&outFile, "o", "build.ninja.in", "the Ninja file to output")
+	flag.StringVar(&BuildDir, "b", ".", "the build output directory")
 	flag.StringVar(&depFile, "d", "", "the dependency file to output")
 	flag.StringVar(&timestampFile, "timestamp", "", "file to write before the output file")
 	flag.StringVar(&timestampDepFile, "timestampdep", "", "the dependency file for the timestamp file")
diff --git a/bootstrap/config.go b/bootstrap/config.go
index b236cc7..5f8b551 100644
--- a/bootstrap/config.go
+++ b/bootstrap/config.go
@@ -19,6 +19,7 @@
 	// modules.  They are always set to the variable name enclosed in "@@" so
 	// that their values can be easily replaced in the generated Ninja file.
 	srcDir            = pctx.StaticVariable("srcDir", "@@SrcDir@@")
+	buildDir          = pctx.StaticVariable("buildDir", "@@BuildDir@@")
 	goRoot            = pctx.StaticVariable("goRoot", "@@GoRoot@@")
 	goOS              = pctx.StaticVariable("goOS", "@@GoOS@@")
 	goArch            = pctx.StaticVariable("goArch", "@@GoArch@@")
diff --git a/build.ninja.in b/build.ninja.in
index 8839a0d..7ef5c56 100644
--- a/build.ninja.in
+++ b/build.ninja.in
@@ -9,13 +9,15 @@
 #
 ninja_required_version = 1.6.0
 
-g.bootstrap.BinDir = .bootstrap/bin
+g.bootstrap.buildDir = @@BuildDir@@
+
+g.bootstrap.BinDir = ${g.bootstrap.buildDir}/.bootstrap/bin
 
 g.bootstrap.bootstrapCmd = @@Bootstrap@@
 
 g.bootstrap.bootstrapManifest = @@BootstrapManifest@@
 
-g.bootstrap.chooseStageCmd = .bootstrap/bin/choosestage
+g.bootstrap.chooseStageCmd = ${g.bootstrap.buildDir}/.bootstrap/bin/choosestage
 
 g.bootstrap.goRoot = @@GoRoot@@
 
@@ -33,10 +35,10 @@
 
 g.bootstrap.srcDir = @@SrcDir@@
 
-builddir = .minibootstrap
+builddir = ${g.bootstrap.buildDir}/.minibootstrap
 
 rule g.bootstrap.bootstrap
-    command = ${g.bootstrap.bootstrapCmd} -i ${in}
+    command = ${g.bootstrap.bootstrapCmd} -i ${in} -b ${g.bootstrap.buildDir}
     description = bootstrap ${in}
     generator = true
 
@@ -63,21 +65,24 @@
 # Factory: github.com/google/blueprint/bootstrap.func·002
 # Defined: Blueprints:1:1
 
-build .bootstrap/blueprint/pkg/github.com/google/blueprint.a: g.bootstrap.gc $
-        ${g.bootstrap.srcDir}/context.go ${g.bootstrap.srcDir}/live_tracker.go $
-        ${g.bootstrap.srcDir}/mangle.go ${g.bootstrap.srcDir}/module_ctx.go $
+build $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
+        : g.bootstrap.gc ${g.bootstrap.srcDir}/context.go $
+        ${g.bootstrap.srcDir}/live_tracker.go ${g.bootstrap.srcDir}/mangle.go $
+        ${g.bootstrap.srcDir}/module_ctx.go $
         ${g.bootstrap.srcDir}/ninja_defs.go $
         ${g.bootstrap.srcDir}/ninja_strings.go $
         ${g.bootstrap.srcDir}/ninja_writer.go $
         ${g.bootstrap.srcDir}/package_ctx.go ${g.bootstrap.srcDir}/scope.go $
         ${g.bootstrap.srcDir}/singleton_ctx.go ${g.bootstrap.srcDir}/unpack.go $
         | ${g.bootstrap.gcCmd} $
-        .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
-        .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
-        .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
-    incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-proptools/pkg
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
     pkgPath = github.com/google/blueprint
-default .bootstrap/blueprint/pkg/github.com/google/blueprint.a
+default $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  blueprint-bootstrap
@@ -87,23 +92,23 @@
 # Defined: Blueprints:70:1
 
 build $
-        .bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $
         : g.bootstrap.gc ${g.bootstrap.srcDir}/bootstrap/bootstrap.go $
         ${g.bootstrap.srcDir}/bootstrap/cleanup.go $
         ${g.bootstrap.srcDir}/bootstrap/command.go $
         ${g.bootstrap.srcDir}/bootstrap/config.go $
         ${g.bootstrap.srcDir}/bootstrap/doc.go $
         ${g.bootstrap.srcDir}/bootstrap/writedocs.go | ${g.bootstrap.gcCmd} $
-        .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
-        .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
-        .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
-        .bootstrap/blueprint/pkg/github.com/google/blueprint.a $
-        .bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
-        .bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
-    incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg -I .bootstrap/blueprint-deptools/pkg -I .bootstrap/blueprint-bootstrap-bpdoc/pkg
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg
     pkgPath = github.com/google/blueprint/bootstrap
 default $
-        .bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  blueprint-bootstrap-bpdoc
@@ -113,17 +118,17 @@
 # Defined: Blueprints:89:1
 
 build $
-        .bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
         : g.bootstrap.gc ${g.bootstrap.srcDir}/bootstrap/bpdoc/bpdoc.go | $
         ${g.bootstrap.gcCmd} $
-        .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
-        .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
-        .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
-        .bootstrap/blueprint/pkg/github.com/google/blueprint.a
-    incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg
     pkgPath = github.com/google/blueprint/bootstrap/bpdoc
 default $
-        .bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  blueprint-deptools
@@ -132,12 +137,13 @@
 # Factory: github.com/google/blueprint/bootstrap.func·002
 # Defined: Blueprints:46:1
 
-build .bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
+build $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         : g.bootstrap.gc ${g.bootstrap.srcDir}/deptools/depfile.go | $
         ${g.bootstrap.gcCmd}
     pkgPath = github.com/google/blueprint/deptools
 default $
-        .bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  blueprint-parser
@@ -146,13 +152,15 @@
 # Factory: github.com/google/blueprint/bootstrap.func·002
 # Defined: Blueprints:31:1
 
-build .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a: $
-        g.bootstrap.gc ${g.bootstrap.srcDir}/parser/modify.go $
+build $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        : g.bootstrap.gc ${g.bootstrap.srcDir}/parser/modify.go $
         ${g.bootstrap.srcDir}/parser/parser.go $
         ${g.bootstrap.srcDir}/parser/printer.go $
         ${g.bootstrap.srcDir}/parser/sort.go | ${g.bootstrap.gcCmd}
     pkgPath = github.com/google/blueprint/parser
-default .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a
+default $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  blueprint-pathtools
@@ -162,12 +170,12 @@
 # Defined: Blueprints:52:1
 
 build $
-        .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
         : g.bootstrap.gc ${g.bootstrap.srcDir}/pathtools/lists.go $
         ${g.bootstrap.srcDir}/pathtools/glob.go | ${g.bootstrap.gcCmd}
     pkgPath = github.com/google/blueprint/pathtools
 default $
-        .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  blueprint-proptools
@@ -177,12 +185,12 @@
 # Defined: Blueprints:64:1
 
 build $
-        .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
         : g.bootstrap.gc ${g.bootstrap.srcDir}/proptools/proptools.go | $
         ${g.bootstrap.gcCmd}
     pkgPath = github.com/google/blueprint/proptools
 default $
-        .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  choosestage
@@ -191,17 +199,19 @@
 # Factory: github.com/google/blueprint/bootstrap.func·003
 # Defined: Blueprints:127:1
 
-build .bootstrap/choosestage/obj/choosestage.a: g.bootstrap.gc $
-        ${g.bootstrap.srcDir}/choosestage/choosestage.go | $
+build ${g.bootstrap.buildDir}/.bootstrap/choosestage/obj/choosestage.a: $
+        g.bootstrap.gc ${g.bootstrap.srcDir}/choosestage/choosestage.go | $
         ${g.bootstrap.gcCmd}
     pkgPath = choosestage
-default .bootstrap/choosestage/obj/choosestage.a
+default ${g.bootstrap.buildDir}/.bootstrap/choosestage/obj/choosestage.a
 
-build .bootstrap/choosestage/obj/a.out: g.bootstrap.link $
-        .bootstrap/choosestage/obj/choosestage.a | ${g.bootstrap.linkCmd}
-default .bootstrap/choosestage/obj/a.out
+build ${g.bootstrap.buildDir}/.bootstrap/choosestage/obj/a.out: $
+        g.bootstrap.link $
+        ${g.bootstrap.buildDir}/.bootstrap/choosestage/obj/choosestage.a | $
+        ${g.bootstrap.linkCmd}
+default ${g.bootstrap.buildDir}/.bootstrap/choosestage/obj/a.out
 build ${g.bootstrap.BinDir}/choosestage: g.bootstrap.cp $
-        .bootstrap/choosestage/obj/a.out
+        ${g.bootstrap.buildDir}/.bootstrap/choosestage/obj/a.out
 default ${g.bootstrap.BinDir}/choosestage
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -211,16 +221,19 @@
 # Factory: github.com/google/blueprint/bootstrap.func·003
 # Defined: Blueprints:122:1
 
-build .bootstrap/gotestmain/obj/gotestmain.a: g.bootstrap.gc $
-        ${g.bootstrap.srcDir}/gotestmain/gotestmain.go | ${g.bootstrap.gcCmd}
+build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a: $
+        g.bootstrap.gc ${g.bootstrap.srcDir}/gotestmain/gotestmain.go | $
+        ${g.bootstrap.gcCmd}
     pkgPath = gotestmain
-default .bootstrap/gotestmain/obj/gotestmain.a
+default ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a
 
-build .bootstrap/gotestmain/obj/a.out: g.bootstrap.link $
-        .bootstrap/gotestmain/obj/gotestmain.a | ${g.bootstrap.linkCmd}
-default .bootstrap/gotestmain/obj/a.out
+build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/a.out: $
+        g.bootstrap.link $
+        ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a | $
+        ${g.bootstrap.linkCmd}
+default ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/a.out
 build ${g.bootstrap.BinDir}/gotestmain: g.bootstrap.cp $
-        .bootstrap/gotestmain/obj/a.out
+        ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/a.out
 default ${g.bootstrap.BinDir}/gotestmain
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -230,25 +243,27 @@
 # Factory: github.com/google/blueprint/bootstrap.func·003
 # Defined: Blueprints:101:1
 
-build .bootstrap/minibp/obj/minibp.a: g.bootstrap.gc $
+build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a: g.bootstrap.gc $
         ${g.bootstrap.srcDir}/bootstrap/minibp/main.go | ${g.bootstrap.gcCmd} $
-        .bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
-        .bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
-        .bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
-        .bootstrap/blueprint/pkg/github.com/google/blueprint.a $
-        .bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
-        .bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
-        .bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
-    incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg -I .bootstrap/blueprint-deptools/pkg -I .bootstrap/blueprint-bootstrap-bpdoc/pkg -I .bootstrap/blueprint-bootstrap/pkg
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg
     pkgPath = minibp
-default .bootstrap/minibp/obj/minibp.a
+default ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a
 
-build .bootstrap/minibp/obj/a.out: g.bootstrap.link $
-        .bootstrap/minibp/obj/minibp.a | ${g.bootstrap.linkCmd}
-    libDirFlags = -L .bootstrap/blueprint-parser/pkg -L .bootstrap/blueprint-pathtools/pkg -L .bootstrap/blueprint-proptools/pkg -L .bootstrap/blueprint/pkg -L .bootstrap/blueprint-deptools/pkg -L .bootstrap/blueprint-bootstrap-bpdoc/pkg -L .bootstrap/blueprint-bootstrap/pkg
-default .bootstrap/minibp/obj/a.out
+build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out: g.bootstrap.link $
+        ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a | $
+        ${g.bootstrap.linkCmd}
+    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg
+default ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out
 
-build ${g.bootstrap.BinDir}/minibp: g.bootstrap.cp .bootstrap/minibp/obj/a.out
+build ${g.bootstrap.BinDir}/minibp: g.bootstrap.cp $
+        ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out
 default ${g.bootstrap.BinDir}/minibp
 
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -256,39 +271,44 @@
 # Factory:   github.com/google/blueprint/bootstrap.func·008
 
 rule s.bootstrap.primarybp
-    command = ${g.bootstrap.BinDir}/minibp --build-primary ${runTests} -m ${g.bootstrap.bootstrapManifest} --timestamp ${timestamp} --timestampdep ${timestampdep} -d ${outfile}.d -o ${outfile} ${in}
+    command = ${g.bootstrap.BinDir}/minibp --build-primary ${runTests} -m ${g.bootstrap.bootstrapManifest} --timestamp ${timestamp} --timestampdep ${timestampdep} -b ${g.bootstrap.buildDir} -d ${outfile}.d -o ${outfile} ${in}
     depfile = ${outfile}.d
     description = minibp ${outfile}
 
 rule s.bootstrap.minibp
-    command = ${g.bootstrap.BinDir}/minibp ${runTests} -m ${g.bootstrap.bootstrapManifest} -d ${out}.d -o ${out} ${in}
+    command = ${g.bootstrap.BinDir}/minibp ${runTests} -m ${g.bootstrap.bootstrapManifest} -b ${g.bootstrap.buildDir} -d ${out}.d -o ${out} ${in}
     depfile = ${out}.d
     description = minibp ${out}
     generator = true
 
-build .bootstrap/primary.ninja.in .bootstrap/primary.ninja.in.timestamp: $
+build ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in $
+        ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in.timestamp: $
         s.bootstrap.primarybp ${g.bootstrap.srcDir}/Blueprints | $
         ${g.bootstrap.BinDir}/choosestage ${g.bootstrap.BinDir}/gotestmain $
         ${g.bootstrap.BinDir}/minibp ${g.bootstrap.srcDir}/Blueprints
-    outfile = .bootstrap/primary.ninja.in
-    timestamp = .bootstrap/primary.ninja.in.timestamp
-    timestampdep = .bootstrap/primary.ninja.in.timestamp.d
-default .bootstrap/primary.ninja.in .bootstrap/primary.ninja.in.timestamp
+    outfile = ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in
+    timestamp = ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in.timestamp
+    timestampdep = ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in.timestamp.d
+default ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in $
+        ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in.timestamp
 
-build .bootstrap/bootstrap.ninja.in: s.bootstrap.minibp $
-        ${g.bootstrap.srcDir}/Blueprints | ${g.bootstrap.bootstrapManifest} $
-        ${g.bootstrap.BinDir}/minibp
-default .bootstrap/bootstrap.ninja.in
-build .bootstrap/notAFile: phony
-default .bootstrap/notAFile
-build .bootstrap/build.ninja.in: g.bootstrap.chooseStage $
-        .bootstrap/bootstrap.ninja.in .bootstrap/primary.ninja.in | $
+build ${g.bootstrap.buildDir}/.bootstrap/bootstrap.ninja.in: $
+        s.bootstrap.minibp ${g.bootstrap.srcDir}/Blueprints | $
+        ${g.bootstrap.bootstrapManifest} ${g.bootstrap.BinDir}/minibp
+default ${g.bootstrap.buildDir}/.bootstrap/bootstrap.ninja.in
+build ${g.bootstrap.buildDir}/.bootstrap/notAFile: phony
+default ${g.bootstrap.buildDir}/.bootstrap/notAFile
+build ${g.bootstrap.buildDir}/.bootstrap/build.ninja.in: $
+        g.bootstrap.chooseStage $
+        ${g.bootstrap.buildDir}/.bootstrap/bootstrap.ninja.in $
+        ${g.bootstrap.buildDir}/.bootstrap/primary.ninja.in | $
         ${g.bootstrap.chooseStageCmd} ${g.bootstrap.bootstrapManifest} $
-        .bootstrap/notAFile
-    current = .bootstrap/bootstrap.ninja.in
-default .bootstrap/build.ninja.in
+        ${g.bootstrap.buildDir}/.bootstrap/notAFile
+    current = ${g.bootstrap.buildDir}/.bootstrap/bootstrap.ninja.in
+default ${g.bootstrap.buildDir}/.bootstrap/build.ninja.in
 
-build build.ninja: g.bootstrap.bootstrap .bootstrap/build.ninja.in | $
+build ${g.bootstrap.buildDir}/build.ninja: g.bootstrap.bootstrap $
+        ${g.bootstrap.buildDir}/.bootstrap/build.ninja.in | $
         ${g.bootstrap.bootstrapCmd}
-default build.ninja
+default ${g.bootstrap.buildDir}/build.ninja
 
diff --git a/choosestage/choosestage.go b/choosestage/choosestage.go
index e1445e0..c3d0273 100644
--- a/choosestage/choosestage.go
+++ b/choosestage/choosestage.go
@@ -135,7 +135,7 @@
 			// If we're currently running this stage, and the build.ninja.in
 			// file differs from the current stage file, then it has been rebuilt.
 			// Restart the stage.
-			if currentFile == fileName {
+			if filepath.Clean(currentFile) == filepath.Clean(fileName) {
 				if _, err := os.Stat(outputFile); !os.IsNotExist(err) {
 					if ok, err := compareFiles(fileName, outputFile); err != nil {
 						fmt.Fprintf(os.Stderr, "Failure when comparing files: %s\n", err)