Use context builddir for removing abandoned files

Removing abandoned files needs to know where the .ninja_log file is
stored.  Export the ninja builddir value from Context and use it to
determine the .ninja_log path in any stage.

The ninja builddir (where ninja stores its .ninja_log and .ninja_deps
files) and the bootstrap.BuildDir (where build output files are written)
are distinct, so to reduce confusion replace SetBuildDir with
SetNinjaBuildDir.
diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go
index 14d6bf8..c952c85 100644
--- a/bootstrap/bootstrap.go
+++ b/bootstrap/bootstrap.go
@@ -722,7 +722,7 @@
 
 		// BuildDir must be different between the three stages, otherwise the
 		// cleanup process will remove files from the other builds.
-		ctx.SetBuildDir(pctx, miniBootstrapDir)
+		ctx.SetNinjaBuildDir(pctx, miniBootstrapDir)
 
 		// Generate the Ninja file to build the primary builder. Save the
 		// timestamps and deps, so that we can come back to this stage if
@@ -811,7 +811,7 @@
 
 		// BuildDir must be different between the three stages, otherwise the
 		// cleanup process will remove files from the other builds.
-		ctx.SetBuildDir(pctx, bootstrapDir)
+		ctx.SetNinjaBuildDir(pctx, bootstrapDir)
 
 		// We generate the depfile here that includes the dependencies for all
 		// the Blueprints files that contribute to generating the big build
@@ -901,7 +901,7 @@
 		})
 
 	case StageMain:
-		ctx.SetBuildDir(pctx, "${buildDir}")
+		ctx.SetNinjaBuildDir(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
diff --git a/bootstrap/cleanup.go b/bootstrap/cleanup.go
index 3171272..69ef06b 100644
--- a/bootstrap/cleanup.go
+++ b/bootstrap/cleanup.go
@@ -18,11 +18,12 @@
 	"bufio"
 	"errors"
 	"fmt"
-	"github.com/google/blueprint"
 	"os"
 	"path/filepath"
 	"strings"
 	"syscall"
+
+	"github.com/google/blueprint"
 )
 
 const logFileName = ".ninja_log"
@@ -32,12 +33,9 @@
 func removeAbandonedFiles(ctx *blueprint.Context, config *Config,
 	srcDir, manifestFile string) error {
 
-	buildDir := BuildDir
-	switch config.stage {
-	case StageBootstrap:
-		buildDir = filepath.Join(buildDir, miniBootstrapSubDir)
-	case StagePrimary:
-		buildDir = filepath.Join(buildDir, bootstrapSubDir)
+	ninjaBuildDir, err := ctx.NinjaBuildDir()
+	if err != nil {
+		return err
 	}
 
 	targetRules, err := ctx.AllTargets()
@@ -49,13 +47,14 @@
 		"@@SrcDir@@", srcDir,
 		"@@BuildDir@@", BuildDir,
 		"@@BootstrapManifest@@", manifestFile)
+	ninjaBuildDir = replacer.Replace(ninjaBuildDir)
 	targets := make(map[string]bool)
 	for target := range targetRules {
 		replacedTarget := replacer.Replace(target)
 		targets[filepath.Clean(replacedTarget)] = true
 	}
 
-	filePaths, err := parseNinjaLog(buildDir)
+	filePaths, err := parseNinjaLog(ninjaBuildDir)
 	if err != nil {
 		return err
 	}
@@ -73,8 +72,8 @@
 	return nil
 }
 
