Error: dlopen() Library not loaded Reason: image not found

Ramesh picture Ramesh · Nov 4, 2013 · Viewed 22.4k times · Source

I am a newbie in this field. My laptop is Macbook air, Software: OS X 10.8.5 (12F45). I am running a code which gives me the following error:

dlopen(/Users/ramesh/offline/build_icerec/lib/icecube/phys_services.so, 2): Library not loaded: /Users/ramesh/offline/build_icerec/lib/libphys-services.dylib Referenced from: /Users/ramesh/offline/build_icerec/lib/icecube/phys_services.so Reason: image not found

I did google search and found variety of answers. I think the one that works is to use

" -install_name @rpath/lib ".

My question is, how to use -install_name @rpath/lib in my case?

Answer

mah picture mah · Mar 21, 2014

Shared object location under OS X is sometimes tricky. When you directly call dlopen() you have the freedom of specifying an absolute path to the library, which works fine. However, if you load a library which in turn needs to load another (as appears to be your situation), you've lost control of specifying where the library lives with its direct path.

There are environment variables that you could set before running your main program that tell the dynamic loader where to search for things. In general these are a bad idea (but you can read about them via the man dyld command on an OS X system).

When an OS X dynamic library is created, it's given an install name; this name is embedded within the binary and can be viewed with the otool command. otool -L mach-o_binary will list the dynamic library references for the mach-o binary you provide the file name to; this can be a primary executable or a dylib, for example.

When a dynamic library is statically linked into another executable (either a primary executable or another dylib), the expected location of where that dylib being linked will be found is based on the location written into it (either at the time it was built, or changes that have been applied afterwards). In your case, it seems that phys_services.so was statically linked against libphys-services.dylib. So to start, run otool -L phys_services.so to find the exact expectation of where the dylib will be.

The install_name_tool command can be used to change the expected location of a library. It can be run against the dylib before it gets statically linked against (in which case you have nothing left to do), or it can be run against the executable that loads it in order to rewrite those expectations. The command pattern for this is install_name_tool -change <old_path> <new_path> So for example, if otool -L phys_services.so shows you /usr/lib/libphys-services.dylib and you want to move the expectation as you posed in your question, you would do that with install_name_tool -change /usr/lib/libphys-services.dylib @rpath/lib/libphys-services.dylib phys_services.so.

The dyld man page (man dyld) will tell you how @rpath is used, as well as other macros @loader_path and @executable_path.