Commit 8f5f347e authored by Russ Cox's avatar Russ Cox

cmd/go: many improvements

* correct dependency calculations
* comment meaning of action fields
* new alias "std" like "all" but standard packages only
* add -o flag to 'go build'
* set up for parallel build (still serial)
* understand that import "C" depends on cgo, runtime/cgo

R=golang-dev, mikioh.mikioh
CC=golang-dev
https://golang.org/cl/5502055
parent 83610567
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -27,6 +27,9 @@ The special import path "all" expands to all package directories ...@@ -27,6 +27,9 @@ The special import path "all" expands to all package directories
found in all the GOPATH trees. For example, 'go list all' found in all the GOPATH trees. For example, 'go list all'
lists all the packages on the local system. lists all the packages on the local system.
The special import path "std" is like all but expands to just the
packages in the standard Go library.
An import path can also name a package to be downloaded from An import path can also name a package to be downloaded from
a remote repository. Run 'go help remote' for details. a remote repository. Run 'go help remote' for details.
......
...@@ -33,6 +33,7 @@ being passed to the template is: ...@@ -33,6 +33,7 @@ being passed to the template is:
ImportPath string // import path of package in dir ImportPath string // import path of package in dir
Dir string // directory containing package sources Dir string // directory containing package sources
Version string // version of installed package (TODO) Version string // version of installed package (TODO)
Stale bool // would 'go install' do anything for this package?
// Source files // Source files
GoFiles []string // .go source files (excluding CgoFiles) GoFiles []string // .go source files (excluding CgoFiles)
......
...@@ -185,8 +185,10 @@ func help(args []string) { ...@@ -185,8 +185,10 @@ func help(args []string) {
// importPaths returns the import paths to use for the given command line. // importPaths returns the import paths to use for the given command line.
func importPaths(args []string) []string { func importPaths(args []string) []string {
if len(args) == 1 && args[0] == "all" { if len(args) == 1 {
return allPackages() if args[0] == "all" || args[0] == "std" {
return allPackages(args[0])
}
} }
if len(args) == 0 { if len(args) == 0 {
return []string{"."} return []string{"."}
...@@ -236,10 +238,13 @@ func run(cmdline ...string) { ...@@ -236,10 +238,13 @@ func run(cmdline ...string) {
// allPackages returns all the packages that can be found // allPackages returns all the packages that can be found
// under the $GOPATH directories and $GOROOT. // under the $GOPATH directories and $GOROOT.
func allPackages() []string { func allPackages(what string) []string {
have := map[string]bool{ have := map[string]bool{
"builtin": true, // ignore pseudo-package that exists only for documentation "builtin": true, // ignore pseudo-package that exists only for documentation
} }
if !build.DefaultContext.CgoEnabled {
have["runtime/cgo"] = true // ignore during walk
}
var pkgs []string var pkgs []string
// Commands // Commands
...@@ -270,6 +275,9 @@ func allPackages() []string { ...@@ -270,6 +275,9 @@ func allPackages() []string {
}) })
for _, t := range build.Path { for _, t := range build.Path {
if what == "std" && !t.Goroot {
continue
}
src := t.SrcDir() + string(filepath.Separator) src := t.SrcDir() + string(filepath.Separator)
filepath.Walk(src, func(path string, fi os.FileInfo, err error) error { filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
if err != nil || !fi.IsDir() { if err != nil || !fi.IsDir() {
...@@ -281,15 +289,21 @@ func allPackages() []string { ...@@ -281,15 +289,21 @@ func allPackages() []string {
return filepath.SkipDir return filepath.SkipDir
} }
name := filepath.ToSlash(path[len(src):])
if what == "std" && strings.Contains(name, ".") {
return filepath.SkipDir
}
if have[name] {
return nil
}
_, err = build.ScanDir(path) _, err = build.ScanDir(path)
if err != nil { if err != nil {
return nil return nil
} }
name := filepath.ToSlash(path[len(src):])
if !have[name] {
pkgs = append(pkgs, name) pkgs = append(pkgs, name)
have[name] = true have[name] = true
}
// Avoid go/build test data. // Avoid go/build test data.
// TODO: Move it into a testdata directory. // TODO: Move it into a testdata directory.
......
This diff is collapsed.
...@@ -33,7 +33,7 @@ func runRun(cmd *Command, args []string) { ...@@ -33,7 +33,7 @@ func runRun(cmd *Command, args []string) {
var b builder var b builder
b.init(*runA, *runN, *runX) b.init(*runA, *runN, *runX)
p := goFilesPackage(args, "") p := goFilesPackage(args, "")
p.targ = "" // force rebuild - no up-to-date copy anywhere p.target = "" // must build - not up to date
a1 := b.action(modeBuild, modeBuild, p) a1 := b.action(modeBuild, modeBuild, p)
a := &action{f: (*builder).runProgram, deps: []*action{a1}} a := &action{f: (*builder).runProgram, deps: []*action{a1}}
b.do(a) b.do(a)
...@@ -42,6 +42,6 @@ func runRun(cmd *Command, args []string) { ...@@ -42,6 +42,6 @@ func runRun(cmd *Command, args []string) {
// runProgram is the action for running a binary that has already // runProgram is the action for running a binary that has already
// been compiled. We ignore exit status. // been compiled. We ignore exit status.
func (b *builder) runProgram(a *action) error { func (b *builder) runProgram(a *action) error {
run(a.deps[0].pkgbin) run(a.deps[0].target)
return nil return nil
} }
...@@ -228,10 +228,6 @@ func runTest(cmd *Command, args []string) { ...@@ -228,10 +228,6 @@ func runTest(cmd *Command, args []string) {
errorf("%s: %s", p, err) errorf("%s: %s", p, err)
continue continue
} }
if buildTest == nil {
// no test at all
continue
}
builds = append(builds, buildTest) builds = append(builds, buildTest)
runs = append(runs, runTest) runs = append(runs, runTest)
} }
...@@ -254,7 +250,9 @@ func runTest(cmd *Command, args []string) { ...@@ -254,7 +250,9 @@ func runTest(cmd *Command, args []string) {
func (b *builder) test(p *Package) (buildAction, runAction *action, err error) { func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
if len(p.info.TestGoFiles)+len(p.info.XTestGoFiles) == 0 { if len(p.info.TestGoFiles)+len(p.info.XTestGoFiles) == 0 {
return &action{p: p}, &action{f: (*builder).notest, p: p}, nil build := &action{p: p}
run := &action{f: (*builder).notest, p: p, deps: []*action{build}}
return build, run, nil
} }
// Build Package structs describing: // Build Package structs describing:
...@@ -292,6 +290,7 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) { ...@@ -292,6 +290,7 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
// $WORK/unicode/utf8/_test/unicode/utf8_test.a. // $WORK/unicode/utf8/_test/unicode/utf8_test.a.
testDir := filepath.Join(b.work, filepath.FromSlash(p.ImportPath+"/_test")) testDir := filepath.Join(b.work, filepath.FromSlash(p.ImportPath+"/_test"))
ptestObj := filepath.Join(testDir, filepath.FromSlash(p.ImportPath+".a")) ptestObj := filepath.Join(testDir, filepath.FromSlash(p.ImportPath+".a"))
pxtestObj := filepath.Join(testDir, filepath.FromSlash(p.ImportPath+"_test.a"))
// Create the directory for the .a files. // Create the directory for the .a files.
ptestDir, _ := filepath.Split(ptestObj) ptestDir, _ := filepath.Split(ptestObj)
...@@ -309,10 +308,15 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) { ...@@ -309,10 +308,15 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
ptest.GoFiles = nil ptest.GoFiles = nil
ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...) ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
ptest.GoFiles = append(ptest.GoFiles, p.info.TestGoFiles...) ptest.GoFiles = append(ptest.GoFiles, p.info.TestGoFiles...)
ptest.targ = "" // must rebuild ptest.target = ""
ptest.Imports = append(append([]string{}, p.info.Imports...), p.info.TestImports...) ptest.Imports = append(append([]string{}, p.info.Imports...), p.info.TestImports...)
ptest.imports = append(append([]*Package{}, p.imports...), imports...) ptest.imports = append(append([]*Package{}, p.imports...), imports...)
ptest.pkgdir = testDir ptest.pkgdir = testDir
a := b.action(modeBuild, modeBuild, ptest)
a.objdir = testDir + string(filepath.Separator)
a.objpkg = ptestObj
a.target = ptestObj
a.link = false
} else { } else {
ptest = p ptest = p
} }
...@@ -330,6 +334,11 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) { ...@@ -330,6 +334,11 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
imports: imports, imports: imports,
pkgdir: testDir, pkgdir: testDir,
} }
pxtest.imports = append(pxtest.imports, ptest)
a := b.action(modeBuild, modeBuild, pxtest)
a.objdir = testDir + string(filepath.Separator)
a.objpkg = pxtestObj
a.target = pxtestObj
} }
// Action for building test.out. // Action for building test.out.
...@@ -344,16 +353,19 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) { ...@@ -344,16 +353,19 @@ func (b *builder) test(p *Package) (buildAction, runAction *action, err error) {
if pxtest != nil { if pxtest != nil {
pmain.imports = append(pmain.imports, pxtest) pmain.imports = append(pmain.imports, pxtest)
} }
pmainAction := b.action(modeBuild, modeBuild, pmain) a := b.action(modeBuild, modeBuild, pmain)
pmainAction.pkgbin = filepath.Join(testDir, "test.out") a.objdir = testDir + string(filepath.Separator)
a.objpkg = filepath.Join(testDir, "main.a")
a.target = filepath.Join(testDir, "test.out") + b.exe
pmainAction := a
if testC { if testC {
// -c flag: create action to copy binary to ./test.out. // -c flag: create action to copy binary to ./test.out.
pmain.targ = "test.out"
runAction = &action{ runAction = &action{
f: (*builder).install, f: (*builder).install,
deps: []*action{pmainAction}, deps: []*action{pmainAction},
p: pmain, p: pmain,
target: "test.out" + b.exe,
} }
} else { } else {
// run test // run test
...@@ -372,8 +384,11 @@ var pass = []byte("\nPASS\n") ...@@ -372,8 +384,11 @@ var pass = []byte("\nPASS\n")
// runTest is the action for running a test binary. // runTest is the action for running a test binary.
func (b *builder) runTest(a *action) error { func (b *builder) runTest(a *action) error {
args := []string{a.deps[0].target}
args = append(args, testArgs...)
if b.nflag || b.xflag { if b.nflag || b.xflag {
b.showcmd("%s", strings.Join(append([]string{a.deps[0].pkgbin}, testArgs...), " ")) b.showcmd("", "%s", strings.Join(args, " "))
if b.nflag { if b.nflag {
return nil return nil
} }
...@@ -387,7 +402,7 @@ func (b *builder) runTest(a *action) error { ...@@ -387,7 +402,7 @@ func (b *builder) runTest(a *action) error {
return nil return nil
} }
cmd := exec.Command(a.deps[0].pkgbin, testArgs...) cmd := exec.Command(args[0], args[1:]...)
cmd.Dir = a.p.Dir cmd.Dir = a.p.Dir
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err == nil && (bytes.Equal(out, pass[1:]) || bytes.HasSuffix(out, pass)) { if err == nil && (bytes.Equal(out, pass[1:]) || bytes.HasSuffix(out, pass)) {
......
This diff is collapsed.
This diff is collapsed.
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