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.