I am linking a (Python extension) library that embeds the Matlab engine with the following command (generated using cmake)
c++ -mmacosx-version-min=10.6 -bundle -headerpad_max_install_names -o library.so library.o /Applications/MATLAB_R2009b.app/bin/maci64/libeng.dylib /Applications/MATLAB_R2009b.app/bin/maci64/libmx.dylib -framework Python
resulting in
$ otool -L library.so
library.so:
@loader_path/libeng.dylib (compatibility version 0.0.0, current version 0.0.0)
@loader_path/libmx.dylib (compatibility version 0.0.0, current version 0.0.0)
/System/Library/Frameworks/Python.framework/Versions/2.6/Python (compatibility version 2.6.0, current version 2.6.1)
/opt/local/lib/gcc44/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.13.0)
/opt/local/lib/gcc44/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)
However, when I try to use the library, I get an error message:
ImportError: dlopen(./library.so, 2): Library not loaded: @loader_path/libmex.dylib
Referenced from: ./library.so
Reason: image not found
I believe the problem stems from the fact that the linker includes the matlab dylib files in the form @loader_path/libeng.dylib
rather than using the full path, even though I give the full path to g++
. How can I force the linker to use the full path?
I know one solution is to use
export DYLD_LIBRARY_PATH=/Applications/MATLAB_R2009b.app/bin/maci64:$DYLD_LIBRARY_PATH
which is where those library files reside, but I'd like to avoid that as it causes some other problems.
Dynamic libraries are linked during the execution of the final executable. Only the name of the dynamic library is placed in the final executable. The actual linking happens during runtime, when both executable and library are placed in the main memory.
The standard locations for dynamic libraries are ~/lib , /usr/local/lib , and /usr/lib . You may also place the . dylib file at a nonstandard location in your file system, but you must add that location to one of these environment variables: LD_LIBRARY_PATH.
Where do DYLIB files go on a Mac? The standard locations for dynamic libraries are ~/lib, /usr/local/lib, and /usr/lib.
Manually changing the files using install_name_tool
install_name_tool -change "@loader_path/libeng.dylib" "/Applications/MATLAB_R2009b.app/bin/maci64/libeng.dylib" library.so install_name_tool -change "@loader_path/libmx.dylib" "/Applications/MATLAB_R2009b.app/bin/maci64/libmx.dylib" library.so
I could use this as a temporary fix, but I wonder if there isn't a better solution where the linker is given a setting to use the full paths.
Note that some of the problems with DYLD_LIBRARY_PATH
can be prevented by using DYLD_FALLBACK_LIBRARY_PATH
instead. This will only be used if the lib cannot be found in the default paths.
Look into the -rpath option to the ld command to control this. You might also be interested in the contents of https://github.com/bimargulies/jni-origin-testbed, which is a demonstration of some relevant technology.
The critical technique here is:
install_name_tool -change libsl2.so "@loader_path/libsl2.so" libsl1.so
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With