How to find which shared library is missing?
When I use ldd
on Linux it tells me right away if something is missing, i.e.
ldd -d some_lib.so
libexample.so => not found
libex.2.so => not found
libm.so.6 => /lib/libm.so.6 (0xf5860000)
libdl.so.2 => /lib/libdl.so.2 (0xf785b000)
libc.so.6 => /lib/libc.so.6 (0xf78a9000)
/lib/ld-linux.so.2 (0x46b4c000)
On Mac OS there is no ldd
and people recommend using otool -L
, but that shows which shared libraries are expected, not weather or not they are there. Another approach would be to use dtruss
, but it requires sudo, and it least in my experience the application behaves very differently when it is being dtrussed, and it fails for an entirely different reason (and before it gets to trying to load the troublesome .dylib).
So if you suspect that a shared library is missing, what is the standard approach to finding which one it is on the Mac?
Solution 1:
The easiest way is simply to run the program. If the shared library is missing, you'll get an output similar to this:
dyld: Library not loaded: mylib.dylib
Referenced from: /path/to/myprogram
Reason: image not found
Abort trap: 6
You can also run the following command:
objdump -r --dylibs-used /path/to/myprogram
This will essentially give you the same output as the otool
command, you've mentioned in your question (many years ago, Apple replaced the old toolchain with a llvm based one, so otool on recent macOS versions will just call objdump). The program lists the shared libraries that the program expects - you can then check manually if you actually have those files. I.e. is there a file in that path with that name, is it readable by your user and does it contain a valid dynamic library.
Solution 2:
The dynamic link editor dyld
prints all dylibs loaded
if you export
(sh) ot setenv
(csh)
these variables:
export DYLD_PRINT_LIBRARIES=1
export DYLD_PRINT_RPATHS=1
export DYLD_PRINT_TO_FILE=dyld.log
myprogram
Here's an example dyld.log; otool -L
the last "unloaded" lib
to see what it wants to link to.
...
dyld: loaded: /opt/local/mac/big/py3/lib/python3.7/site-packages/scikits/umfpack/__umfpack.cpython-37m-darwin.so
dyld: loaded: /opt/local/mac/big/SuiteSparse/lib/libumfpack.5.7.8.dylib
dyld: unloaded: /opt/local/mac/big/py3/lib/python3.7/site-packages/scikits/umfpack/__umfpack.cpython-37m-darwin.so
The manual page man dyld
lists dozens more switches.
There oughta be a better way ...