mirror of
https://github.com/golang/go
synced 2024-11-12 10:00:25 -07:00
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 #8290. LGTM=r R=golang-codereviews, r, tracey.brendan CC=adg, golang-codereviews, iant https://golang.org/cl/151730045
This commit is contained in:
parent
e5afecbd0e
commit
8c3005c492
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
21
src/cmd/go/testgo.go
Normal file
21
src/cmd/go/testgo.go
Normal file
@ -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"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user