Linking to a dynamic library on a Mac with full path
Asked Answered
D

4

23

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.

Damales answered 20/12, 2009 at 22:5 Comment(1)
Please refer my answer in this link [Add_libray][1] [1]: #4877240Convulsive
D
33

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.

Damales answered 20/12, 2009 at 22:33 Comment(3)
this is useful, but you're right, there should be a way of doing this in CMakeVoss
I ended up needing to do the inverse operation; replacing an absolute path with one involving @loader_path. The dyld man page was helpful in explaining the behaviour of dyld as it regards absolute paths and expansion of @loader_path.Hospers
the thing with the install_name_tool is that it doesn't work as expected if the library is code signed, right?Poltergeist
C
7

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.

Chiekochien answered 7/6, 2011 at 11:11 Comment(1)
Using this just broke the shell I was in, and gave me: ``` python dyld: Library not loaded: @loader_path/../lib/libpython2.7.dylib Referenced from: .../bin/python Reason: image not found Trace/BPT trap: 5 ```Knorring
S
5

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
Solothurn answered 20/12, 2009 at 22:9 Comment(1)
Could you elaborate a bit more on this? I'm having same issue. I feel like a few of the paths in my built project are not looking to the correct place!Beulahbeuthel
F
-1

You can also use symbolic link !

Form answered 14/8, 2010 at 17:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.