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 ...