UseAllFiles bool `json:",omitempty"` // use files regardless of +build lines, file names
Compiler string `json:",omitempty"` // compiler to assume when computing target paths
BuildTags []string `json:",omitempty"` // build constraints to match in +build lines
+ ToolTags []string `json:",omitempty"` // toolchain-specific build constraints
ReleaseTags []string `json:",omitempty"` // releases the current release is compatible with
InstallSuffix string `json:",omitempty"` // suffix to use in the name of the install dir
}
UseAllFiles: c.UseAllFiles,
Compiler: c.Compiler,
BuildTags: c.BuildTags,
+ ToolTags: c.ToolTags,
ReleaseTags: c.ReleaseTags,
InstallSuffix: c.InstallSuffix,
}
"cmd/internal/sys"
"flag"
"fmt"
- "internal/buildcfg"
"os"
"path/filepath"
"runtime"
base.Fatalf("go %s: %s environment variable is relative; must be absolute path: %s\n", flag.Args()[0], key, path)
}
}
-
- // 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.
- for _, expt := range buildcfg.EnabledExperiments() {
- cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt)
- }
}
func instrumentInit() {
"go/build/constraint"
"go/doc"
"go/token"
+ "internal/buildcfg"
exec "internal/execabs"
"internal/goroot"
"internal/goversion"
UseAllFiles bool // use files regardless of +build lines, file names
Compiler string // compiler to assume when computing target paths
- // The build and release tags specify build constraints
+ // The build, tool, and release tags specify build constraints
// that should be considered satisfied when processing +build lines.
// Clients creating a new context may customize BuildTags, which
- // defaults to empty, but it is usually an error to customize ReleaseTags,
- // which defaults to the list of Go releases the current release is compatible with.
+ // defaults to empty, but it is usually an error to customize ToolTags or ReleaseTags.
+ // ToolTags defaults to build tags appropriate to the current Go toolchain configuration.
+ // ReleaseTags defaults to the list of Go releases the current release is compatible with.
// BuildTags is not set for the Default build Context.
- // In addition to the BuildTags and ReleaseTags, build constraints
+ // In addition to the BuildTags, ToolTags, and ReleaseTags, build constraints
// consider the values of GOARCH and GOOS as satisfied tags.
// The last element in ReleaseTags is assumed to be the current release.
BuildTags []string
+ ToolTags []string
ReleaseTags []string
// The install suffix specifies a suffix to use in the name of the installation
return ""
}
-var defaultReleaseTags []string
+var defaultToolTags, defaultReleaseTags []string
func defaultContext() Context {
var c Context
- c.GOARCH = envOr("GOARCH", runtime.GOARCH)
- c.GOOS = envOr("GOOS", runtime.GOOS)
+ c.GOARCH = buildcfg.GOARCH
+ c.GOOS = buildcfg.GOOS
c.GOROOT = pathpkg.Clean(runtime.GOROOT())
c.GOPATH = envOr("GOPATH", defaultGOPATH())
c.Compiler = runtime.Compiler
+ // 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.
+ for _, exp := range buildcfg.EnabledExperiments() {
+ c.ToolTags = append(c.ToolTags, "goexperiment."+exp)
+ }
+ defaultToolTags = append([]string{}, c.ToolTags...) // our own private copy
+
// Each major Go release in the Go 1.x series adds a new
// "go1.x" release tag. That is, the go1.x tag is present in
// all releases >= Go 1.x. Code that requires Go 1.x or later
// we must not being doing special things like AllowBinary or IgnoreVendor,
// and all the file system callbacks must be nil (we're meant to use the local file system).
if mode&AllowBinary != 0 || mode&IgnoreVendor != 0 ||
- ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
+ ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ToolTags, defaultToolTags) || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
return errNoModules
}
return true
}
}
+ for _, tag := range ctxt.ToolTags {
+ if tag == name {
+ return true
+ }
+ }
for _, tag := range ctxt.ReleaseTags {
if tag == name {
return true
"errors"
"flag"
"fmt"
+ "go/build"
"hash/fnv"
"io"
"io/fs"
GOARCH string
cgoEnabled bool
noOptEnv bool
- expTags map[string]bool // Set lazily
}
// shouldTest looks for build tags in a source file and returns
}
if strings.HasPrefix(name, "goexperiment.") {
- // Query goexperiment tags from the toolchain.
- if ctxt.expTags == nil {
- ctxt.expTags = make(map[string]bool)
- cmd := exec.Command(goTool(), "tool", "compile", "-V=goexperiment")
- out, err := cmd.CombinedOutput()
- if err != nil {
- log.Fatalf("failed to get GOEXPERIMENT configuration:\n%s", out)
- }
- i := bytes.Index(out, []byte("X:"))
- if i != -1 {
- for _, exp := range strings.Split(string(out[i+2:]), ",") {
- v := true
- if strings.HasPrefix(exp, "no") {
- v, exp = false, exp[2:]
- }
- ctxt.expTags["goexperiment."+exp] = v
- }
+ for _, tag := range build.Default.ToolTags {
+ if tag == name {
+ return true
}
}
-
- return ctxt.expTags[name]
+ return false
}
if name == "cgo" && ctxt.cgoEnabled {