Commit 00e9a54d authored by Russ Cox's avatar Russ Cox

go: improvements

Add 'go clean'.
Make 'go build' write to pkgname, not a.out.
Make 'go test -c' write to pkgname.test, not test.out.
Make 'go install' write alternate binaries to .../bin/goos_goarch/.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5600048
parent 38e37011
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec" "os/exec"
"path"
"path/filepath" "path/filepath"
"regexp" "regexp"
"runtime" "runtime"
...@@ -113,7 +114,10 @@ func runBuild(cmd *Command, args []string) { ...@@ -113,7 +114,10 @@ func runBuild(cmd *Command, args []string) {
} }
if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" { if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
*buildO = "a.out" _, *buildO = path.Split(pkgs[0].ImportPath)
if b.goos == "windows" {
*buildO += ".exe"
}
} }
if *buildO != "" { if *buildO != "" {
...@@ -174,10 +178,8 @@ func runInstall(cmd *Command, args []string) { ...@@ -174,10 +178,8 @@ func runInstall(cmd *Command, args []string) {
type builder struct { type builder struct {
work string // the temporary work directory (ends in filepath.Separator) work string // the temporary work directory (ends in filepath.Separator)
arch string // e.g., "6" arch string // e.g., "6"
goroot string // the $GOROOT
goarch string // the $GOARCH goarch string // the $GOARCH
goos string // the $GOOS goos string // the $GOOS
gobin string // the $GOBIN
exe string // the executable suffix - "" or ".exe" exe string // the executable suffix - "" or ".exe"
gcflags []string // additional flags for Go compiler gcflags []string // additional flags for Go compiler
actionCache map[cacheKey]*action // a cache of already-constructed actions actionCache map[cacheKey]*action // a cache of already-constructed actions
...@@ -231,14 +233,17 @@ const ( ...@@ -231,14 +233,17 @@ const (
modeInstall modeInstall
) )
var (
gobin = build.Path[0].BinDir()
goroot = build.Path[0].Path
)
func (b *builder) init() { func (b *builder) init() {
var err error var err error
b.actionCache = make(map[cacheKey]*action) b.actionCache = make(map[cacheKey]*action)
b.mkdirCache = make(map[string]bool) b.mkdirCache = make(map[string]bool)
b.goarch = buildContext.GOARCH b.goarch = buildContext.GOARCH
b.goos = buildContext.GOOS b.goos = buildContext.GOOS
b.goroot = build.Path[0].Path
b.gobin = build.Path[0].BinDir()
if b.goos == "windows" { if b.goos == "windows" {
b.exe = ".exe" b.exe = ".exe"
} }
...@@ -367,8 +372,6 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action ...@@ -367,8 +372,6 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
a.target = a.objpkg a.target = a.objpkg
if a.link { if a.link {
// An executable file. // An executable file.
// Have to use something other than .a for the suffix.
// It is easier on Windows if we use .exe, so use .exe everywhere.
// (This is the name of a temporary file.) // (This is the name of a temporary file.)
a.target = a.objdir + "a.out" + b.exe a.target = a.objdir + "a.out" + b.exe
} }
...@@ -762,7 +765,7 @@ func (b *builder) copyFile(dst, src string, perm os.FileMode) error { ...@@ -762,7 +765,7 @@ func (b *builder) copyFile(dst, src string, perm os.FileMode) error {
// fmtcmd inserts "cd dir\n" before the command. // fmtcmd inserts "cd dir\n" before the command.
// //
// fmtcmd replaces the value of b.work with $WORK. // fmtcmd replaces the value of b.work with $WORK.
// fmtcmd replaces the value of b.goroot with $GOROOT. // fmtcmd replaces the value of goroot with $GOROOT.
// fmtcmd replaces the value of b.gobin with $GOBIN. // fmtcmd replaces the value of b.gobin with $GOBIN.
// //
// fmtcmd replaces the name of the current directory with dot (.) // fmtcmd replaces the name of the current directory with dot (.)
...@@ -777,9 +780,11 @@ func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string ...@@ -777,9 +780,11 @@ func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string
cmd = "cd " + dir + "\n" + cmd cmd = "cd " + dir + "\n" + cmd
} }
} }
cmd = strings.Replace(cmd, b.work, "$WORK", -1) if b.work != "" {
cmd = strings.Replace(cmd, b.gobin, "$GOBIN", -1) cmd = strings.Replace(cmd, b.work, "$WORK", -1)
cmd = strings.Replace(cmd, b.goroot, "$GOROOT", -1) }
cmd = strings.Replace(cmd, gobin, "$GOBIN", -1)
cmd = strings.Replace(cmd, goroot, "$GOROOT", -1)
return cmd return cmd
} }
...@@ -976,7 +981,7 @@ func (goToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g ...@@ -976,7 +981,7 @@ func (goToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
gcargs = append(gcargs, "-+") gcargs = append(gcargs, "-+")
} }
binary := filepath.Join(b.goroot, "bin/go-tool/", b.arch+"g") binary := filepath.Join(goroot, "bin/go-tool/", b.arch+"g")
args := stringList(binary, "-o", ofile, b.gcflags, gcargs, importArgs) args := stringList(binary, "-o", ofile, b.gcflags, gcargs, importArgs)
for _, f := range gofiles { for _, f := range gofiles {
args = append(args, mkAbs(p.Dir, f)) args = append(args, mkAbs(p.Dir, f))
...@@ -986,7 +991,7 @@ func (goToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g ...@@ -986,7 +991,7 @@ func (goToolchain) gc(b *builder, p *Package, obj string, importArgs []string, g
func (goToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { func (goToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
sfile = mkAbs(p.Dir, sfile) sfile = mkAbs(p.Dir, sfile)
binary := filepath.Join(b.goroot, "bin/go-tool/", b.arch+"a") binary := filepath.Join(goroot, "bin/go-tool/", b.arch+"a")
return b.run(p.Dir, p.ImportPath, binary, "-I", obj, "-o", ofile, "-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, sfile) return b.run(p.Dir, p.ImportPath, binary, "-I", obj, "-o", ofile, "-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, sfile)
} }
...@@ -999,19 +1004,19 @@ func (goToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s ...@@ -999,19 +1004,19 @@ func (goToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []s
for _, f := range ofiles { for _, f := range ofiles {
absOfiles = append(absOfiles, mkAbs(objDir, f)) absOfiles = append(absOfiles, mkAbs(objDir, f))
} }
return b.run(p.Dir, p.ImportPath, filepath.Join(b.goroot, "bin/go-tool/pack"), "grc", mkAbs(objDir, afile), absOfiles) return b.run(p.Dir, p.ImportPath, filepath.Join(goroot, "bin/go-tool/pack"), "grc", mkAbs(objDir, afile), absOfiles)
} }
func (goToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error { func (goToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
importArgs := b.includeArgs("-L", allactions) importArgs := b.includeArgs("-L", allactions)
binary := filepath.Join(b.goroot, "bin/go-tool/", b.arch+"l") binary := filepath.Join(goroot, "bin/go-tool/", b.arch+"l")
return b.run(p.Dir, p.ImportPath, binary, "-o", out, importArgs, mainpkg) return b.run(p.Dir, p.ImportPath, binary, "-o", out, importArgs, mainpkg)
} }
func (goToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { func (goToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
inc := filepath.Join(b.goroot, "pkg", fmt.Sprintf("%s_%s", b.goos, b.goarch)) inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", b.goos, b.goarch))
cfile = mkAbs(p.Dir, cfile) cfile = mkAbs(p.Dir, cfile)
binary := filepath.Join(b.goroot, "bin/go-tool/", b.arch+"c") binary := filepath.Join(goroot, "bin/go-tool/", b.arch+"c")
return b.run(p.Dir, p.ImportPath, binary, "-FVw", return b.run(p.Dir, p.ImportPath, binary, "-FVw",
"-I", objdir, "-I", inc, "-o", ofile, "-I", objdir, "-I", inc, "-o", ofile,
"-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, cfile) "-DGOOS_"+b.goos, "-DGOARCH_"+b.goarch, cfile)
...@@ -1075,7 +1080,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions [] ...@@ -1075,7 +1080,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
} }
func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
inc := filepath.Join(b.goroot, "pkg", fmt.Sprintf("%s_%s", b.goos, b.goarch)) inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", b.goos, b.goarch))
cfile = mkAbs(p.Dir, cfile) cfile = mkAbs(p.Dir, cfile)
return b.run(p.Dir, p.ImportPath, "gcc", "-Wall", "-g", return b.run(p.Dir, p.ImportPath, "gcc", "-Wall", "-g",
"-I", objdir, "-I", inc, "-o", ofile, "-I", objdir, "-I", inc, "-o", ofile,
......
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
)
var cmdClean = &Command{
UsageLine: "clean [-i] [-r] [-n] [-x] [importpath...]",
Short: "remove object files",
Long: `
Clean removes object files from package source directories.
The go command builds most objects in a temporary directory,
so go clean is mainly concerned with object files left by other
tools or by manual invocations of go build.
Specifically, clean removes the following files from each of the
source directories corresponding to the import paths:
_obj/ old object directory, left from Makefiles
_test/ old test directory, left from Makefiles
_testmain.go old gotest file, left from Makefiles
test.out old test log, left from Makefiles
build.out old test log, left from Makefiles
*.[568ao] object files, left from Makefiles
DIR(.exe) from go build
DIR.test(.exe) from go test -c
MAINFILE(.exe) from go build MAINFILE.go
In the list, DIR represents the final path element of the
directory, and MAINFILE is the base name of any Go source
file in the directory that is not included when building
the package.
The -i flag causes clean to remove the corresponding installed
archive or binary (what 'go install' would create).
The -n flag causes clean to print the remove commands it would execute,
but not run them.
The -r flag causes clean to be applied recursively to all the
dependencies of the packages named by the import paths.
The -x flag causes clean to print remove commands as it executes them.
`,
}
var cleanI bool // clean -i flag
var cleanN bool // clean -n flag
var cleanR bool // clean -r flag
var cleanX bool // clean -x flag
func init() {
// break init cycle
cmdClean.Run = runClean
cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
}
func runClean(cmd *Command, args []string) {
for _, pkg := range packagesAndErrors(args) {
clean(pkg)
}
}
var cleaned = map[*Package]bool{}
// TODO: These are dregs left by Makefile-based builds.
// Eventually, can stop deleting these.
var cleanDir = map[string]bool{
"_test": true,
"_obj": true,
}
var cleanFile = map[string]bool{
"_testmain.go": true,
"test.out": true,
"build.out": true,
"a.out": true,
}
var cleanExt = map[string]bool{
".5": true,
".6": true,
".8": true,
".a": true,
".o": true,
}
func clean(p *Package) {
if cleaned[p] {
return
}
if p.Dir == "" {
errorf("can't load package: %v", p.Error)
return
}
dirs, err := ioutil.ReadDir(p.Dir)
if err != nil {
errorf("%v", err)
return
}
var b builder
packageFile := map[string]bool{}
if p.Name != "main" {
// Record which files are not in package main.
// The others are.
keep := func(list []string) {
for _, f := range list {
packageFile[f] = true
}
}
keep(p.GoFiles)
keep(p.CgoFiles)
keep(p.TestGoFiles)
keep(p.XTestGoFiles)
}
_, elem := filepath.Split(p.Dir)
allRemove := []string{
elem,
elem + ".exe",
elem + ".test",
elem + ".test.exe",
}
for _, dir := range dirs {
name := dir.Name()
if packageFile[name] {
continue
}
if !dir.IsDir() && strings.HasSuffix(name, ".go") {
base := name[:len(name)-len(".go")]
allRemove = append(allRemove, base, base+".exe")
}
}
if cleanN || cleanX {
b.showcmd(p.Dir, "rm %s", strings.Join(allRemove, " "))
}
toRemove := map[string]bool{}
for _, name := range allRemove {
toRemove[name] = true
}
for _, dir := range dirs {
name := dir.Name()
if dir.IsDir() {
// TODO: Remove once Makefiles are forgotten.
if cleanDir[name] {
if cleanN || cleanX {
b.showcmd(p.Dir, "rm -r %s", name)
if cleanN {
continue
}
}
os.RemoveAll(filepath.Join(p.Dir, name))
}
continue
}
if cleanN {
continue
}
if cleanFile[name] || cleanExt[filepath.Ext(name)] || toRemove[name] {
os.Remove(filepath.Join(p.Dir, name))
}
}
if cleanI && p.target != "" {
if cleanN || cleanX {
b.showcmd("", "rm %s", p.target)
}
if !cleanN {
os.Remove(p.target)
}
}
if cleanR {
for _, p1 := range p.imports {
clean(p1)
}
}
}
...@@ -10,6 +10,7 @@ Usage: go command [arguments] ...@@ -10,6 +10,7 @@ Usage: go command [arguments]
The commands are: The commands are:
build compile packages and dependencies build compile packages and dependencies
clean remove object files
doc run godoc on package sources doc run godoc on package sources
fix run gofix on packages fix run gofix on packages
fmt run gofmt on package sources fmt run gofmt on package sources
...@@ -18,6 +19,7 @@ The commands are: ...@@ -18,6 +19,7 @@ The commands are:
list list packages list list packages
run compile and run Go program run compile and run Go program
test test packages test test packages
tool run specified go tool
version print Go version version print Go version
vet run govet on packages vet run govet on packages
...@@ -67,6 +69,48 @@ For more about import paths, see 'go help importpath'. ...@@ -67,6 +69,48 @@ For more about import paths, see 'go help importpath'.
See also: go install, go get, go clean. See also: go install, go get, go clean.
Remove object files
Usage:
go clean [-i] [-r] [-n] [-x] [importpath...]
Clean removes object files from package source directories.
The go command builds most objects in a temporary directory,
so go clean is mainly concerned with object files left by other
tools or by manual invocations of go build.
Specifically, clean removes the following files from each of the
source directories corresponding to the import paths:
_obj/ old object directory, left from Makefiles
_test/ old test directory, left from Makefiles
_testmain.go old gotest file, left from Makefiles
test.out old test log, left from Makefiles
build.out old test log, left from Makefiles
*.[568ao] object files, left from Makefiles
DIR(.exe) from go build
DIR.test(.exe) from go test -c
MAINFILE(.exe) from go build MAINFILE.go
In the list, DIR represents the final path element of the
directory, and MAINFILE is the base name of any Go source
file in the directory that is not included when building
the package.
The -i flag causes clean to remove the corresponding installed
archive or binary (what 'go install' would create).
The -n flag causes clean to print the remove commands it would execute,
but not run them.
The -r flag causes clean to be applied recursively to all the
dependencies of the packages named by the import paths.
The -x flag causes clean to print remove commands as it executes them.
Run godoc on package sources Run godoc on package sources
Usage: Usage:
...@@ -90,12 +134,12 @@ Usage: ...@@ -90,12 +134,12 @@ Usage:
go fix [importpath...] go fix [importpath...]
Fix runs the gofix command on the packages named by the import paths. Fix runs the Go fix command on the packages named by the import paths.
For more about gofix, see 'godoc gofix'. For more about fix, see 'godoc fix'.
For more about import paths, see 'go help importpath'. For more about import paths, see 'go help importpath'.
To run gofix with specific options, run gofix itself. To run fix with specific options, run 'go tool fix'.
See also: go fmt, go vet. See also: go fmt, go vet.
...@@ -252,7 +296,7 @@ Test packages ...@@ -252,7 +296,7 @@ Test packages
Usage: Usage:
go test [-c] [-file a.go -file b.go ...] [-p n] [-x] [importpath...] [flags for test binary] go test [-c] [-file a.go -file b.go ...] [-i] [-p n] [-x] [importpath...] [flags for test binary]
'Go test' automates testing the packages named by the import paths. 'Go test' automates testing the packages named by the import paths.
It prints a summary of the test results in the format: It prints a summary of the test results in the format:
...@@ -285,6 +329,18 @@ See 'go help importpath' for more about import paths. ...@@ -285,6 +329,18 @@ See 'go help importpath' for more about import paths.
See also: go build, go vet. See also: go build, go vet.
Run specified go tool
Usage:
go tool command [args...]
Tool runs the go tool command identified by the arguments.
With no arguments it prints the list of known tools.
For more about each tool command, see 'go tool command -h'.
Print Go version Print Go version
Usage: Usage:
...@@ -300,12 +356,12 @@ Usage: ...@@ -300,12 +356,12 @@ Usage:
go vet [importpath...] go vet [importpath...]
Vet runs the govet command on the packages named by the import paths. Vet runs the Go vet command on the packages named by the import paths.
For more about govet, see 'godoc govet'. For more about vet, see 'godoc vet'.
For more about import paths, see 'go help importpath'. For more about import paths, see 'go help importpath'.
To run govet with specific options, run govet itself. To run govet with specific options, run 'go tool vet'.
See also: go fmt, go fix. See also: go fmt, go fix.
...@@ -487,19 +543,23 @@ and flags that apply to the resulting test binary. ...@@ -487,19 +543,23 @@ and flags that apply to the resulting test binary.
The flags handled by 'go test' are: The flags handled by 'go test' are:
-c Compile the test binary to test.out but do not run it. -c Compile the test binary to pkg.test but do not run it.
-file a.go -file a.go
Use only the tests in the source file a.go. Use only the tests in the source file a.go.
Multiple -file flags may be provided. Multiple -file flags may be provided.
-i
Install packages that are dependencies of the test.
-p n -p n
Compile and test up to n packages in parallel. Compile and test up to n packages in parallel.
The default value is the number of CPUs available. The default value is the number of CPUs available.
-x Print each subcommand go test executes. -x Print each subcommand go test executes.
The resulting test binary, called test.out, has its own flags: The resulting test binary, called pkg.test, where pkg is the name of the
directory containing the package sources, has its own flags:
-test.v -test.v
Verbose output: log all tests as they are run. Verbose output: log all tests as they are run.
...@@ -557,7 +617,7 @@ here are passed through unaltered. For instance, the command ...@@ -557,7 +617,7 @@ here are passed through unaltered. For instance, the command
will compile the test binary using x_test.go and then run it as will compile the test binary using x_test.go and then run it as
test.out -test.v -test.cpuprofile=prof.out -dir=testdata -update pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
Description of testing functions Description of testing functions
......
...@@ -67,6 +67,7 @@ func (c *Command) Usage() { ...@@ -67,6 +67,7 @@ func (c *Command) Usage() {
// The order here is the order in which they are printed by 'go help'. // The order here is the order in which they are printed by 'go help'.
var commands = []*Command{ var commands = []*Command{
cmdBuild, cmdBuild,
cmdClean,
cmdDoc, cmdDoc,
cmdFix, cmdFix,
cmdFmt, cmdFmt,
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"go/build" "go/build"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"sort" "sort"
"strings" "strings"
"time" "time"
...@@ -22,6 +23,7 @@ type Package struct { ...@@ -22,6 +23,7 @@ type Package struct {
Name string `json:",omitempty"` // package name Name string `json:",omitempty"` // package name
Doc string `json:",omitempty"` // package documentation string Doc string `json:",omitempty"` // package documentation string
Dir string `json:",omitempty"` // directory containing package sources Dir string `json:",omitempty"` // directory containing package sources
Target string `json:",omitempty"` // install path
Version string `json:",omitempty"` // version of installed package (TODO) Version string `json:",omitempty"` // version of installed package (TODO)
Standard bool `json:",omitempty"` // is this package part of the standard Go library? Standard bool `json:",omitempty"` // is this package part of the standard Go library?
Stale bool `json:",omitempty"` // would 'go install' do anything for this package? Stale bool `json:",omitempty"` // would 'go install' do anything for this package?
...@@ -273,6 +275,10 @@ func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string ...@@ -273,6 +275,10 @@ func scanPackage(ctxt *build.Context, t *build.Tree, arg, importPath, dir string
if t.Goroot && isGoTool[p.ImportPath] { if t.Goroot && isGoTool[p.ImportPath] {
p.target = filepath.Join(t.Path, "bin/go-tool", elem) p.target = filepath.Join(t.Path, "bin/go-tool", elem)
} else { } else {
if ctxt.GOOS != runtime.GOOS || ctxt.GOARCH != runtime.GOARCH {
// Install cross-compiled binaries to subdirectories of bin.
elem = ctxt.GOOS + "_" + ctxt.GOARCH + "/" + elem
}
p.target = filepath.Join(t.BinDir(), elem) p.target = filepath.Join(t.BinDir(), elem)
} }
if ctxt.GOOS == "windows" { if ctxt.GOOS == "windows" {
...@@ -404,6 +410,8 @@ Stale: ...@@ -404,6 +410,8 @@ Stale:
p.target = "" p.target = ""
} }
p.Target = p.target
return p return p
} }
......
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"go/token" "go/token"
"os" "os"
"os/exec" "os/exec"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
"text/template" "text/template"
...@@ -28,7 +29,7 @@ func init() { ...@@ -28,7 +29,7 @@ func init() {
var cmdTest = &Command{ var cmdTest = &Command{
CustomFlags: true, CustomFlags: true,
UsageLine: "test [-c] [-file a.go -file b.go ...] [-p n] [-x] [importpath...] [flags for test binary]", UsageLine: "test [-c] [-file a.go -file b.go ...] [-i] [-p n] [-x] [importpath...] [flags for test binary]",
Short: "test packages", Short: "test packages",
Long: ` Long: `
'Go test' automates testing the packages named by the import paths. 'Go test' automates testing the packages named by the import paths.
...@@ -72,19 +73,23 @@ and flags that apply to the resulting test binary. ...@@ -72,19 +73,23 @@ and flags that apply to the resulting test binary.
The flags handled by 'go test' are: The flags handled by 'go test' are:
-c Compile the test binary to test.out but do not run it. -c Compile the test binary to pkg.test but do not run it.
-file a.go -file a.go
Use only the tests in the source file a.go. Use only the tests in the source file a.go.
Multiple -file flags may be provided. Multiple -file flags may be provided.
-i
Install packages that are dependencies of the test.
-p n -p n
Compile and test up to n packages in parallel. Compile and test up to n packages in parallel.
The default value is the number of CPUs available. The default value is the number of CPUs available.
-x Print each subcommand go test executes. -x Print each subcommand go test executes.
The resulting test binary, called test.out, has its own flags: The resulting test binary, called pkg.test, where pkg is the name of the
directory containing the package sources, has its own flags:
-test.v -test.v
Verbose output: log all tests as they are run. Verbose output: log all tests as they are run.
...@@ -142,7 +147,7 @@ here are passed through unaltered. For instance, the command ...@@ -142,7 +147,7 @@ here are passed through unaltered. For instance, the command
will compile the test binary using x_test.go and then run it as will compile the test binary using x_test.go and then run it as
test.out -test.v -test.cpuprofile=prof.out -dir=testdata -update pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
`, `,
} }
...@@ -296,7 +301,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, ...@@ -296,7 +301,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
// Build Package structs describing: // Build Package structs describing:
// ptest - package + test files // ptest - package + test files
// pxtest - package of external test files // pxtest - package of external test files
// pmain - test.out binary // pmain - pkg.test binary
var ptest, pxtest, pmain *Package var ptest, pxtest, pmain *Package
// go/build does not distinguish the dependencies used // go/build does not distinguish the dependencies used
...@@ -315,6 +320,11 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, ...@@ -315,6 +320,11 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
} }
stk.pop() stk.pop()
// Use last element of import path, not package name.
// They differ when package name is "main".
_, elem := path.Split(p.ImportPath)
testBinary := elem + ".test"
// The ptest package needs to be importable under the // The ptest package needs to be importable under the
// same import path that p has, but we cannot put it in // same import path that p has, but we cannot put it in
// the usual place in the temporary tree, because then // the usual place in the temporary tree, because then
...@@ -383,7 +393,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, ...@@ -383,7 +393,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
a.target = a.objpkg a.target = a.objpkg
} }
// Action for building test.out. // Action for building pkg.test.
pmain = &Package{ pmain = &Package{
Name: "main", Name: "main",
Dir: testDir, Dir: testDir,
...@@ -412,7 +422,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, ...@@ -412,7 +422,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
a := b.action(modeBuild, modeBuild, pmain) a := b.action(modeBuild, modeBuild, pmain)
a.objdir = testDir + string(filepath.Separator) a.objdir = testDir + string(filepath.Separator)
a.objpkg = filepath.Join(testDir, "main.a") a.objpkg = filepath.Join(testDir, "main.a")
a.target = filepath.Join(testDir, "test.out") + b.exe a.target = filepath.Join(testDir, testBinary) + b.exe
pmainAction := a pmainAction := a
if testC { if testC {
...@@ -421,7 +431,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, ...@@ -421,7 +431,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
f: (*builder).install, f: (*builder).install,
deps: []*action{pmainAction}, deps: []*action{pmainAction},
p: pmain, p: pmain,
target: "test.out" + b.exe, target: testBinary + b.exe,
} }
printAction = &action{p: p, deps: []*action{runAction}} // nop printAction = &action{p: p, deps: []*action{runAction}} // nop
} else { } else {
......
...@@ -79,7 +79,7 @@ var testFlagDefn = []*testFlagSpec{ ...@@ -79,7 +79,7 @@ var testFlagDefn = []*testFlagSpec{
// to have "test" before them, and reading the command line for the 6.out. // to have "test" before them, and reading the command line for the 6.out.
// Unfortunately for us, we need to do our own flag processing because go test // Unfortunately for us, we need to do our own flag processing because go test
// grabs some flags but otherwise its command line is just a holding place for // grabs some flags but otherwise its command line is just a holding place for
// test.out's arguments. // pkg.test's arguments.
// We allow known flags both before and after the package name list, // We allow known flags both before and after the package name list,
// to allow both // to allow both
// go test fmt -custom-flag-for-fmt-test // go test fmt -custom-flag-for-fmt-test
......
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