From bc724d51d560bcee872cfed8ed953db0f60af045 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Wed, 26 Jan 2022 09:18:14 -0500 Subject: [PATCH] cmd/go: avoid recording GOROOT_FINAL in precompiled C archives 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 Run-TryBot: Bryan Mills Reviewed-by: Russ Cox TryBot-Result: Gopher Robot --- src/cmd/go/internal/work/exec.go | 16 ++++++++-------- .../testdata/script/cgo_stale_precompiled.txt | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 src/cmd/go/testdata/script/cgo_stale_precompiled.txt diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index ccd5aee221bd04..48a74458bdaf59 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -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) { @@ -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. @@ -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) } } diff --git a/src/cmd/go/testdata/script/cgo_stale_precompiled.txt b/src/cmd/go/testdata/script/cgo_stale_precompiled.txt new file mode 100644 index 00000000000000..cda804070a3ee2 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_stale_precompiled.txt @@ -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