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: ...@@ -93,6 +93,10 @@ and test commands:
a list of build tags to consider satisfied during the build. a list of build tags to consider satisfied during the build.
For more information about build tags, see the description of For more information about build tags, see the description of
build constraints in the documentation for the go/build package. 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 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. in an element in the list, surround it with either single or double quotes.
...@@ -131,6 +135,7 @@ var buildCcflags []string // -ccflags flag ...@@ -131,6 +135,7 @@ var buildCcflags []string // -ccflags flag
var buildLdflags []string // -ldflags flag var buildLdflags []string // -ldflags flag
var buildGccgoflags []string // -gccgoflags flag var buildGccgoflags []string // -gccgoflags flag
var buildRace bool // -race flag var buildRace bool // -race flag
var buildToolExec []string // -toolexec flag
var buildContext = build.Default var buildContext = build.Default
var buildToolchain toolchain = noToolchain{} var buildToolchain toolchain = noToolchain{}
...@@ -184,6 +189,7 @@ func addBuildFlags(cmd *Command) { ...@@ -184,6 +189,7 @@ func addBuildFlags(cmd *Command) {
cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "") cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
cmd.Flag.Var(buildCompiler{}, "compiler", "") cmd.Flag.Var(buildCompiler{}, "compiler", "")
cmd.Flag.BoolVar(&buildRace, "race", false, "") cmd.Flag.BoolVar(&buildRace, "race", false, "")
cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
} }
func addBuildFlagsNX(cmd *Command) { func addBuildFlagsNX(cmd *Command) {
...@@ -1229,6 +1235,7 @@ func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error { ...@@ -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 // 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 { 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, return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
buildToolExec,
tool("cover"), tool("cover"),
"-mode", a.p.coverMode, "-mode", a.p.coverMode,
"-var", varName, "-var", varName,
...@@ -1657,7 +1664,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, ...@@ -1657,7 +1664,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool,
gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix) 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 { if ofile == archive {
args = append(args, "-pack") args = append(args, "-pack")
} }
...@@ -1676,7 +1683,7 @@ func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { ...@@ -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. // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch)) inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
sfile = mkAbs(p.Dir, sfile) 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 { func (gcToolchain) pkgpath(basedir string, p *Package) string {
...@@ -1715,7 +1722,7 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s ...@@ -1715,7 +1722,7 @@ func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
// Need actual pack. // Need actual pack.
cmdline[0] = tool("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 { func packInternal(b *builder, afile string, ofiles []string) error {
...@@ -1823,7 +1830,7 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, ...@@ -1823,7 +1830,7 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
} }
} }
ldflags = append(ldflags, buildLdflags...) 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 { 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 ...@@ -2212,7 +2219,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfi
} }
objExt = "o" 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 return nil, nil, err
} }
outGo = append(outGo, gofiles...) outGo = append(outGo, gofiles...)
...@@ -2344,7 +2351,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfi ...@@ -2344,7 +2351,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfi
if p.Standard && p.ImportPath == "runtime/cgo" { if p.Standard && p.ImportPath == "runtime/cgo" {
cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker 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 return nil, nil, err
} }
outGo = append(outGo, importGo) outGo = append(outGo, importGo)
......
...@@ -112,6 +112,10 @@ and test commands: ...@@ -112,6 +112,10 @@ and test commands:
a list of build tags to consider satisfied during the build. a list of build tags to consider satisfied during the build.
For more information about build tags, see the description of For more information about build tags, see the description of
build constraints in the documentation for the go/build package. 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 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. in an element in the list, surround it with either single or double quotes.
......
...@@ -25,6 +25,6 @@ func runFix(cmd *Command, args []string) { ...@@ -25,6 +25,6 @@ func runFix(cmd *Command, args []string) {
// Use pkg.gofiles instead of pkg.Dir so that // Use pkg.gofiles instead of pkg.Dir so that
// the command only applies to this package, // the command only applies to this package,
// not to packages in subdirectories. // 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) { ...@@ -223,7 +223,7 @@ func download(arg string, stk *importStack, getTestDeps bool) {
// due to wildcard expansion. // due to wildcard expansion.
for _, p := range pkgs { for _, p := range pkgs {
if *getFix { 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. // The imports might have changed, so reload again.
p = reloadPackage(arg, stk) p = reloadPackage(arg, stk)
......
...@@ -46,5 +46,5 @@ func runVetFiles(p *Package, files []string) { ...@@ -46,5 +46,5 @@ func runVetFiles(p *Package, files []string) {
for i := range files { for i := range files {
files[i] = filepath.Join(p.Dir, files[i]) 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