cmd/go: handle relative temp dir

Most programs seem to accept a relative temp dir, as weird as that might be.

Also, the meaning of relative is a little more fluid on Windows:
TMP=\temp is relative (to the current drive) but will work well enough.

Also, Windows GetTempPath automatically converts a relative
%TMP% into an absolute path, so we'd be imposing different
behavior for GOTMPDIR vs TMP.

It seems easier and more consistent to just impose the obvious
meaning than to add an error we can only implement some of
the time.

Originally got here because "cmd/go:" should be"go:" in error message,
but the error message is gone now.

Fixes #23264.

Change-Id: I3c3fb801cbd5e652364f1f62bb3881e9317e3581
Reviewed-on: https://go-review.googlesource.com/123876
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 6f5e0c8..7a15ce3 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -6390,15 +6390,14 @@
 	tg.setenv("GOCACHE", "off")
 	tg.setenv("GOPATH", tg.path("."))
 	tg.setenv("GOTMPDIR", "tmp")
-	tg.runFail("build", "a")
-	tg.grepStderr("relative tmpdir", "wrong error")
+	tg.run("build", "-work", "a")
+	tg.grepStderr("WORK=[^t]", "work should be absolute path")
 
-	if runtime.GOOS != "windows" && runtime.GOOS != "plan9" {
-		tg.unsetenv("GOTMPDIR")
-		tg.setenv("TMPDIR", "tmp")
-		tg.runFail("build", "a")
-		tg.grepStderr("relative tmpdir", "wrong error")
-	}
+	tg.unsetenv("GOTMPDIR")
+	tg.setenv("TMP", "tmp")    // windows
+	tg.setenv("TMPDIR", "tmp") // unix
+	tg.run("build", "-work", "a")
+	tg.grepStderr("WORK=[^t]", "work should be absolute path")
 }
 
 // Issue 24704.
diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go
index 8ce68be..9cbc89f 100644
--- a/src/cmd/go/internal/work/action.go
+++ b/src/cmd/go/internal/work/action.go
@@ -213,7 +213,6 @@
 )
 
 func (b *Builder) Init() {
-	var err error
 	b.Print = func(a ...interface{}) (int, error) {
 		return fmt.Fprint(os.Stderr, a...)
 	}
@@ -225,14 +224,19 @@
 	if cfg.BuildN {
 		b.WorkDir = "$WORK"
 	} else {
-		b.WorkDir, err = ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-build")
+		tmp, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-build")
 		if err != nil {
 			base.Fatalf("%s", err)
 		}
-		if !filepath.IsAbs(b.WorkDir) {
-			os.RemoveAll(b.WorkDir)
-			base.Fatalf("cmd/go: relative tmpdir not supported")
+		if !filepath.IsAbs(tmp) {
+			abs, err := filepath.Abs(tmp)
+			if err != nil {
+				os.RemoveAll(tmp)
+				base.Fatalf("go: creating work dir: %v", err)
+			}
+			tmp = abs
 		}
+		b.WorkDir = tmp
 		if cfg.BuildX || cfg.BuildWork {
 			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.WorkDir)
 		}