1
0
mirror of https://github.com/golang/go synced 2024-11-21 20:54:45 -07:00

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
This commit is contained in:
Russ Cox 2012-03-27 11:57:39 -04:00
parent 671862747e
commit 9d7076b178
7 changed files with 80 additions and 21 deletions

View File

@ -393,11 +393,12 @@ For example, you should not set <code>$GOHOSTARCH</code> to
<p><code>$GOBIN</code> <p><code>$GOBIN</code>
<p> <p>
The location where binaries from the main repository will be installed. The location where Go binaries will be installed.
XXX THIS MAY CHANGE TO BE AN OVERRIDE EVEN FOR GOPATH ENTRIES XXX
The default is <code>$GOROOT/bin</code>. The default is <code>$GOROOT/bin</code>.
After installing, you will want to arrange to add this After installing, you will want to arrange to add this
directory to your <code>$PATH</code>, so you can use the tools. 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>
<p><code>$GOARM</code> (arm, default=6)</p> <p><code>$GOARM</code> (arm, default=6)</p>

View File

@ -74,6 +74,8 @@ The build flags are shared by the build, install, run, and test commands:
more information about build tags. more information about build tags.
For more about specifying packages, see 'go help packages'. 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. See also: go install, go get, go clean.
`, `,
@ -304,19 +306,13 @@ const (
var ( var (
goroot = filepath.Clean(runtime.GOROOT()) goroot = filepath.Clean(runtime.GOROOT())
gobin = defaultGobin() gobin = os.Getenv("GOBIN")
gorootBin = filepath.Join(goroot, "bin")
gorootSrcPkg = filepath.Join(goroot, "src/pkg") gorootSrcPkg = filepath.Join(goroot, "src/pkg")
gorootPkg = filepath.Join(goroot, "pkg") gorootPkg = filepath.Join(goroot, "pkg")
gorootSrc = filepath.Join(goroot, "src") 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() { func (b *builder) init() {
var err error var err error
b.print = fmt.Print b.print = fmt.Print
@ -388,17 +384,23 @@ func goFilesPackage(gofiles []string) *Package {
pkg.load(&stk, bp, err) pkg.load(&stk, bp, err)
pkg.localPrefix = dirToImportPath(dir) pkg.localPrefix = dirToImportPath(dir)
pkg.ImportPath = "command-line-arguments" pkg.ImportPath = "command-line-arguments"
pkg.target = ""
if *buildO == "" {
if pkg.Name == "main" { if pkg.Name == "main" {
_, elem := filepath.Split(gofiles[0]) _, elem := filepath.Split(gofiles[0])
*buildO = elem[:len(elem)-len(".go")] + exeSuffix exe := elem[:len(elem)-len(".go")] + exeSuffix
if *buildO == "" {
*buildO = exe
}
if gobin != "" {
pkg.target = filepath.Join(gobin, exe)
}
} else { } else {
if *buildO == "" {
*buildO = pkg.Name + ".a" *buildO = pkg.Name + ".a"
} }
} }
pkg.target = "" pkg.Target = pkg.target
pkg.Target = ""
pkg.Stale = true pkg.Stale = true
computeStale(pkg) computeStale(pkg)
@ -463,7 +465,7 @@ func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action
return a return a
} }
if p.local { if p.local && p.target == "" {
// Imported via local path. No permanent target. // Imported via local path. No permanent target.
mode = modeBuild mode = modeBuild
} }

View File

@ -91,6 +91,8 @@ The build flags are shared by the build, install, run, and test commands:
more information about build tags. more information about build tags.
For more about specifying packages, see 'go help packages'. 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. 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 command with source in DIR/src/foo/quux is installed into
DIR/bin/quux, not DIR/bin/foo/quux. The foo/ is stripped 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 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: Here's an example directory layout:

View File

@ -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 command with source in DIR/src/foo/quux is installed into
DIR/bin/quux, not DIR/bin/foo/quux. The foo/ is stripped 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 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: Here's an example directory layout:

View File

@ -222,6 +222,9 @@ func loadImport(path string, srcDir string, stk *importStack, importPos []token.
// See issue 3268 for mistakes to avoid. // See issue 3268 for mistakes to avoid.
bp, err := buildContext.Import(path, srcDir, 0) bp, err := buildContext.Import(path, srcDir, 0)
bp.ImportPath = importPath bp.ImportPath = importPath
if gobin != "" {
bp.BinDir = gobin
}
p.load(stk, bp, err) p.load(stk, bp, err)
if p.Error != nil && len(importPos) > 0 { if p.Error != nil && len(importPos) > 0 {
pos := 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, err := build.ImportDir(filepath.Join(gorootSrc, arg), 0)
bp.ImportPath = arg bp.ImportPath = arg
bp.Goroot = true bp.Goroot = true
bp.BinDir = gorootBin
if gobin != "" {
bp.BinDir = gobin bp.BinDir = gobin
}
bp.Root = goroot bp.Root = goroot
bp.SrcRoot = gorootSrc bp.SrcRoot = gorootSrc
p := new(Package) p := new(Package)

View File

@ -8,6 +8,9 @@ go build -o testgo
ok=true ok=true
unset GOPATH
unset GOBIN
# Test that error messages have file:line information # Test that error messages have file:line information
# at beginning of line. # at beginning of line.
for i in testdata/errmsg/*.go for i in testdata/errmsg/*.go
@ -80,6 +83,42 @@ if ! ./testgo test ./testdata/testimport/*.go; then
ok=false ok=false
fi 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 if $ok; then
echo PASS echo PASS
else else

View File

@ -0,0 +1,5 @@
package main
func main() {
println("hello world")
}