cmd/gomobile: remove go/build usages from build.go

This CL is a pure refactoring. This removes a global variable ctx,
which is a build.Default.

Before this change, ctx was used to keep build tags and its state
affected go command executions. As the variable is mutable, the
code was not readable.

This changes introduces another global variable buildTags instead,
but this is more consistent with other build flags, and this is
immutable.

Updates golang/go#27234

Change-Id: Id8d0c779de21b249e96febd2f40833cd0c84534f
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/208060
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go
index 2910d8d..e26d51e 100644
--- a/cmd/gomobile/bind.go
+++ b/cmd/gomobile/bind.go
@@ -18,8 +18,6 @@
 	"golang.org/x/tools/go/packages"
 )
 
-// ctx in build.go
-
 var cmdBind = &command{
 	run:   runBind,
 	Name:  "bind",
@@ -81,12 +79,6 @@
 		return fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
 	}
 
-	// TODO(hajimehoshi): ctx is now used only for recording build tags in bind. Remove this.
-	oldCtx := ctx
-	defer func() {
-		ctx = oldCtx
-	}()
-
 	if bindJavaPkg != "" && targetOS != "android" {
 		return fmt.Errorf("-javapkg is supported only for android target")
 	}
@@ -99,9 +91,6 @@
 			return err
 		}
 	}
