I'm running a Python script with the MacPorts version of Python (2.7), i.e, I've run:
port select --set python python27
However, when I run my script, it can't find a dylib in /opt/local/lib
:
ImportError: dlopen(/opt/local/lib/python2.7/site-packages/grgsm/_grgsm_swig.so, 2): Library not loaded: libgnuradio-grgsm.dylib
Referenced from: /opt/local/lib/python2.7/site-packages/grgsm/_grgsm_swig.so
Reason: image not found
The dylib in question resides here:
-rwxr-xr-x 1 root admin 816036 Dec 16 11:24 /opt/local/lib/libgnuradio-grgsm.dylib
Setting export DYLIB_LIBRARY_PATH=/opt/local/lib/
doesn't help in this case (nor should it really be necessary for each user on the system to set that environment variable). I've already run update_dyld_shared_cache
.
The Python module in question resides in /opt/local/lib/python2.7/site-packages
so I made a symlink to it in /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/
.
otool -L
on the loading .so
reports:
otool -L /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/grgsm/_grgsm_swig.so
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/grgsm/_grgsm_swig.so:
libgnuradio-grgsm.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libboost_filesystem-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libboost_system-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libboost_thread-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libgnuradio-runtime.3.7.8.1.dylib (compatibility version 3.7.8, current version 0.0.0)
/opt/local/lib/libgnuradio-pmt.3.7.8.1.dylib (compatibility version 3.7.8, current version 0.0.0)
/opt/local/lib/libvolk.1.1.1.dylib (compatibility version 1.1.1, current version 0.0.0)
/usr/local/lib/libosmocore.7.dylib (compatibility version 8.0.0, current version 8.0.0)
/usr/local/lib/libosmogsm.5.dylib (compatibility version 7.0.0, current version 7.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
Notice that the library in question doesn't have a path.
Best Answer
Libraries are usually referenced using absolute paths on OS X, making it unnecessary to set any variables. Your
otool -L
output on the Python module should thus containThis path is copied from what Apple calls the "shared library identification name" in a library when you link against it. That means that whatever value is in the output of
otool -L
on the Python module is the same value that you get by runningotool -D
on/opt/local/lib/libgnuradio-grgsm.dylib
(or just usingotool -L
and looking at the first line). If you do this on your machine, you will notice that it also does not contain an absolute path. That's the root cause of the issue you see.First, this is a bug in GNU Radio, or MacPorts' packaging of GNU Radio. Please file a ticket so this can get fixed or addressed with the GNU Radio developers.
Second, there are a couple of ways to work around this issue for now:
Method A: Fix the identification name of
libgnuradio-grgsm.dylib
. This can be done usinginstall_name_tool -id $correctID /opt/local/lib/libgnuradio-grgsm.dylib
. Note that the absolute path to the unversioned dylib is likely not the correct value for this.libgnuradio-grgsm.dylib
is likely a symlink to another symlink with the major version embedded. This path is the one that should be used as install name. After this change, rebuilding the Python module should solve the issue.Method B: Fix the path in the load command of the Python module. Use
install_name_tool -change libgnuradio-grgsm.dylib $correctID /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/grgsm/_grgsm_swig.so
to do this.$correctID
should be chosen as explained in Method A.