mirror of
https://github.com/golang/go
synced 2024-11-24 22:57:57 -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:
parent
671862747e
commit
9d7076b178
@ -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>
|
||||||
|
@ -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])
|
exe := elem[:len(elem)-len(".go")] + exeSuffix
|
||||||
*buildO = elem[:len(elem)-len(".go")] + exeSuffix
|
if *buildO == "" {
|
||||||
} else {
|
*buildO = exe
|
||||||
|
}
|
||||||
|
if gobin != "" {
|
||||||
|
pkg.target = filepath.Join(gobin, exe)
|
||||||
|
}
|
||||||
|
} 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
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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 = gobin
|
bp.BinDir = gorootBin
|
||||||
|
if gobin != "" {
|
||||||
|
bp.BinDir = gobin
|
||||||
|
}
|
||||||
bp.Root = goroot
|
bp.Root = goroot
|
||||||
bp.SrcRoot = gorootSrc
|
bp.SrcRoot = gorootSrc
|
||||||
p := new(Package)
|
p := new(Package)
|
||||||
|
@ -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
|
||||||
|
5
src/cmd/go/testdata/src/go-cmd-test/helloworld.go
vendored
Normal file
5
src/cmd/go/testdata/src/go-cmd-test/helloworld.go
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("hello world")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user