Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking to a dynamic library on a Mac with full path

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.

like image 908
D R Avatar asked Dec 20 '09 22:12

D R


People also ask

How are dynamic libraries linked?

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.

Where can I find dynamic library?

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 are Dylib files on Mac?

Where do DYLIB files go on a Mac? The standard locations for dynamic libraries are ~/lib, /usr/local/lib, and /usr/lib.


3 Answers

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.

like image 61
D R Avatar answered Sep 27 '22 21:09

D R


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.

like image 36
quazgar Avatar answered Sep 27 '22 21:09

quazgar


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
like image 39
bmargulies Avatar answered Sep 27 '22 22:09

bmargulies