From 91c82ff7c972d0bd6f67d49e11bcba25e7eb287e Mon Sep 17 00:00:00 2001 From: Russ Cox <rsc@golang.org> Date: Sun, 5 Mar 2023 13:05:25 -0500 Subject: [PATCH] cmd/dist: reproducibility fixes Fix a few lingering reproducibility problems. - Do not set CC during go install std if it is unset, so that the automatic disabling of cgo in cmd/go can run. - Since CC is not necessary, remove code insisting on it. - Use a fixed quoting algorithm instead of %q from the bootstrap toolchain, which can differ from release to release. - Remove go_bootstrap tool successfully on Windows. For #24904. Change-Id: I5c29ba6a8592e93bfab37f123b69f55c02f12ce3 Reviewed-on: https://go-review.googlesource.com/c/go/+/475377 Auto-Submit: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Bryan Mills <bcmills@google.com> --- src/cmd/dist/build.go | 13 +++++-------- src/cmd/dist/buildgo.go | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index 1c63c6ebc7b..343f0ce332f 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -313,6 +313,9 @@ var clangos = []string{ // compilerEnvLookup returns the compiler settings for goos/goarch in map m. // kind is "CC" or "CXX". func compilerEnvLookup(kind string, m map[string]string, goos, goarch string) string { + if !needCC() { + return "" + } if cc := m[goos+"/"+goarch]; cc != "" { return cc } @@ -1568,7 +1571,7 @@ func cmdbootstrap() { } // Remove go_bootstrap now that we're done. - xremove(pathf("%s/go_bootstrap", tooldir)) + xremove(pathf("%s/go_bootstrap"+exe, tooldir)) if goos == "android" { // Make sure the exec wrapper will sync a fresh $GOROOT to the device. @@ -1740,13 +1743,7 @@ var firstClass = map[string]bool{ } func needCC() bool { - switch os.Getenv("CGO_ENABLED") { - case "1": - return true - case "0": - return false - } - return cgoEnabled[gohostos+"/"+gohostarch] + return os.Getenv("CGO_ENABLED") == "1" } func checkCC() { diff --git a/src/cmd/dist/buildgo.go b/src/cmd/dist/buildgo.go index 7f1bc0105e0..d6a3b812143 100644 --- a/src/cmd/dist/buildgo.go +++ b/src/cmd/dist/buildgo.go @@ -63,11 +63,11 @@ func defaultCCFunc(name string, defaultcc map[string]string) string { } sort.Strings(keys) for _, k := range keys { - fmt.Fprintf(&buf, "\tcase %q:\n\t\treturn %q\n", k, defaultcc[k]) + fmt.Fprintf(&buf, "\tcase %s:\n\t\treturn %s\n", quote(k), quote(defaultcc[k])) } fmt.Fprintf(&buf, "\t}\n") if cc := defaultcc[""]; cc != "" { - fmt.Fprintf(&buf, "\treturn %q\n", cc) + fmt.Fprintf(&buf, "\treturn %s\n", quote(cc)) } else { clang, gcc := "clang", "gcc" if strings.HasSuffix(name, "CXX") { @@ -79,12 +79,12 @@ func defaultCCFunc(name string, defaultcc map[string]string) string { if i > 0 { fmt.Fprintf(&buf, ", ") } - fmt.Fprintf(&buf, "%q", os) + fmt.Fprintf(&buf, "%s", quote(os)) } fmt.Fprintf(&buf, ":\n") - fmt.Fprintf(&buf, "\t\treturn %q\n", clang) + fmt.Fprintf(&buf, "\t\treturn %s\n", quote(clang)) fmt.Fprintf(&buf, "\t}\n") - fmt.Fprintf(&buf, "\treturn %q\n", gcc) + fmt.Fprintf(&buf, "\treturn %s\n", quote(gcc)) } fmt.Fprintf(&buf, "}\n") @@ -105,7 +105,7 @@ func mkzosarch(dir, file string) { fmt.Fprintf(&buf, "package cfg\n\n") fmt.Fprintf(&buf, "var OSArchSupportsCgo = map[string]bool{\n") for _, plat := range list { - fmt.Fprintf(&buf, "\t%q: %v,\n", plat, cgoEnabled[plat]) + fmt.Fprintf(&buf, "\t%s: %v,\n", quote(plat), cgoEnabled[plat]) } fmt.Fprintf(&buf, "}\n") @@ -133,11 +133,11 @@ func mkzcgo(dir, file string) { fmt.Fprintln(&buf) fmt.Fprintf(&buf, "package build\n") fmt.Fprintln(&buf) - fmt.Fprintf(&buf, "const defaultCGO_ENABLED = %q\n", os.Getenv("CGO_ENABLED")) + fmt.Fprintf(&buf, "const defaultCGO_ENABLED = %s\n", quote(os.Getenv("CGO_ENABLED"))) fmt.Fprintln(&buf) fmt.Fprintf(&buf, "var cgoEnabled = map[string]bool{\n") for _, plat := range list { - fmt.Fprintf(&buf, "\t%q: true,\n", plat) + fmt.Fprintf(&buf, "\t%s: true,\n", quote(plat)) } fmt.Fprintf(&buf, "}\n") @@ -156,7 +156,28 @@ func mktzdata(dir, file string) { fmt.Fprintln(&buf) fmt.Fprintf(&buf, "package tzdata\n") fmt.Fprintln(&buf) - fmt.Fprintf(&buf, "const zipdata = %q\n", zip) + fmt.Fprintf(&buf, "const zipdata = %s\n", quote(zip)) writefile(buf.String(), file, writeSkipSame) } + +// quote is like strconv.Quote but simpler and has output +// that does not depend on the exact Go bootstrap version. +func quote(s string) string { + const hex = "0123456789abcdef" + var out strings.Builder + out.WriteByte('"') + for i := 0; i < len(s); i++ { + c := s[i] + if 0x20 <= c && c <= 0x7E && c != '"' && c != '\\' { + out.WriteByte(c) + } else { + out.WriteByte('\\') + out.WriteByte('x') + out.WriteByte(hex[c>>4]) + out.WriteByte(hex[c&0xf]) + } + } + out.WriteByte('"') + return out.String() +} -- GitLab