summaryrefslogtreecommitdiff
path: root/src/cmd/go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-09-26 14:41:26 -0400
committerRuss Cox <rsc@golang.org>2014-09-26 14:41:26 -0400
commit7c071adcac2d9ac390ed7d2bd12d23a29c2c29aa (patch)
tree1b4f802199f27eed022cdb2c4b264ad6af409c0d /src/cmd/go
parentb1818d8bb1b85e14f19cbc0b2c9b6c923240457a (diff)
downloadgo-7c071adcac2d9ac390ed7d2bd12d23a29c2c29aa.tar.gz
cmd/go: make build -a skip standard packages in Go releases
Today, 'go build -a my/pkg' and 'go install -a my/pkg' recompile not just my/pkg and all its dependencies that you wrote but also the standard library packages. Recompiling the standard library is problematic on some systems because the installed copy is not writable. The -a behavior means that you can't use 'go install -a all' or 'go install -a my/...' to rebuild everything after a Go release - the rebuild stops early when it cannot overwrite the installed standard library. During development work, however, you do want install -a to rebuild everything, because anything might have changed. Resolve the conflict by making the behavior of -a depend on whether we are using a released copy of Go or a devel copy. In the release copies, -a no longer applies to the standard library. In the devel copies, it still does. This is the latest in a long line of refinements to the "do I build this or not" logic. It is surely not the last. Fixes issue 8290. LGTM=r R=golang-codereviews, r, tracey.brendan CC=adg, golang-codereviews, iant https://codereview.appspot.com/151730045
Diffstat (limited to 'src/cmd/go')
-rw-r--r--src/cmd/go/build.go1
-rw-r--r--src/cmd/go/doc.go1
-rw-r--r--src/cmd/go/pkg.go18
-rwxr-xr-xsrc/cmd/go/test.bash28
-rw-r--r--src/cmd/go/testgo.go21
5 files changed, 67 insertions, 2 deletions
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 23ad765ba..9c7b42650 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -57,6 +57,7 @@ and test commands:
-a
force rebuilding of packages that are already up-to-date.
+ In Go releases, does not apply to the standard library.
-n
print the commands but do not run them.
-p n
diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go
index cffb53d99..8e2facd04 100644
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -76,6 +76,7 @@ and test commands:
-a
force rebuilding of packages that are already up-to-date.
+ In Go releases, does not apply to the standard library.
-n
print the commands but do not run them.
-p n
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index 4bbcc2b97..eafaa8ee6 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -14,6 +14,7 @@ import (
"os"
pathpkg "path"
"path/filepath"
+ "runtime"
"sort"
"strings"
"time"
@@ -685,6 +686,12 @@ func computeStale(pkgs ...*Package) {
}
}
+// The runtime version string takes one of two forms:
+// "go1.X[.Y]" for Go releases, and "devel +hash" at tip.
+// Determine whether we are in a released copy by
+// inspecting the version.
+var isGoRelease = !strings.HasPrefix(runtime.Version(), "go1")
+
// isStale reports whether package p needs to be rebuilt.
func isStale(p *Package, topRoot map[string]bool) bool {
if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") {
@@ -705,7 +712,16 @@ func isStale(p *Package, topRoot map[string]bool) bool {
return false
}
- if buildA || p.target == "" || p.Stale {
+ // If we are running a release copy of Go, do not rebuild the standard packages.
+ // They may not be writable anyway, but they are certainly not changing.
+ // This makes 'go build -a' skip the standard packages when using an official release.
+ // See issue 4106 and issue 8290.
+ pkgBuildA := buildA
+ if p.Standard && isGoRelease {
+ pkgBuildA = false
+ }
+
+ if pkgBuildA || p.target == "" || p.Stale {
return true
}
diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash
index bc2ce710a..128487619 100755
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -4,7 +4,7 @@
# license that can be found in the LICENSE file.
set -e
-go build -o testgo
+go build -tags testgo -o testgo
go() {
echo TEST ERROR: ran go, not testgo: go "$@" >&2
exit 2
@@ -71,6 +71,32 @@ if ! grep -q "/tool/.*/$linker" $d/err.out; then
fi
rm -r $d
+TEST 'go build -a in dev branch'
+./testgo install math || ok=false # should be up to date already but just in case
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+if ! TESTGO_IS_GO_RELEASE=0 ./testgo build -v -a math 2>$d/err.out; then
+ cat $d/err.out
+ ok=false
+elif ! grep -q runtime $d/err.out; then
+ echo "testgo build -a math in dev branch DID NOT build runtime, but should have"
+ cat $d/err.out
+ ok=false
+fi
+rm -r $d
+
+TEST 'go build -a in release branch'
+./testgo install math || ok=false # should be up to date already but just in case
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+if ! TESTGO_IS_GO_RELEASE=1 ./testgo build -v -a math 2>$d/err.out; then
+ cat $d/err.out
+ ok=false
+elif grep -q runtime $d/err.out; then
+ echo "testgo build -a math in dev branch DID build runtime, but should NOT have"
+ cat $d/err.out
+ ok=false
+fi
+rm -r $d
+
# Test local (./) imports.
testlocal() {
local="$1"
diff --git a/src/cmd/go/testgo.go b/src/cmd/go/testgo.go
new file mode 100644
index 000000000..01923f74b
--- /dev/null
+++ b/src/cmd/go/testgo.go
@@ -0,0 +1,21 @@
+// Copyright 2014 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.
+
+// This file contains extra hooks for testing the go command.
+// It is compiled into the Go binary only when building the
+// test copy; it does not get compiled into the standard go
+// command, so these testing hooks are not present in the
+// go command that everyone uses.
+
+// +build testgo
+
+package main
+
+import "os"
+
+func init() {
+ if v := os.Getenv("TESTGO_IS_GO_RELEASE"); v != "" {
+ isGoRelease = v == "1"
+ }
+}