"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/load"
+ "cmd/internal/objabi"
"cmd/internal/sys"
"flag"
"fmt"
}
cfg.BuildPkgdir = p
}
+
+ // For each experiment that has been enabled in the toolchain, define a
+ // build tag with the same name but prefixed by "goexperiment." which can be
+ // used for compiling alternative files for the experiment. This allows
+ // changes for the experiment, like extra struct fields in the runtime,
+ // without affecting the base non-experiment code at all. [2:] strips the
+ // leading "X:" from objabi.Expstring().
+ exp := objabi.Expstring()[2:]
+ if exp != "none" {
+ experiments := strings.Split(exp, ",")
+ for _, expt := range experiments {
+ cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt)
+ }
+ }
}
func instrumentInit() {
"cmd/go/internal/robustio"
"cmd/go/internal/txtar"
"cmd/go/internal/work"
+ "cmd/internal/objabi"
"cmd/internal/sys"
)
"GOCACHE=" + testGOCACHE,
"GODEBUG=" + os.Getenv("GODEBUG"),
"GOEXE=" + cfg.ExeSuffix,
+ "GOEXPSTRING=" + objabi.Expstring()[2:],
"GOOS=" + runtime.GOOS,
"GOPATH=" + filepath.Join(ts.workdir, "gopath"),
"GOPROXY=" + proxyURL,
GOARCH=<target GOARCH>
GOCACHE=<actual GOCACHE being used outside the test>
GOEXE=<executable file suffix: .exe on Windows, empty on other systems>
+ GOEXPSTRING=<value of objabi.Expstring(), from GOEXPERIMENT when toolchain built>
GOOS=<target GOOS>
GOPATH=$WORK/gopath
GOPROXY=<local module proxy serving from cmd/go/testdata/mod>
--- /dev/null
+# compile_ext will fail if the buildtags that are enabled (or not enabled) for the
+# framepointer and fieldtrack experiments are not consistent with the value of
+# GOEXPSTRING (which comes from objabi.Expstring()).
+
+[short] skip
+go run m
+
+-- expt_main.go --
+package main
+
+import (
+ "os"
+ "strings"
+)
+
+func main() {
+ fp()
+ ft()
+}
+
+func hasExpEntry(s string) bool {
+ // script_test.go defines GOEXPSTRING to be the value of
+ // objabi.Expstring(), which gives the enabled experiments baked into the
+ // toolchain.
+ g := os.Getenv("GOEXPSTRING")
+ for _, f := range strings.Split(g, ",") {
+ if f == s {
+ return true
+ }
+ }
+ return false
+}
+
+-- fp_off.go --
+// +build !goexperiment.framepointer
+
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func fp() {
+ if hasExpEntry("framepointer") {
+ fmt.Println("in !framepointer build, but objabi.Expstring() has 'framepointer'")
+ os.Exit(1)
+ }
+}
+
+-- fp_on.go --
+// +build goexperiment.framepointer
+
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func fp() {
+ if !hasExpEntry("framepointer") {
+ fmt.Println("in framepointer build, but objabi.Expstring() does not have 'framepointer', is", os.Getenv("GOEXPSTRING"))
+ os.Exit(1)
+ }
+}
+
+-- ft_off.go --
+// +build !goexperiment.fieldtrack
+
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func ft() {
+ if hasExpEntry("fieldtrack") {
+ fmt.Println("in !fieldtrack build, but objabi.Expstring() has 'fieldtrack'")
+ os.Exit(1)
+ }
+}
+
+-- ft_on.go --
+// +build goexperiment.fieldtrack
+
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func ft() {
+ if !hasExpEntry("fieldtrack") {
+ fmt.Println("in fieldtrack build, but objabi.Expstring() does not have 'fieldtrack', is", os.Getenv("GOEXPSTRING"))
+ os.Exit(1)
+ }
+}
+
+-- go.mod --
+module m
+go 1.14