Skip to content

Commit

Permalink
cmd/go: avoid recording GOROOT_FINAL in precompiled C archives
Browse files Browse the repository at this point in the history
C archives for packages in GOROOT are shipped along with binary
releases of the Go toolchain. Although we build the toolchain with
GOROOT_FINAL set, we don't know actually know where the release will
be installed: the user's real GOROOT can differ arbitrarily from our
GOROOT_FINAL.

(In the specific case of toolchains installed through golang.org/dl
wrappers, the release's GOROOT_FINAL is /usr/local/go but the actual
GOROOT to which the release is installed is
$HOME/sdk/$(go env GOVERSION).)

Fixes #50183
Updates #48319

Change-Id: If10a42f90c725300bbcb89c3b5b01a2d93ab6ef7
Reviewed-on: https://go-review.googlesource.com/c/go/+/380915
Trust: Bryan Mills <bcmills@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
Bryan C. Mills committed Jan 26, 2022
1 parent a9eedc0 commit 0f4bd92
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/cmd/go/internal/work/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,13 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
}
} else if p.Goroot {
// The Go compiler always hides the exact value of $GOROOT
// when building things in GOROOT, but the C compiler
// merely rewrites GOROOT to GOROOT_FINAL.
if len(p.CFiles) > 0 {
fmt.Fprintf(h, "goroot %s\n", cfg.GOROOT_FINAL)
}
// when building things in GOROOT.
//
// The C compiler does not, but for packages in GOROOT we rewrite the path
// as though -trimpath were set, so that we don't invalidate the build cache
// (and especially any precompiled C archive files) when changing
// GOROOT_FINAL. (See https://go.dev/issue/50183.)
//
// b.WorkDir is always either trimmed or rewritten to
// the literal string "/tmp/go-build".
} else if !strings.HasPrefix(p.Dir, b.WorkDir) {
Expand Down Expand Up @@ -2337,7 +2339,7 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s
// directives pointing to the source directory. It should not generate those
// when -trimpath is enabled.
if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
if cfg.BuildTrimpath {
if cfg.BuildTrimpath || p.Goroot {
// Keep in sync with Action.trimpath.
// The trimmed paths are a little different, but we need to trim in the
// same situations.
Expand All @@ -2359,8 +2361,6 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s
to = filepath.Join("/_", toPath)
}
flags = append(flags[:len(flags):len(flags)], "-fdebug-prefix-map="+from+"="+to)
} else if p.Goroot && cfg.GOROOT_FINAL != cfg.GOROOT {
flags = append(flags[:len(flags):len(flags)], "-fdebug-prefix-map="+cfg.GOROOT+"="+cfg.GOROOT_FINAL)
}
}

Expand Down
17 changes: 17 additions & 0 deletions src/cmd/go/testdata/script/cgo_stale_precompiled.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Regression test for https://go.dev/issue/47215 and https://go.dev/issue/50183:
# A mismatched $GOROOT_FINAL or missing $CC caused the C dependencies of the net
# package to appear stale, and it could not be rebuilt due to a missing $CC.

[!cgo] skip

# Control case: net must not already be stale.
! stale net

# https://go.dev/issue/47215: a missing $(go env CC) caused the precompiled net to be stale.
[!plan9] env PATH='' # Guaranteed not to include $(go env CC)!
[plan9] env path=''
! stale net # issue #47215

# https://go.dev/issue/50183: a mismatched GOROOT_FINAL caused net to be stale.
env GOROOT_FINAL=$WORK${/}goroot
! stale net

0 comments on commit 0f4bd92

Please sign in to comment.