-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Description
I've noticed that the /usr/local/bin/rustc has several dylib load commands for various rust libraries which have incorrect/nonexistent paths prefixed to them.
There are two points I'd like to bring up, the first being much more serious.
Bad Paths
In my setup various tools all report that /usr/local/bin/rustc loads/requires the following dynamic libraries:
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_driver-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_trans-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_privacy-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_borrowck-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_resolve-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_lint-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_typeck-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libflate-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_data_structures-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libarena-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libgraphviz-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libgetopts-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librbml-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_back-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libsyntax-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libserialize-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libterm-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/liblog-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libfmt_macros-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_llvm-198068b3.dylib
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libstd-198068b3.dylib
/usr/lib/libSystem.B.dylib
/usr/lib/libedit.3.dylib
/usr/lib/libc++.1.dylib
However, most of these (the rust libs) appear to be an artifact from the initial compilation build (on a side note, non-absolute paths in OSX typically should have an @rpath or @install_path prefixed to the path, etc.) . If you run:
DYLD_PRINT_LIBRARIES=true /usr/local/bin/rustc --version
you will notice all of the libraries actually get bound to /usr/local/lib/<name of dylib>. This only accidentally works, because dyld's default library search path(s) are:
$(HOME)/lib:/usr/local/lib:/lib:/usr/lib
and when interpreting a binary if dyld fails to find a library at the specified LC_LOAD_DYLIB path, it then takes the basename of the library with the bad path, e.g.:
x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libstd-198068b3.dylib -> libstd-198068b3.dylib
and looks for that dynamic library in the default path list; in our case it just so happens the libraries were installed to /usr/local/lib, so it finds them and runs as normal. If they were installed to a nonstandard path, /usr/local/bin/rustc would fail to run with something like:
dyld: Library not loaded: x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libstd-198068b3.dylib
Referenced from: /usr/local/bin/rustc
Reason: image not found
Trace/BPT trap: 5
You can verify this by moving /usr/local/lib/libstd-198068b3.dylib somewhere else (don't do this unless you know how to undue it), or by manually editing the basename of the imported libraries in the rustc binary (don't do this either unless you know how to undo it); either case will fail with an error similar to the above.
Therefore /usr/local/bin/rustc is only accidentally running correctly on OSX as of this writing.
If /usr/local/lib/ is the preferred location for rust libraries (and why not), then I highly suggest outputting LC_LOAD_DYLIB paths like /usr/local/lib/libstd-198068b3.dylib, etc.
If you want this dynamic or configurable, then I suggest using @rpath although this adds more complexity; more information can be found at the Apple official documentation.
Too Many Libraries
This is a less serious issue, but I believe most of the libraries printed above are actually not required to run rustc on OSX. Please correct me if I'm wrong, but it looks like the only imports in rustc are:
2038 __ZN4main20h62bf81b281987584efdE (8) ~> x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/librustc_driver-198068b3.dylib
2040 __ZN2rt10lang_start20hd654f015947477d622wE (8) ~> x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libstd-198068b3.dylib
2048 _rust_stack_exhausted (8) ~> x86_64-apple-darwin/stage1/lib/rustlib/x86_64-apple-darwin/lib/libstd-198068b3.dylib
2050 _exit (8) ~> /usr/lib/libSystem.B.dylib
2028 dyld_stub_binder (8) -> /usr/lib/libSystem.B.dylib
Hence, the minimal set of dynamic libraries required is:
/usr/local/lib/librustc_driver-198068b3.dylib
/usr/local/lib/libstd-198068b3.dylib
/usr/lib/libSystem.B.dylib
which I believe closely matches the library dependencies for the GNU/Linux rustc distribution.