Michael Hudson-Doyle uploaded a change:
https://go-review.googlesource.com/18359
cmd/go: pass -no-pie along with -Wl,-r to gcc when supported
Go fails to build on a system which has PIE enabled by default like this:
/usr/bin/ld: -r and -pie may not be used together
collect2: error: ld returned 1 exit status
The only system I know that has this property right now is Ubuntu Xenial
running on s390x, which is hardly the most accessible system, but it's
planned
to enable this on amd64 soon too. The fix is to pass -no-pie along with
-Wl,-r
to the compiler, but unfortunately that flag is very new as well. So this
does
a test compile of a trivial file to see if the flag is supported.
Change-Id: I1345571142b7c3a96212e43297d19e84ec4a3d41
---
M src/cmd/go/build.go
1 file changed, 27 insertions(+), 0 deletions(-)
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 6c6d551..1559e43 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -2902,6 +2902,29 @@
return a
}
+// On systems with PIE (position independent executables) enabled by
default,
+// -no-pie must be passed when doing a partial link with -Wl,-r. But
-no-pie is
+// not supported by all compilers.
+func (b *builder) gccSupportsNoPie() bool {
+ src := filepath.Join(
b.work, "trivial.c")
+ if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
+ return false
+ }
+ cmdArgs := b.gccCmd(
b.work)
+ cmdArgs = append(cmdArgs, "-no-pie", "-c", "trivial.c")
+ if buildN || buildX {
+ b.showcmd(
b.work, "%s", joinUnambiguously(cmdArgs))
+ if buildN {
+ return false
+ }
+ }
+ cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
+ cmd.Dir =
b.work
+ cmd.Env = envForDir(cmd.Dir, os.Environ())
+ err := cmd.Run()
+ return err == nil
+}
+
// gccArchArgs returns arguments to pass to gcc based on the architecture.
func (b *builder) gccArchArgs() []string {
switch goarch {
@@ -3158,6 +3181,10 @@
}
ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
+ if b.gccSupportsNoPie() {
+ ldflags = append(ldflags, "-no-pie")
+ }
+
// We are creating an object file, so we don't want a build ID.
ldflags = b.disableBuildID(ldflags)
--
https://go-review.googlesource.com/18359