Search code examples
pythonmacosdynamic-linkingdylib

Problem loading dylib libraries in python with macOS


I know that similar questions have been asked many times, but I could not find a solution that worked in my case. I am a newbie with macOS, and for sure I'm missing something on how dynamic linking works in Mac. I must import a dylib library in python, which in turn should import another library. Here are the relevant files, environment variables and parts of the code:

$ echo $DYLD_LIBRARY_PATH 
/usr/local/lib/:/Developer/NVIDIA/CUDA-10.2/lib

$ ls /Developer/NVIDIA/CUDA-10.2/lib/libcurand.*
/Developer/NVIDIA/CUDA-10.2/lib/libcurand.10.dylib
/Developer/NVIDIA/CUDA-10.2/lib/libcurand.dylib

$ ls -al /usr/local/lib/libcurand.*
lrwxr-xr-x  1 golosio  admin  50 Feb 24 09:55 /usr/local/lib/libcurand.10.dylib -> /Developer/NVIDIA/CUDA-10.2/lib/libcurand.10.dylib
lrwxr-xr-x  1 golosio  admin  47 Feb 24 09:55 /usr/local/lib/libcurand.dylib -> /Developer/NVIDIA/CUDA-10.2/lib/libcurand.dylib

$ ls -al /usr/local/lib/libneurongpu.*
-rwxr-xr-x  1 root  admin  4496 Feb 24 10:32 /usr/local/lib/libneurongpu.0.dylib
lrwxr-xr-x  1 root  admin    20 Feb 24 10:32 /usr/local/lib/libneurongpu.dylib -> libneurongpu.0.dylib
-rwxr-xr-x  1 root  admin   953 Feb 24 10:32 /usr/local/lib/libneurongpu.la

$ python

>>> import ctypes

>>> lib_path="/usr/local/lib/libneurongpu.dylib"

>>> _neurongpu=ctypes.CDLL(lib_path)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 366, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(/usr/local/lib/libneurongpu.dylib, 6): Library not loaded: @rpath/libcurand.10.dylib
  Referenced from: /usr/local/lib/libneurongpu.dylib
  Reason: image not found

I would like to understand not only what I should do to import the libraries, but also why what I am doing is not working.


Solution

  • libneurongpu is calling a sub library libcurand via an @rpath and not finding it wherever it’s looking. Try an otool -l /usr/local/lib/libneurongpu.0.dylib to see the @rpath. Then you may wish to adjust the library to call the sub library from the correct location.

    There are two options.

    1. Remove the @rpath in the library path. install_name_tool -change @rpath/libcurand.10.dylib libcurand.10.dylib /usr/local/lib/libneurongpu.0.dylib This will search the same directory as the calling library.

    2. Set the @rpath (or add another) to the correct directory. install_name_tool -add_rpath /usr/local/bin /usr/local/lib/libneurongpu.0.dylib