From: zhangjian Date: Thu, 26 Sep 2024 16:42:21 +0000 (+0000) Subject: cmd/go: make sure the linker for shared doesn't include tempdir path X-Git-Tag: go1.24rc1~708 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1041c2cf019188954a4c2621f44270505968c291;p=gostls13.git cmd/go: make sure the linker for shared doesn't include tempdir path This is similar to CL 478196 and CL 477296, but this is for -buildmode=shared. When using "go install -buildmode=shared std", because the gold linker is used by default on Linux arm64, it will cause temporary paths to be included in libstd.so. Based on the changes of CL 478196, I speculate that this may also have issues on other platforms. So, this change is for all platform. Fixes #69464 Change-Id: I4493c82be030186e61aef597ea0e6f43bcf95a32 GitHub-Last-Rev: ee40cf81acf70f553bfc63a21a41ce0174857043 GitHub-Pull-Request: golang/go#69394 Reviewed-on: https://go-review.googlesource.com/c/go/+/612396 Reviewed-by: Michael Matloob LUCI-TryBot-Result: Go LUCI Reviewed-by: David Chase --- diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go index 1fbd267e09..a04794bbe5 100644 --- a/src/cmd/go/internal/work/gc.go +++ b/src/cmd/go/internal/work/gc.go @@ -714,7 +714,21 @@ func (gcToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, } ldflags = append(ldflags, d.Package.ImportPath+"="+d.Target) } - return b.Shell(root).run(".", targetPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", targetPath, "-importcfg", importcfg, ldflags) + + // On OS X when using external linking to build a shared library, + // the argument passed here to -o ends up recorded in the final + // shared library in the LC_ID_DYLIB load command. + // To avoid putting the temporary output directory name there + // (and making the resulting shared library useless), + // run the link in the output directory so that -o can name + // just the final path element. + // On Windows, DLL file name is recorded in PE file + // export section, so do like on OS X. + // On Linux, for a shared object, at least with the Gold linker, + // the output file path is recorded in the .gnu.version_d section. + dir, targetPath := filepath.Split(targetPath) + + return b.Shell(root).run(dir, targetPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", targetPath, "-importcfg", importcfg, ldflags) } func (gcToolchain) cc(b *Builder, a *Action, ofile, cfile string) error { diff --git a/src/cmd/go/testdata/script/build_shared_reproducible.txt b/src/cmd/go/testdata/script/build_shared_reproducible.txt new file mode 100644 index 0000000000..7e3bb348f3 --- /dev/null +++ b/src/cmd/go/testdata/script/build_shared_reproducible.txt @@ -0,0 +1,10 @@ +[!buildmode:shared] skip +[short] skip +[!cgo] skip '-buildmode=shared requires external linking' +[!GOOS:linux] skip + +env GO111MODULE=off +env CGO_ENABLED=1 +go install -a -trimpath -buildvcs=false -buildmode=shared -pkgdir=pkgdir1 runtime +go install -a -trimpath -buildvcs=false -buildmode=shared -pkgdir=pkgdir2 runtime +[GOOS:linux] cmp -q pkgdir1/libruntime.so pkgdir2/libruntime.so