diff options
author | Russ Cox <rsc@golang.org> | 2012-03-27 11:57:39 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2012-03-27 11:57:39 -0400 |
commit | 9d7076b178e3b688a8421a8ce02466a3701d31a0 (patch) | |
tree | 7319165ddb1e8d2a36073ecabbd0ef1753d2faf9 | |
parent | 671862747ef238f1713170f712e85d1cd6d46685 (diff) | |
download | go-9d7076b178e3b688a8421a8ce02466a3701d31a0.tar.gz go-9d7076b178e3b688a8421a8ce02466a3701d31a0.zip |
cmd/go: respect $GOBIN always
Another attempt at https://golang.org/cl/5754088.
Before, we only consulted $GOBIN for source code
found in $GOROOT, but that's confusing to explain
and less useful. The new behavior lets users set
GOBIN=$HOME/bin and have all go-compiled binaries
installed there.
Tested a few cases in test.bash.
Ran all.bash with and without $GOBIN and it works.
Even so, I expect it to break the builders,
like it did last time, we can debug from there.
Fixes #3269 (again).
Fixes #3396.
Fixes #3397.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5927051
-rw-r--r-- | doc/install-source.html | 5 | ||||
-rw-r--r-- | src/cmd/go/build.go | 34 | ||||
-rw-r--r-- | src/cmd/go/doc.go | 6 | ||||
-rw-r--r-- | src/cmd/go/help.go | 4 | ||||
-rw-r--r-- | src/cmd/go/pkg.go | 8 | ||||
-rwxr-xr-x | src/cmd/go/test.bash | 39 | ||||
-rw-r--r-- | src/cmd/go/testdata/src/go-cmd-test/helloworld.go | 5 |
7 files changed, 80 insertions, 21 deletions
diff --git a/doc/install-source.html b/doc/install-source.html index 82ff8e740d..4673850f42 100644 --- a/doc/install-source.html +++ b/doc/install-source.html @@ -393,11 +393,12 @@ For example, you should not set <code>$GOHOSTARCH</code> to <p><code>$GOBIN</code> <p> -The location where binaries from the main repository will be installed. -XXX THIS MAY CHANGE TO BE AN OVERRIDE EVEN FOR GOPATH ENTRIES XXX +The location where Go binaries will be installed. The default is <code>$GOROOT/bin</code>. After installing, you will want to arrange to add this directory to your <code>$PATH</code>, so you can use the tools. +If <code>$GOBIN</code> is set, the <a href="/cmd/go">go command</a> +installs all commands there. </p> <p><code>$GOARM</code> (arm, default=6)</p> diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index 16177c1277..4bb83f1618 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -74,6 +74,8 @@ The build flags are shared by the build, install, run, and test commands: more information about build tags. For more about specifying packages, see 'go help packages'. +For more about where packages and binaries are installed, +see 'go help gopath'. See also: go install, go get, go clean. `, @@ -304,19 +306,13 @@ const ( var ( goroot = filepath.Clean(runtime.GOROOT()) - gobin = defaultGobin() + gobin = os.Getenv("GOBIN") + gorootBin = filepath.Join(goroot, "bin") gorootSrcPkg = filepath.Join(goroot, "src/pkg") gorootPkg = filepath.Join(goroot, "pkg") gorootSrc = filepath.Join(goroot, "src") ) -func defaultGobin() string { - if s := os.Getenv("GOBIN"); s != "" { - return s - } - return filepath.Join(goroot, "bin") -} - func (b *builder) init() { var err error b.print = fmt.Print @@ -388,17 +384,23 @@ func goFilesPackage(gofiles []string) *Package { pkg.load(&stk, bp, err) pkg.localPrefix = dirToImportPath(dir) pkg.ImportPath = "command-line-arguments" + pkg.target = "" - if *buildO == "" { - if pkg.Name == "main" { - _, elem := filepath.Split(gofiles[0]) - *buildO = elem[:len(elem)-len(".go")] + exeSuffix - } else { + if pkg.Name == "main" { + _, elem := filepath.Split(gofiles[0]) + exe := elem[:len(elem)-len(".go")] + exeSuffix + if *buildO == "" { + *buildO = exe + } + if gobin != "" { + pkg.target = filepath.Join(gobin, exe) + } + } else { + if *buildO == "" { *buildO = pkg.Name + ".a" } } - pkg.target = "" - pkg.Target = "" + pkg.Target = pkg.target pkg.Stale = true computeStale(pkg) @@ -463,7 +465,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action return a } - if p.local { + if p.local && p.target == "" { // Imported via local path. No permanent target. mode = modeBuild } diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go index 162eecfcc9..4bfd5236d8 100644 --- a/src/cmd/go/doc.go +++ b/src/cmd/go/doc.go @@ -91,6 +91,8 @@ The build flags are shared by the build, install, run, and test commands: more information about build tags. For more about specifying packages, see 'go help packages'. +For more about where packages and binaries are installed, +see 'go help gopath'. See also: go install, go get, go clean. @@ -461,7 +463,9 @@ the final element, not the entire path. That is, the command with source in DIR/src/foo/quux is installed into DIR/bin/quux, not DIR/bin/foo/quux. The foo/ is stripped so that you can add DIR/bin to your PATH to get at the -installed commands. +installed commands. If the GOBIN environment variable is +set, commands are installed to the directory it names instead +of DIR/bin. Here's an example directory layout: diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go index 26640d833c..47ea0c7110 100644 --- a/src/cmd/go/help.go +++ b/src/cmd/go/help.go @@ -209,7 +209,9 @@ the final element, not the entire path. That is, the command with source in DIR/src/foo/quux is installed into DIR/bin/quux, not DIR/bin/foo/quux. The foo/ is stripped so that you can add DIR/bin to your PATH to get at the -installed commands. +installed commands. If the GOBIN environment variable is +set, commands are installed to the directory it names instead +of DIR/bin. Here's an example directory layout: diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go index 1a75019aca..30bbfad55a 100644 --- a/src/cmd/go/pkg.go +++ b/src/cmd/go/pkg.go @@ -222,6 +222,9 @@ func loadImport(path string, srcDir string, stk *importStack, importPos []token. // See issue 3268 for mistakes to avoid. bp, err := buildContext.Import(path, srcDir, 0) bp.ImportPath = importPath + if gobin != "" { + bp.BinDir = gobin + } p.load(stk, bp, err) if p.Error != nil && len(importPos) > 0 { pos := importPos[0] @@ -552,7 +555,10 @@ func loadPackage(arg string, stk *importStack) *Package { bp, err := build.ImportDir(filepath.Join(gorootSrc, arg), 0) bp.ImportPath = arg bp.Goroot = true - bp.BinDir = gobin + bp.BinDir = gorootBin + if gobin != "" { + bp.BinDir = gobin + } bp.Root = goroot bp.SrcRoot = gorootSrc p := new(Package) diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash index 5415351015..fe186d4bbc 100755 --- a/src/cmd/go/test.bash +++ b/src/cmd/go/test.bash @@ -8,6 +8,9 @@ go build -o testgo ok=true +unset GOPATH +unset GOBIN + # Test that error messages have file:line information # at beginning of line. for i in testdata/errmsg/*.go @@ -80,6 +83,42 @@ if ! ./testgo test ./testdata/testimport/*.go; then ok=false fi +# Test that without $GOBIN set, binaries get installed +# into the GOPATH bin directory. +rm -rf testdata/bin +if ! GOPATH=$(pwd)/testdata ./testgo install go-cmd-test; then + echo "go install go-cmd-test failed" + ok=false +elif ! test -x testdata/bin/go-cmd-test; then + echo "go install go-cmd-test did not write to testdata/bin/go-cmd-test" + ok=false +fi + +# And with $GOBIN set, binaries get installed to $GOBIN. +if ! GOBIN=$(pwd)/testdata/bin1 GOPATH=$(pwd)/testdata ./testgo install go-cmd-test; then + echo "go install go-cmd-test failed" + ok=false +elif ! test -x testdata/bin1/go-cmd-test; then + echo "go install go-cmd-test did not write to testdata/bin1/go-cmd-test" + ok=false +fi + +# Without $GOBIN set, installing a program outside $GOPATH should fail +# (there is nowhere to install it). +if ./testgo install testdata/src/go-cmd-test/helloworld.go; then + echo "go install testdata/src/go-cmd-test/helloworld.go should have failed, did not" + ok=false +fi + +# With $GOBIN set, should install there. +if ! GOBIN=$(pwd)/testdata/bin1 ./testgo install testdata/src/go-cmd-test/helloworld.go; then + echo "go install testdata/src/go-cmd-test/helloworld.go failed" + ok=false +elif ! test -x testdata/bin1/helloworld; then + echo "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld" + ok=false +fi + if $ok; then echo PASS else diff --git a/src/cmd/go/testdata/src/go-cmd-test/helloworld.go b/src/cmd/go/testdata/src/go-cmd-test/helloworld.go new file mode 100644 index 0000000000..002a5c740c --- /dev/null +++ b/src/cmd/go/testdata/src/go-cmd-test/helloworld.go @@ -0,0 +1,5 @@ +package main + +func main() { + println("hello world") +} |