Allocate OutputPath.String in PathForOutput

In an AOSP aosp_blueline-userdebub build, OutputPath.String was
allocating 802MB of strings in filepath.Join to prepend the
out dir to each path.  Allocate the joined string in PathForOutput
instead, which results in ~57MB of new allocations in PathForOutput
but no allocations in OutputPath.String.

Test: all soong tests
Change-Id: Id452e0c46a2aeda71bfac11a227bb6edb8e3523d
diff --git a/android/paths.go b/android/paths.go
index da579d5..66725c6 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -843,10 +843,12 @@
 // OutputPath is a Path representing an intermediates file path rooted from the build directory
 type OutputPath struct {
 	basePath
+	fullPath string
 }
 
 func (p OutputPath) withRel(rel string) OutputPath {
 	p.basePath = p.basePath.withRel(rel)
+	p.fullPath = filepath.Join(p.fullPath, rel)
 	return p
 }
 
@@ -870,7 +872,9 @@
 	if err != nil {
 		reportPathError(ctx, err)
 	}
-	return OutputPath{basePath{path, ctx.Config(), ""}}
+	fullPath := filepath.Join(ctx.Config().buildDir, path)
+	path = fullPath[len(fullPath)-len(path):]
+	return OutputPath{basePath{path, ctx.Config(), ""}, fullPath}
 }
 
 // PathsForOutput returns Paths rooted from buildDir
@@ -885,7 +889,7 @@
 func (p OutputPath) writablePath() {}
 
 func (p OutputPath) String() string {
-	return filepath.Join(p.config.buildDir, p.path)
+	return p.fullPath
 }
 
 // Join creates a new OutputPath with paths... joined with the current path. The