"bytes"
"container/heap"
"errors"
+ "flag"
"fmt"
"go/build"
"io"
do not delete it when exiting.
-x
print the commands.
+ -race
+ enable data race detection.
+ Currently supported only on linux/amd64 and darwin/amd64.
-ccflags 'arg list'
arguments to pass on each 5c, 6c, or 8c compiler invocation
var buildCcflags []string // -ccflags flag
var buildLdflags []string // -ldflags flag
var buildGccgoflags []string // -gccgoflags flag
+var buildRace bool // -race flag
var buildContext = build.Default
var buildToolchain toolchain = noToolchain{}
cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
cmd.Flag.Var(buildCompiler{}, "compiler", "")
+ cmd.Flag.BoolVar(&buildRace, "race", false, "")
}
func addBuildFlagsNX(cmd *Command) {
}
func runBuild(cmd *Command, args []string) {
+ raceInit()
var b builder
b.init()
}
func runInstall(cmd *Command, args []string) {
+ raceInit()
pkgs := packagesForBuild(args)
for _, p := range pkgs {
// using cgo, to make sure we do not overwrite the binary while
// a package is using it. If this is a cross-build, then the cgo we
// are writing is not the cgo we need to use.
- if goos == runtime.GOOS && goarch == runtime.GOARCH {
+ if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
var stk importStack
p1 := loadPackage("cmd/cgo", &stk)
if p.Standard && p.ImportPath == "runtime/cgo" {
cgoflags = append(cgoflags, "-import_runtime_cgo=false")
}
+ if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
+ cgoflags = append(cgoflags, "-import_syscall=false")
+ }
+
if _, ok := buildToolchain.(gccgcToolchain); ok {
cgoflags = append(cgoflags, "-gccgo")
if prefix := gccgoPrefix(p); prefix != "" {
func (q *actionQueue) pop() *action {
return heap.Pop(q).(*action)
}
+
+func raceInit() {
+ if !buildRace {
+ return
+ }
+ if goarch != "amd64" || goos != "linux" && goos != "darwin" {
+ fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64 and darwin/amd64\n", flag.Args()[0])
+ os.Exit(2)
+ }
+ buildGcflags = append(buildGcflags, "-b")
+ buildLdflags = append(buildLdflags, "-b")
+ buildCcflags = append(buildCcflags, "-DRACE")
+ buildContext.InstallTag = "race"
+ buildContext.BuildTags = append(buildContext.BuildTags, "race")
+}
// Everything depends on runtime, except runtime and unsafe.
if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") {
importPaths = append(importPaths, "runtime")
+ // When race detection enabled everything depends on runtime/race.
+ // Exclude runtime/cgo and cmd/cgo to avoid circular dependencies.
+ if buildRace && (!p.Standard || (p.ImportPath != "runtime/race" && p.ImportPath != "runtime/cgo" && p.ImportPath != "cmd/cgo")) {
+ importPaths = append(importPaths, "runtime/race")
+ }
}
// Build list of full paths to all Go files in the package,
{name: "gccgoflags"},
{name: "tags"},
{name: "compiler"},
+ {name: "race", boolVar: &buildRace},
// passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
{name: "bench", passToTest: true},
}
switch f.name {
// bool flags.
- case "a", "c", "i", "n", "x", "v", "work":
+ case "a", "c", "i", "n", "x", "v", "work", "race":
setBoolFlag(f.boolVar, value)
case "p":
setIntFlag(&buildP, value)
GOPATH string // Go path
CgoEnabled bool // whether cgo can be used
BuildTags []string // additional tags to recognize in +build lines
+ InstallTag string // package install directory suffix
UseAllFiles bool // use files regardless of +build lines, file names
Compiler string // compiler to assume when computing target paths
dir, elem := pathpkg.Split(p.ImportPath)
pkga = "pkg/gccgo/" + dir + "lib" + elem + ".a"
case "gc":
- pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + p.ImportPath + ".a"
+ tag := ""
+ if ctxt.InstallTag != "" {
+ tag = "_" + ctxt.InstallTag
+ }
+ pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + tag + "/" + p.ImportPath + ".a"
default:
// Save error for end of function.
pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)