-func parseNinjaLog(buildDir string) ([]string, error) {
-	logFilePath := filepath.Join(buildDir, logFileName)
+func parseNinjaLog(ninjaBuildDir string) ([]string, error) {
+	logFilePath := filepath.Join(ninjaBuildDir, logFileName)
 	logFile, err := os.Open(logFilePath)
 	if err != nil {
 		if os.IsNotExist(err) {
diff --git a/context.go b/context.go
index c1d5b38..811df15 100644
--- a/context.go
+++ b/context.go
@@ -88,7 +88,7 @@
 	globalRules     map[Rule]*ruleDef
 
 	// set during PrepareBuildActions
-	buildDir           *ninjaString // The builddir special Ninja variable
+	ninjaBuildDir      *ninjaString // The builddir special Ninja variable
 	requiredNinjaMajor int          // For the ninja_required_version variable
 	requiredNinjaMinor int          // For the ninja_required_version variable
 	requiredNinjaMicro int          // For the ninja_required_version variable
@@ -1435,8 +1435,8 @@
 
 	deps = append(depsModules, depsSingletons...)
 
-	if c.buildDir != nil {
-		liveGlobals.addNinjaStringDeps(c.buildDir)
+	if c.ninjaBuildDir != nil {
+		liveGlobals.addNinjaStringDeps(c.ninjaBuildDir)
 	}
 
 	pkgNames := c.makeUniquePackageNames(liveGlobals)
@@ -1630,7 +1630,7 @@
 }
 
 func (c *Context) initSpecialVariables() {
-	c.buildDir = nil
+	c.ninjaBuildDir = nil
 	c.requiredNinjaMajor = 1
 	c.requiredNinjaMinor = 6
 	c.requiredNinjaMicro = 0
@@ -1912,9 +1912,9 @@
 	}
 }
 
-func (c *Context) setBuildDir(value *ninjaString) {
-	if c.buildDir == nil {
-		c.buildDir = value
+func (c *Context) setNinjaBuildDir(value *ninjaString) {
+	if c.ninjaBuildDir == nil {
+		c.ninjaBuildDir = value
 	}
 }
 
@@ -2085,6 +2085,14 @@
 	return targets, nil
 }
 
+func (c *Context) NinjaBuildDir() (string, error) {
+	if c.ninjaBuildDir != nil {
+		return c.ninjaBuildDir.Eval(c.globalVariables)
+	} else {
+		return "", nil
+	}
+}
+
 // ModuleTypePropertyStructs returns a mapping from module type name to a list of pointers to
 // property structs returned by the factory for that module type.
 func (c *Context) ModuleTypePropertyStructs() map[string][]interface{} {
@@ -2290,8 +2298,8 @@
 }
 
 func (c *Context) writeBuildDir(nw *ninjaWriter) error {
-	if c.buildDir != nil {
-		err := nw.Assign("builddir", c.buildDir.Value(c.pkgNames))
+	if c.ninjaBuildDir != nil {
+		err := nw.Assign("builddir", c.ninjaBuildDir.Value(c.pkgNames))
 		if err != nil {
 			return err
 		}
diff --git a/singleton_ctx.go b/singleton_ctx.go
index c4c0b6c..ee96fc6 100644
--- a/singleton_ctx.go
+++ b/singleton_ctx.go
@@ -37,11 +37,10 @@
 	Build(pctx *PackageContext, params BuildParams)
 	RequireNinjaVersion(major, minor, micro int)
 
-	// SetBuildDir sets the value of the top-level "builddir" Ninja variable
+	// SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
 	// that controls where Ninja stores its build log files.  This value can be
-	// set at most one time for a single build.  Setting it multiple times (even
-	// across different singletons) will result in a panic.
-	SetBuildDir(pctx *PackageContext, value string)
+	// set at most one time for a single build, later calls are ignored.
+	SetNinjaBuildDir(pctx *PackageContext, value string)
 
 	VisitAllModules(visit func(Module))
 	VisitAllModulesIf(pred func(Module) bool, visit func(Module))
@@ -138,7 +137,7 @@
 	s.context.requireNinjaVersion(major, minor, micro)
 }
 
-func (s *singletonContext) SetBuildDir(pctx *PackageContext, value string) {
+func (s *singletonContext) SetNinjaBuildDir(pctx *PackageContext, value string) {
 	s.scope.ReparentTo(pctx)
 
 	ninjaValue, err := parseNinjaString(s.scope, value)
@@ -146,7 +145,7 @@
 		panic(err)
 	}
 
-	s.context.setBuildDir(ninjaValue)
+	s.context.setNinjaBuildDir(ninjaValue)
 }
 
 func (s *singletonContext) VisitAllModules(visit func(Module)) {