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

Binaries built with rustup rustc that link to dynamic libs fail to run #765

Open
sophiajt opened this issue Oct 20, 2016 · 6 comments
Open

Comments

@sophiajt
Copy link

If you build the rls using the rustup rust nighty, it will build successfully, but it won't properly set up the rpath. This causes the resulting rls to fail to run correctly on at least macOS and Windows (and possibly other platforms).

@sophiajt sophiajt reopened this Oct 20, 2016
@sophiajt
Copy link
Author

This is also true in Linux. If I try to run an RLS build with rustup's version of nightly, I get:

rls: error while loading shared libraries: librustc_driver-6eb85298.so: cannot open shared object file: No such file or directory

@sophiajt sophiajt changed the title RLS can't build correctly with nightly from rustup Binaries built with rustup rustc that link to dynamic libs fail to run Nov 16, 2016
@Diggsey
Copy link
Contributor

Diggsey commented Nov 17, 2016

I've looked into this a little, and I don't think there's anything more rustup can do here.

This is the situation:

  • rustup and a global rustc produce identical executables as output.
  • the RLS works with the global rustc, because rustc installs its shared libraries globally to a location already searched by ldd
  • uninstalling the global rustc will therefore cause existing builds of the rls to start failing

The problem is that the RLS has an implicit dependency on these shared libraries.

For developing the RLS, it's sufficient to use cargo run, or rustup run <toolchain> /path/to/rls, since in both cases rustup will automatically configure LD_LIBRARY_PATH for you to include the compiler's shared libraries for the current toolchain, and ldd will be happy.

Ideally, the RLS shouldn't continue to depend on the rust installation after it has been built. The best way to do this is to copy the shared libraries on which it depends into the output directory, and compile the binary with a relative RPATH, to produce an entirely self-contained set of binaries.

This is preferable to hard-coding the $HOME/.multirust/toolchains/... directory into the RPATH of the executable, because it won't cause things to retroactively break whenever you update or remove the toolchain used to build the binary.

I imagine that in future the RLS will be distributed by rustup as just another component of the rust installation. In that case the relative RPATH solution makes even more sense, since this is exactly how rustc itself works (and why rustc doesn't care that rustup has installed it somewhere non-global).

@nrc
Copy link
Member

nrc commented Nov 29, 2016

Ideally, the RLS shouldn't continue to depend on the rust installation after it has been built. The best way to do this is to copy the shared libraries on which it depends into the output directory, and compile the binary with a relative RPATH, to produce an entirely self-contained set of binaries.

This sounds like a good solution. How would we automate this? Can we instruct Cargo to do it declaratively or do we need to do this in the build script? Is there an example doing this already we can look at?

@sophiajt
Copy link
Author

cc @alexcrichton for ^

@steveklabnik
Copy link
Member

IIRC, you'd have to do the copying in a build script, and set the rpath in the profile section http://doc.crates.io/manifest.html#the-profile-sections

@shepmaster
Copy link
Member

Duplicate of #350 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants