]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: fix corner case missed rebuild of binary
authorRuss Cox <rsc@golang.org>
Sun, 5 Nov 2017 21:09:46 +0000 (16:09 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 6 Nov 2017 15:37:59 +0000 (15:37 +0000)
If the only thing changing in the binary is the embedded main.a action ID,
go install was declining to install the binary, but go list could see that the
binary needed reinstalling (was stale).

Fixes #22531.

Change-Id: I4a53b0ebd4c34aad907bab7da571fada545f3c6f
Reviewed-on: https://go-review.googlesource.com/76014
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/cmd/go/go_test.go
src/cmd/go/internal/work/exec.go

index 854de7968ffb433a1168df55faedc035381d49f7..1c06ad0afb0c67bf7aff50106babbca8a36893d0 100644 (file)
@@ -4740,7 +4740,34 @@ func TestBuildCache(t *testing.T) {
 
        tg.run("build", "-o", os.DevNull, "-x", "complex")
        tg.grepStderr(`[\\/]link|gccgo`, "did not run linker")
+}
 
+func TestIssue22531(t *testing.T) {
+       if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") {
+               t.Skip("GODEBUG gocacheverify")
+       }
+       tg := testgo(t)
+       defer tg.cleanup()
+       tg.parallel()
+       tg.makeTempdir()
+       tg.setenv("GOPATH", tg.tempdir)
+       tg.setenv("GOCACHE", filepath.Join(tg.tempdir, "cache"))
+       tg.tempFile("src/m/main.go", "package main /* c1 */; func main() {}\n")
+       tg.run("install", "-x", "m")
+       tg.run("list", "-f", "{{.Stale}}", "m")
+       tg.grepStdout("false", "reported m as stale after install")
+       tg.run("tool", "buildid", filepath.Join(tg.tempdir, "bin/m"+exeSuffix))
+
+       // The link action ID did not include the full main build ID,
+       // even though the full main build ID is written into the
+       // eventual binary. That caused the following install to
+       // be a no-op, thinking the gofmt binary was up-to-date,
+       // even though .Stale could see it was not.
+       tg.tempFile("src/m/main.go", "package main /* c2 */; func main() {}\n")
+       tg.run("install", "-x", "m")
+       tg.run("list", "-f", "{{.Stale}}", "m")
+       tg.grepStdout("false", "reported m as stale after reinstall")
+       tg.run("tool", "buildid", filepath.Join(tg.tempdir, "bin/m"+exeSuffix))
 }
 
 func TestTestCache(t *testing.T) {
index da4b5306e9b099f72aa553a14c766525ad458e59..7a4e62b0a4466fa4dca187ea3395eddd9f679bfb 100644 (file)
@@ -690,6 +690,11 @@ func (b *Builder) linkActionID(a *Action) cache.ActionID {
                                }
                                fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(buildID))
                        }
+                       // Because we put package main's full action ID into the binary's build ID,
+                       // we must also put the full action ID into the binary's action ID hash.
+                       if p1.Name == "main" {
+                               fmt.Fprintf(h, "packagemain %s\n", a1.buildID)
+                       }
                        if p1.Shlib != "" {
                                fmt.Fprintf(h, "pakageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib)))
                        }