-	if targetOS == "darwin" {
-		ctx.BuildTags = append(ctx.BuildTags, "ios")
-	}
 
 	var gobind string
 	if !buildN {
@@ -232,8 +221,12 @@
 func packagesConfig(targetOS string) *packages.Config {
 	config := &packages.Config{}
 	config.Env = append(os.Environ(), "GOARCH=arm", "GOOS="+targetOS)
-	if len(ctx.BuildTags) > 0 {
-		config.BuildFlags = []string{"-tags=" + strings.Join(ctx.BuildTags, ",")}
+	tags := buildTags
+	if targetOS == "darwin" {
+		tags = append(tags, "ios")
+	}
+	if len(tags) > 0 {
+		config.BuildFlags = []string{"-tags=" + strings.Join(tags, ",")}
 	}
 	return config
 }
diff --git a/cmd/gomobile/bind_androidapp.go b/cmd/gomobile/bind_androidapp.go
index 8bba0da..f2f36b4 100644
--- a/cmd/gomobile/bind_androidapp.go
+++ b/cmd/gomobile/bind_androidapp.go
@@ -31,8 +31,8 @@
 	)
 	cmd.Env = append(cmd.Env, "GOOS=android")
 	cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
-	if len(ctx.BuildTags) > 0 {
-		cmd.Args = append(cmd.Args, "-tags="+strings.Join(ctx.BuildTags, ","))
+	if len(buildTags) > 0 {
+		cmd.Args = append(cmd.Args, "-tags="+strings.Join(buildTags, ","))
 	}
 	if bindJavaPkg != "" {
 		cmd.Args = append(cmd.Args, "-javapkg="+bindJavaPkg)
diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_iosapp.go
index 69a1636..53b5591 100644
--- a/cmd/gomobile/bind_iosapp.go
+++ b/cmd/gomobile/bind_iosapp.go
@@ -24,9 +24,8 @@
 	)
 	cmd.Env = append(cmd.Env, "GOOS=darwin")
 	cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
-	if len(ctx.BuildTags) > 0 {
-		cmd.Args = append(cmd.Args, "-tags="+strings.Join(ctx.BuildTags, ","))
-	}
+	tags := append(buildTags, "ios")
+	cmd.Args = append(cmd.Args, "-tags="+strings.Join(tags, ","))
 	if bindPrefix != "" {
 		cmd.Args = append(cmd.Args, "-prefix="+bindPrefix)
 	}
diff --git a/cmd/gomobile/build.go b/cmd/gomobile/build.go
index 59aa286..208a174 100644
--- a/cmd/gomobile/build.go
+++ b/cmd/gomobile/build.go
@@ -9,7 +9,6 @@
 import (
 	"bufio"
 	"fmt"
-	"go/build"
 	"io"
 	"os"
 	"os/exec"
@@ -20,7 +19,6 @@
 	"golang.org/x/tools/go/packages"
 )
 
-var ctx = build.Default
 var tmpdir string
 
 var cmdBuild = &command{
@@ -89,16 +87,6 @@
 		return nil, fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
 	}
 
-	// TODO(hajimehoshi): ctx is now used only for recording build tags in build. Remove this.
-	oldCtx := ctx
-	defer func() {
-		ctx = oldCtx
-	}()
-
-	if targetOS == "darwin" {
-		ctx.BuildTags = append(ctx.BuildTags, "ios")
-	}
-
 	var buildPath string
 	switch len(args) {
 	case 0:
@@ -228,20 +216,21 @@
 
 // "Build flags", used by multiple commands.
 var (
-	buildA          bool   // -a
-	buildI          bool   // -i
-	buildN          bool   // -n
-	buildV          bool   // -v
-	buildX          bool   // -x
-	buildO          string // -o
-	buildGcflags    string // -gcflags
-	buildLdflags    string // -ldflags
-	buildTarget     string // -target
-	buildTrimpath   bool   // -trimpath
-	buildWork       bool   // -work
-	buildBundleID   string // -bundleid
-	buildIOSVersion string // -iosversion
-	buildAndroidAPI int    // -androidapi
+	buildA          bool        // -a
+	buildI          bool        // -i
+	buildN          bool        // -n
+	buildV          bool        // -v
+	buildX          bool        // -x
+	buildO          string      // -o
+	buildGcflags    string      // -gcflags
+	buildLdflags    string      // -ldflags
+	buildTarget     string      // -target
+	buildTrimpath   bool        // -trimpath
+	buildWork       bool        // -work
+	buildBundleID   string      // -bundleid
+	buildIOSVersion string      // -iosversion
+	buildAndroidAPI int         // -androidapi
+	buildTags       stringsFlag // -tags
 )
 
 func addBuildFlags(cmd *command) {
@@ -256,7 +245,7 @@
 	cmd.flag.BoolVar(&buildA, "a", false, "")
 	cmd.flag.BoolVar(&buildI, "i", false, "")
 	cmd.flag.BoolVar(&buildTrimpath, "trimpath", false, "")
-	cmd.flag.Var((*stringsFlag)(&ctx.BuildTags), "tags", "")
+	cmd.flag.Var(&buildTags, "tags", "")
 }
 
 func addBuildFlagsNVXWork(cmd *command) {
@@ -299,8 +288,16 @@
 		goBin(),
 		subcmd,
 	)
-	if len(ctx.BuildTags) > 0 {
-		cmd.Args = append(cmd.Args, "-tags", strings.Join(ctx.BuildTags, " "))
+	tags := buildTags
+	targetOS, _, err := parseBuildTarget(buildTarget)
+	if err != nil {
+		return err
+	}
+	if targetOS == "darwin" {
+		tags = append(tags, "ios")
+	}
+	if len(tags) > 0 {
+		cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, " "))
 	}
 	if buildV {
 		cmd.Args = append(cmd.Args, "-v")
diff --git a/cmd/gomobile/build_darwin_test.go b/cmd/gomobile/build_darwin_test.go
index 0b25d2a..73e1b81 100644
--- a/cmd/gomobile/build_darwin_test.go
+++ b/cmd/gomobile/build_darwin_test.go
@@ -23,10 +23,10 @@
 	buildTarget = "ios"
 	buildBundleID = "org.golang.todo"
 	gopath = filepath.SplitList(goEnv("GOPATH"))[0]
-	oldTags := ctx.BuildTags
-	ctx.BuildTags = []string{"tag1"}
+	oldTags := buildTags
+	buildTags = []string{"tag1"}
 	defer func() {
-		ctx.BuildTags = oldTags
+		buildTags = oldTags
 	}()
 	tests := []struct {
 		pkg  string
diff --git a/cmd/gomobile/build_test.go b/cmd/gomobile/build_test.go
index 619a4fa..75c601b 100644
--- a/cmd/gomobile/build_test.go
+++ b/cmd/gomobile/build_test.go
@@ -86,10 +86,10 @@
 		os.Setenv("HOMEDRIVE", "C:")
 	}
 	cmdBuild.flag.Parse([]string{"golang.org/x/mobile/example/basic"})
-	oldTags := ctx.BuildTags
-	ctx.BuildTags = []string{"tag1"}
+	oldTags := buildTags
+	buildTags = []string{"tag1"}
 	defer func() {
-		ctx.BuildTags = oldTags
+		buildTags = oldTags
 	}()
 	err := runBuild(cmdBuild)
 	if err != nil {