mirror of
https://github.com/golang/go
synced 2024-11-14 20:20:30 -07:00
cmd/link/internal/ld: clean tmpdir obj timestamps
This patch changes the Go linker to "clean" (reset to Unix epoch) the timestamps on object files copied to the tmpdir that is presented to the external linker or archive tool. The intent is to improve build reproducibility on Darwin, where later versions of xcode seem to want to incorporate object file timestamps into the hash used for the final build ID (which precludes the possibility of having reproducible Go builds). Credit for this idea goes to Cherry (see https://github.com/golang/go/issues/64947#issuecomment-1887667189). Updates #64947. Change-Id: I2eb7dddff538e247122b04fdcf8a57c923f61201 Reviewed-on: https://go-review.googlesource.com/c/go/+/585355 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
c7c578cdf3
commit
3454ac0d63
@ -47,6 +47,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"cmd/internal/bio"
|
||||
"cmd/internal/goobj"
|
||||
@ -1268,6 +1269,22 @@ func hostlinksetup(ctxt *Link) {
|
||||
}
|
||||
}
|
||||
|
||||
// cleanTimeStamps resets the timestamps for the specified list of
|
||||
// existing files to the Unix epoch (1970-01-01 00:00:00 +0000 UTC).
|
||||
// We take this step in order to help preserve reproducible builds;
|
||||
// this seems to be primarily needed for external linking on on Darwin
|
||||
// with later versions of xcode, which (unfortunately) seem to want to
|
||||
// incorporate object file times into the final output file's build
|
||||
// ID. See issue 64947 for the unpleasant details.
|
||||
func cleanTimeStamps(files []string) {
|
||||
epocht := time.Unix(0, 0)
|
||||
for _, f := range files {
|
||||
if err := os.Chtimes(f, epocht, epocht); err != nil {
|
||||
Exitf("cannot chtimes %s: %v", f, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hostobjCopy creates a copy of the object files in hostobj in a
|
||||
// temporary directory.
|
||||
func (ctxt *Link) hostobjCopy() (paths []string) {
|
||||
@ -1360,9 +1377,14 @@ func (ctxt *Link) archive() {
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
argv = append(argv, "-X64")
|
||||
}
|
||||
godotopath := filepath.Join(*flagTmpdir, "go.o")
|
||||
cleanTimeStamps([]string{godotopath})
|
||||
hostObjCopyPaths := ctxt.hostobjCopy()
|
||||
cleanTimeStamps(hostObjCopyPaths)
|
||||
|
||||
argv = append(argv, *flagOutfile)
|
||||
argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
|
||||
argv = append(argv, ctxt.hostobjCopy()...)
|
||||
argv = append(argv, godotopath)
|
||||
argv = append(argv, hostObjCopyPaths...)
|
||||
|
||||
if ctxt.Debugvlog != 0 {
|
||||
ctxt.Logf("archive: %s\n", strings.Join(argv, " "))
|
||||
@ -1733,8 +1755,13 @@ func (ctxt *Link) hostlink() {
|
||||
argv = append(argv, compressDWARF)
|
||||
}
|
||||
|
||||
argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
|
||||
argv = append(argv, ctxt.hostobjCopy()...)
|
||||
hostObjCopyPaths := ctxt.hostobjCopy()
|
||||
cleanTimeStamps(hostObjCopyPaths)
|
||||
godotopath := filepath.Join(*flagTmpdir, "go.o")
|
||||
cleanTimeStamps([]string{godotopath})
|
||||
|
||||
argv = append(argv, godotopath)
|
||||
argv = append(argv, hostObjCopyPaths...)
|
||||
if ctxt.HeadType == objabi.Haix {
|
||||
// We want to have C files after Go files to remove
|
||||
// trampolines csects made by ld.
|
||||
|
Loading…
Reference in New Issue
Block a user