mirror of
https://github.com/golang/go
synced 2024-11-21 14:54:40 -07:00
race: build system changes
This is the first part of a bigger change that adds data race detection feature: https://golang.org/cl/6456044 Adds -race flag to go command. API change: +pkg go/build, type Context struct, InstallTag string R=rsc CC=golang-dev https://golang.org/cl/6488075
This commit is contained in:
parent
99b6e9f73b
commit
8ed026e783
@ -8,6 +8,7 @@ import (
|
||||
"bytes"
|
||||
"container/heap"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io"
|
||||
@ -59,6 +60,9 @@ The build flags are shared by the build, install, run, and test commands:
|
||||
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
|
||||
@ -104,6 +108,7 @@ var buildGcflags []string // -gcflags flag
|
||||
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{}
|
||||
@ -154,6 +159,7 @@ func addBuildFlags(cmd *Command) {
|
||||
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) {
|
||||
@ -173,6 +179,7 @@ func (v *stringsFlag) String() string {
|
||||
}
|
||||
|
||||
func runBuild(cmd *Command, args []string) {
|
||||
raceInit()
|
||||
var b builder
|
||||
b.init()
|
||||
|
||||
@ -217,6 +224,7 @@ See also: go build, go get, go clean.
|
||||
}
|
||||
|
||||
func runInstall(cmd *Command, args []string) {
|
||||
raceInit()
|
||||
pkgs := packagesForBuild(args)
|
||||
|
||||
for _, p := range pkgs {
|
||||
@ -441,7 +449,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
|
||||
// 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)
|
||||
@ -1547,6 +1555,10 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
|
||||
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 != "" {
|
||||
@ -1778,3 +1790,18 @@ func (q *actionQueue) push(a *action) {
|
||||
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")
|
||||
}
|
||||
|
@ -342,6 +342,11 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
|
||||
// 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,
|
||||
|
@ -34,6 +34,7 @@ func printStderr(args ...interface{}) (int, error) {
|
||||
}
|
||||
|
||||
func runRun(cmd *Command, args []string) {
|
||||
raceInit()
|
||||
var b builder
|
||||
b.init()
|
||||
b.print = printStderr
|
||||
|
@ -207,6 +207,7 @@ func runTest(cmd *Command, args []string) {
|
||||
var pkgArgs []string
|
||||
pkgArgs, testArgs = testFlags(args)
|
||||
|
||||
raceInit()
|
||||
pkgs := packagesForBuild(pkgArgs)
|
||||
if len(pkgs) == 0 {
|
||||
fatalf("no packages to test")
|
||||
|
@ -71,6 +71,7 @@ var testFlagDefn = []*testFlagSpec{
|
||||
{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},
|
||||
@ -129,7 +130,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
||||
}
|
||||
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)
|
||||
|
@ -33,6 +33,7 @@ type Context struct {
|
||||
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
|
||||
|
||||
@ -362,7 +363,11 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user