aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/asm/internal/lex/input.go2
-rw-r--r--src/cmd/go/internal/cfg/cfg.go84
-rw-r--r--src/cmd/go/internal/envcmd/env.go16
-rw-r--r--src/cmd/go/internal/load/pkg.go4
-rw-r--r--src/cmd/go/internal/work/exec.go9
-rw-r--r--src/cmd/go/internal/work/gc.go3
-rw-r--r--src/cmd/go/main.go3
-rw-r--r--src/cmd/internal/objabi/flag.go6
-rw-r--r--src/cmd/internal/objabi/util.go2
-rw-r--r--src/cmd/link/internal/ld/main.go2
10 files changed, 81 insertions, 50 deletions
diff --git a/src/cmd/asm/internal/lex/input.go b/src/cmd/asm/internal/lex/input.go
index e373ae817e..276b4b0dcd 100644
--- a/src/cmd/asm/internal/lex/input.go
+++ b/src/cmd/asm/internal/lex/input.go
@@ -50,7 +50,7 @@ func predefine(defines flags.MultiFlag) map[string]*Macro {
// Set macros for GOEXPERIMENTs so we can easily switch
// runtime assembly code based on them.
if *flags.CompilingRuntime {
- for _, exp := range buildcfg.EnabledExperiments() {
+ for _, exp := range buildcfg.Experiment.Enabled() {
// Define macro.
name := "GOEXPERIMENT_" + exp
macros[name] = &Macro{
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index deab3dddd0..77c0e229e5 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -22,6 +22,26 @@ import (
"cmd/go/internal/fsys"
)
+// Global build parameters (used during package load)
+var (
+ Goos = envOr("GOOS", build.Default.GOOS)
+ Goarch = envOr("GOARCH", build.Default.GOARCH)
+
+ ExeSuffix = exeSuffix()
+
+ // ModulesEnabled specifies whether the go command is running
+ // in module-aware mode (as opposed to GOPATH mode).
+ // It is equal to modload.Enabled, but not all packages can import modload.
+ ModulesEnabled bool
+)
+
+func exeSuffix() string {
+ if Goos == "windows" {
+ return ".exe"
+ }
+ return ""
+}
+
// These are general "build flags" used by build and other commands.
var (
BuildA bool // -a flag
@@ -60,8 +80,6 @@ var (
// GoPathError is set when GOPATH is not set. it contains an
// explanation why GOPATH is unset.
GoPathError string
-
- GOEXPERIMENT = envOr("GOEXPERIMENT", buildcfg.DefaultGOEXPERIMENT)
)
func defaultContext() build.Context {
@@ -79,20 +97,15 @@ func defaultContext() build.Context {
build.ToolDir = filepath.Join(ctxt.GOROOT, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
}
- ctxt.GOPATH = envOr("GOPATH", gopath(ctxt))
-
// Override defaults computed in go/build with defaults
// from go environment configuration file, if known.
- ctxt.GOOS = envOr("GOOS", ctxt.GOOS)
- ctxt.GOARCH = envOr("GOARCH", ctxt.GOARCH)
+ ctxt.GOPATH = envOr("GOPATH", gopath(ctxt))
+ ctxt.GOOS = Goos
+ ctxt.GOARCH = Goarch
- // The experiments flags are based on GOARCH, so they may
- // need to change. TODO: This should be cleaned up.
- buildcfg.UpdateExperiments(ctxt.GOOS, ctxt.GOARCH, GOEXPERIMENT)
+ // ToolTags are based on GOEXPERIMENT, which we will parse and
+ // initialize later.
ctxt.ToolTags = nil
- for _, exp := range buildcfg.EnabledExperiments() {
- ctxt.ToolTags = append(ctxt.ToolTags, "goexperiment."+exp)
- }
// The go/build rule for whether cgo is enabled is:
// 1. If $CGO_ENABLED is set, respect it.
@@ -137,6 +150,33 @@ func init() {
BuildToolchainLinker = func() string { return "missing-linker" }
}
+// Experiment configuration.
+var (
+ // RawGOEXPERIMENT is the GOEXPERIMENT value set by the user.
+ RawGOEXPERIMENT = envOr("GOEXPERIMENT", buildcfg.DefaultGOEXPERIMENT)
+ // CleanGOEXPERIMENT is the minimal GOEXPERIMENT value needed to reproduce the
+ // experiments enabled by RawGOEXPERIMENT.
+ CleanGOEXPERIMENT = RawGOEXPERIMENT
+
+ Experiment *buildcfg.ExperimentFlags
+ ExperimentErr error
+)
+
+func init() {
+ Experiment, ExperimentErr = buildcfg.ParseGOEXPERIMENT(Goos, Goarch, RawGOEXPERIMENT)
+ if ExperimentErr != nil {
+ return
+ }
+
+ // GOEXPERIMENT is valid, so convert it to canonical form.
+ CleanGOEXPERIMENT = Experiment.String()
+
+ // Add build tags based on the experiments in effect.
+ for _, exp := range Experiment.Enabled() {
+ BuildContext.ToolTags = append(BuildContext.ToolTags, "goexperiment."+exp)
+ }
+}
+
// An EnvVar is an environment variable Name=Value.
type EnvVar struct {
Name string
@@ -151,26 +191,6 @@ var OrigEnv []string
// not CmdEnv.
var CmdEnv []EnvVar
-// Global build parameters (used during package load)
-var (
- Goarch = BuildContext.GOARCH
- Goos = BuildContext.GOOS
-
- ExeSuffix = exeSuffix()
-
- // ModulesEnabled specifies whether the go command is running
- // in module-aware mode (as opposed to GOPATH mode).
- // It is equal to modload.Enabled, but not all packages can import modload.
- ModulesEnabled bool
-)
-
-func exeSuffix() string {
- if Goos == "windows" {
- return ".exe"
- }
- return ""
-}
-
var envCache struct {
once sync.Once
m map[string]string
diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
index c1adf8cef4..fcabc8d1c7 100644
--- a/src/cmd/go/internal/envcmd/env.go
+++ b/src/cmd/go/internal/envcmd/env.go
@@ -74,7 +74,14 @@ func MkEnv() []cfg.EnvVar {
{Name: "GOCACHE", Value: cache.DefaultDir()},
{Name: "GOENV", Value: envFile},
{Name: "GOEXE", Value: cfg.ExeSuffix},
- {Name: "GOEXPERIMENT", Value: buildcfg.GOEXPERIMENT()},
+
+ // List the raw value of GOEXPERIMENT, not the cleaned one.
+ // The set of default experiments may change from one release
+ // to the next, so a GOEXPERIMENT setting that is redundant
+ // with the current toolchain might actually be relevant with
+ // a different version (for example, when bisecting a regression).
+ {Name: "GOEXPERIMENT", Value: cfg.RawGOEXPERIMENT},
+
{Name: "GOFLAGS", Value: cfg.Getenv("GOFLAGS")},
{Name: "GOHOSTARCH", Value: runtime.GOARCH},
{Name: "GOHOSTOS", Value: runtime.GOOS},
@@ -222,6 +229,9 @@ func runEnv(ctx context.Context, cmd *base.Command, args []string) {
}
buildcfg.Check()
+ if cfg.ExperimentErr != nil {
+ base.Fatalf("go: %v", cfg.ExperimentErr)
+ }
env := cfg.CmdEnv
env = append(env, ExtraEnvVars()...)
@@ -374,9 +384,9 @@ func checkBuildConfig(add map[string]string, del map[string]bool) error {
}
}
- goexperiment, okGOEXPERIMENT := get("GOEXPERIMENT", buildcfg.GOEXPERIMENT(), "")
+ goexperiment, okGOEXPERIMENT := get("GOEXPERIMENT", cfg.RawGOEXPERIMENT, buildcfg.DefaultGOEXPERIMENT)
if okGOEXPERIMENT {
- if _, _, err := buildcfg.ParseGOEXPERIMENT(goos, goarch, goexperiment); err != nil {
+ if _, err := buildcfg.ParseGOEXPERIMENT(goos, goarch, goexperiment); err != nil {
return err
}
}
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index fdc00f95dc..8c169d1643 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -2334,8 +2334,8 @@ func (p *Package) setBuildInfo() {
}
}
appendSetting("GOARCH", cfg.BuildContext.GOARCH)
- if cfg.GOEXPERIMENT != "" {
- appendSetting("GOEXPERIMENT", cfg.GOEXPERIMENT)
+ if cfg.RawGOEXPERIMENT != "" {
+ appendSetting("GOEXPERIMENT", cfg.RawGOEXPERIMENT)
}
appendSetting("GOOS", cfg.BuildContext.GOOS)
if key, val := cfg.GetArchEnv(); key != "" && val != "" {
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index 7d3a16c5f5..6d6837aa8a 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -12,7 +12,6 @@ import (
"encoding/json"
"errors"
"fmt"
- "internal/buildcfg"
exec "internal/execabs"
"internal/lazyregexp"
"io"
@@ -320,8 +319,8 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
key, val := cfg.GetArchEnv()
fmt.Fprintf(h, "%s=%s\n", key, val)
- if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
- fmt.Fprintf(h, "GOEXPERIMENT=%q\n", goexperiment)
+ if cfg.CleanGOEXPERIMENT != "" {
+ fmt.Fprintf(h, "GOEXPERIMENT=%q\n", cfg.CleanGOEXPERIMENT)
}
// TODO(rsc): Convince compiler team not to add more magic environment variables,
@@ -1301,8 +1300,8 @@ func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) {
key, val := cfg.GetArchEnv()
fmt.Fprintf(h, "%s=%s\n", key, val)
- if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
- fmt.Fprintf(h, "GOEXPERIMENT=%q\n", goexperiment)
+ if cfg.CleanGOEXPERIMENT != "" {
+ fmt.Fprintf(h, "GOEXPERIMENT=%q\n", cfg.CleanGOEXPERIMENT)
}
// The linker writes source file paths that say GOROOT_FINAL, but
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
index e1e2b11dd7..a6174b2ed2 100644
--- a/src/cmd/go/internal/work/gc.go
+++ b/src/cmd/go/internal/work/gc.go
@@ -8,7 +8,6 @@ import (
"bufio"
"bytes"
"fmt"
- "internal/buildcfg"
"io"
"log"
"os"
@@ -245,7 +244,7 @@ CheckFlags:
}
// TODO: Test and delete these conditions.
- if buildcfg.Experiment.FieldTrack || buildcfg.Experiment.PreemptibleLoops {
+ if cfg.ExperimentErr != nil || cfg.Experiment.FieldTrack || cfg.Experiment.PreemptibleLoops {
canDashC = false
}
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index c0a1d3ccfc..ed46ed822a 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -190,6 +190,9 @@ func invoke(cmd *base.Command, args []string) {
// 'go env' handles checking the build config
if cmd != envcmd.CmdEnv {
buildcfg.Check()
+ if cfg.ExperimentErr != nil {
+ base.Fatalf("go: %v", cfg.ExperimentErr)
+ }
}
// Set environment (GOOS, GOARCH, etc) explicitly.
diff --git a/src/cmd/internal/objabi/flag.go b/src/cmd/internal/objabi/flag.go
index f75c054fcb..acb2dd59ea 100644
--- a/src/cmd/internal/objabi/flag.go
+++ b/src/cmd/internal/objabi/flag.go
@@ -99,11 +99,11 @@ func (versionFlag) Set(s string) error {
if s == "goexperiment" {
// test/run.go uses this to discover the full set of
// experiment tags. Report everything.
- p = " X:" + strings.Join(buildcfg.AllExperiments(), ",")
+ p = " X:" + strings.Join(buildcfg.Experiment.All(), ",")
} else {
- // If the enabled experiments differ from the defaults,
+ // If the enabled experiments differ from the baseline,
// include that difference.
- if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
+ if goexperiment := buildcfg.Experiment.String(); goexperiment != "" {
p = " X:" + goexperiment
}
}
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index 6bfa25a5ca..c2f1b204b9 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -22,5 +22,5 @@ const (
// or link object files that are incompatible with each other. This
// string always starts with "go object ".
func HeaderString() string {
- return fmt.Sprintf("go object %s %s %s X:%s\n", buildcfg.GOOS, buildcfg.GOARCH, buildcfg.Version, strings.Join(buildcfg.EnabledExperiments(), ","))
+ return fmt.Sprintf("go object %s %s %s X:%s\n", buildcfg.GOOS, buildcfg.GOARCH, buildcfg.Version, strings.Join(buildcfg.Experiment.Enabled(), ","))
}
diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go
index 26f9db8ec4..d13c3ff8b6 100644
--- a/src/cmd/link/internal/ld/main.go
+++ b/src/cmd/link/internal/ld/main.go
@@ -124,7 +124,7 @@ func Main(arch *sys.Arch, theArch Arch) {
addstrdata1(ctxt, "internal/buildcfg.defaultGOROOT="+final)
buildVersion := buildcfg.Version
- if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" {
+ if goexperiment := buildcfg.Experiment.String(); goexperiment != "" {
buildVersion += " X:" + goexperiment
}
addstrdata1(ctxt, "runtime.buildVersion="+buildVersion)