Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: rpath should only be used when linking shared objects or executables #12115

Closed
binarycrusader opened this issue Aug 11, 2015 · 3 comments
Milestone

Comments

@binarycrusader
Copy link
Contributor

The TestCgoHandlesWlORIGIN test found in src/cmd/go/go_test.go fails on Solaris:

$ go test -v -run TestCgoHandlesWlORIGIN
=== RUN   TestCgoHandlesWlORIGIN
--- FAIL: TestCgoHandlesWlORIGIN (0.17s)
        go_test.go:251: running testgo [build origin]
        go_test.go:270: standard error:
        go_test.go:271: # origin
                ld: fatal: option '-rpath $ORIGIN' is incompatible with building a relocatable object
                collect2: error: ld returned 1 exit status

        go_test.go:280: go [build origin] failed unexpectedly: exit status 2
FAIL
exit status 1
FAIL    cmd/go  4.040s

Relocatable objects, which come from the compiler, or which are created with 'ld -r', aren't loadable
objects on their own. It doesn't make sense to give such a "non-final" object a runpath, so ld(1) on Solaris exits with an error message.

If this test were reworked for say, an executable or a shared library, then that would make more sense.

@binarycrusader
Copy link
Contributor Author

It's also possible that this is just a symptom of the cgo tool indiscriminately applying LDFLAGS at different parts of the build process and the test itself is "correct". I haven't investigated further yet.

@binarycrusader
Copy link
Contributor Author

So after further investigation, I've come to the conclusion that the real issue is not so much the test, as the fact that there seems to be no way to control when and how LDFLAGS are applied during the build process.

Some flags should only be applied when performing the linking step for a shared library or executable, etc. In other contexts, they're either invalid, or meaningless to apply (so should not be specified).

Go already manipulates the linker flags used depending on context, so perhaps something like this is sufficient:

diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 718edd2..fdf00f3 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -2972,6 +2972,12 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofi
                // See issue 8788 for details.
                case strings.HasPrefix(f, "-fsanitize="):
                        continue
+               // runpath flags not applicable unless building a shared
+               // library; see issue 12115 for details. Since rpath expects an
+               // argument, both it and the following argument are skipped.
+               case buildBuildmode != "c-shared" && strings.HasPrefix(f, "-Wl,-rpath"):
+                       i+= 2
+                       continue
                default:
                        bareLDFLAGS = append(bareLDFLAGS, f)
                }

However, it seems like there's a larger issue -- namely, that Go should likely offer finer control over when LDFLAGS are applied.

I welcome any feedback or suggestions others might have.

@binarycrusader binarycrusader changed the title cmd/go: TestCgoHandlesWlORIGIN fails on Solaris due to potentially faulty test cmd/go: rpath should only be used when linking shared objects or executables Aug 11, 2015
@ianlancetaylor ianlancetaylor added this to the Go1.6 milestone Aug 11, 2015
@gopherbot
Copy link

CL https://golang.org/cl/14674 mentions this issue.

@golang golang locked and limited conversation to collaborators Sep 27, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants