Hi.

Very soon now the way rustc links crates dynamically is going to change[1], and it will impact the way you work with Rust in some important cases. The TL;DR is that rustc will no longer encode RPATH information in the binaries it produces, so the dynamic linker will be less likely to find the dynamic library (.so, .dylib) dependencies; in some scenarios people will need to use LD_LIBRARY_PATH or rely on higher-level tooling to arrange for libraries to be discovered by the dynamic linker at runtime.

[1]: https://github.com/rust-lang/rust/pull/14832

# Background

When the OS loads an executable, the dynamic linker searches some set of paths for it's dynamic library dependencies. If it doesn't find them, the program doesn't run, and for the most part the dynamic linker only searches a few system-defined locations, meaning that you're uninstalled development libraries won't be discovered by default. This is a common minor annoyance that is often solved by setting `LD_LIBRARY_PATH` to include the directories containing the dependencies.

Long ago Rust tried to solve this annoyance with RPATH. With RPATH you encode potential directories for the dynamic linker to search for dependencies *inside* the dependent libraries. rustc by default puts a few strategically-crafted RPATHs in its binaries that for the most part make the dynamic loading 'just work'.

Over time though we've concluded that we should not be doing this.

Firstly, this mechanism just doesn't work on Windows. For a while we tried to come up with a hack to simulate the behavior on Windows, but if there are any possibilities there they are very ugly and out of place in a language like Rust that tries not to do too much magic behind the scenes. As it stands now, the models on Unix and Windows are very different, which is a difficult discrepancy to justify.

Secondly, using RPATH is widely considered a bad practice. The primary risk with RPATH is that an attacker will place a substitute library on a known RPATH, injecting malicious code. I believe there are other considerations as well.

Finally, this behavior is inconsistent with other low-level languages, and inconsistent with the direction we've been moving in for e.g. library versioning. In general the user, or tools higher in the stack, should be in control over how they use their binaries, and Rust shouldn't be enforcing too much policy after compile-time.

So we're turning it off. The previous behavior can be restored by passing --rpath to rustc, or re-enabled for the Rust distribution itself by passing --enable-rpath to configure.

# Impact

Because static linking is the default in Rust, *by default* this change should have no impact on casual and new users unless they are explicitly opting in to dynamic linking.

Dynamic libraries installed as part of the Rust distribution should continue to be discovered correctly by the dynamic linker, modulo some potential bugs.

*Running rustc directly from the build directory will no longer work by default*. To do this either set LD_LIBRARY_PATH or pass --enable-rpath to the configure script.

Installing rustc to non-default locations will result in an installation that puts some important libraries in a location the dynamic linker won't find, will need to be compensated for with LD_LIBRARY_PATH.

Rust executables that link to dynamic Rust libraries outside of the system paths will not run without LD_LIBRARY_PATH.

Thanks. Have a nice day.





_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to