Commit 83c10b20 authored by Russ Cox's avatar Russ Cox

cmd/go: add build flag -toolexec

Like the -exec flag, which specifies a program to use to run a built executable,
the -toolexec flag specifies a program to use to run a tool like 5a, 5g, or 5l.

This flag enables running the toolchain under common testing environments,
such as valgrind.

This flag also enables the use of custom testing environments or the substitution
of alternate tools. See https://godoc.org/rsc.io/toolstash for one possibility.

Change-Id: I256aa7af2d96a4bc7911dc58151cc2155dbd4121
Reviewed-on: https://go-review.googlesource.com/3351Reviewed-by: default avatarRob Pike <r@golang.org>
parent 0e80b2e0
......@@ -93,6 +93,10 @@ and test commands:
a list of build tags to consider satisfied during the build.
For more information about build tags, see the description of
build constraints in the documentation for the go/build package.
-toolexec 'cmd args'
a program to use to invoke toolchain programs like 5a, 5g, and 5l.
For example, instead of running 5g, the go command will run
'cmd args /path/to/5g <arguments for 5g>'.
The list flags accept a space-separated list of strings. To embed spaces
in an element in the list, surround it with either single or double quotes.
......@@ -131,6 +135,7 @@ var buildCcflags []string // -ccflags flag
var buildLdflags []string // -ldflags flag
var buildGccgoflags []string // -gccgoflags flag
var buildRace bool // -race flag
var buildToolExec []string // -toolexec flag
var buildContext = build.Default
var buildToolchain toolchain = noToolchain{}
......@@ -184,6 +189,7 @@ func addBuildFlags(cmd *Command) {
cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
cmd.Flag.Var(buildCompiler{}, "compiler", "")
cmd.Flag.BoolVar(&buildRace, "race", false, "")
cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
}
func addBuildFlagsNX(cmd *Command) {
......@@ -1229,6 +1235,7 @@ func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
// go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
buildToolExec,
tool("cover"),
"-mode", a.p.coverMode,
"-var", varName,
......@@ -1657,7 +1664,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
}
args := stringList(tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
args := stringList(buildToolExec, tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
if ofile == archive {
args = append(args, "-pack")
}
......@@ -1676,7 +1683,7 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
sfile = mkAbs(p.Dir, sfile)
return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-I", inc, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
return b.run(p.Dir, p.ImportPath, nil, stringList(buildToolExec, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-I", inc, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile))
}
func (gcToolchain) pkgpath(basedir string, p *Package) string {
......@@ -1715,7 +1722,7 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
// Need actual pack.
cmdline[0] = tool("pack")
return b.run(p.Dir, p.ImportPath, nil, cmdline)
return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cmdline)
}
func packInternal(b *builder, afile string, ofiles []string) error {
......@@ -1823,7 +1830,7 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
}
}
ldflags = append(ldflags, buildLdflags...)
return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
return b.run(".", p.ImportPath, nil, stringList(buildToolExec, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg))
}
func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
......@@ -2212,7 +2219,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfi
}
objExt = "o"
}
if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
return nil, nil, err
}
outGo = append(outGo, gofiles...)
......@@ -2344,7 +2351,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfi
if p.Standard && p.ImportPath == "runtime/cgo" {
cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
}
if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
return nil, nil, err
}
outGo = append(outGo, importGo)
......
......@@ -112,6 +112,10 @@ and test commands:
a list of build tags to consider satisfied during the build.
For more information about build tags, see the description of
build constraints in the documentation for the go/build package.
-toolexec 'cmd args'
a program to use to invoke toolchain programs like 5a, 5g, and 5l.
For example, instead of running 5g, the go command will run
'cmd args /path/to/5g <arguments for 5g>'.
The list flags accept a space-separated list of strings. To embed spaces
in an element in the list, surround it with either single or double quotes.
......
......@@ -25,6 +25,6 @@ func runFix(cmd *Command, args []string) {
// Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package,
// not to packages in subdirectories.
run(stringList(tool("fix"), relPaths(pkg.allgofiles)))
run(stringList(buildToolExec, tool("fix"), relPaths(pkg.allgofiles)))
}
}
......@@ -223,7 +223,7 @@ func download(arg string, stk *importStack, getTestDeps bool) {
// due to wildcard expansion.
for _, p := range pkgs {
if *getFix {
run(stringList(tool("fix"), relPaths(p.allgofiles)))
run(buildToolExec, stringList(tool("fix"), relPaths(p.allgofiles)))
// The imports might have changed, so reload again.
p = reloadPackage(arg, stk)
......
......@@ -46,5 +46,5 @@ func runVetFiles(p *Package, files []string) {
for i := range files {
files[i] = filepath.Join(p.Dir, files[i])
}
run(tool("vet"), relPaths(files))
run(buildToolExec, tool("vet"), relPaths(files))
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment