14

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?

crthompson
  • 15,653
  • 6
  • 58
  • 80
Ramesh
  • 143
  • 1
  • 1
  • 6
  • I had the same problem after installing xcode 8, while using binding.pry in ruby. After reinstalling ruby, everything worked fine. Seems easier than the complex, but correct answer from mah. `rvm requirements` also helped me because I had recently updated my system. – Joe Eifert Oct 13 '16 at 15:31

1 Answers1

32

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.

mah
  • 39,056
  • 9
  • 76
  • 93
  • 1
    You may also try to pass the `-Wl,-rpath,${RPATH}` option to the linker where `${RPATH}` is the path to a library, like `/foo/bar/lib`. Several such options may be specified and the linker will search for the dynamic libraries in all those locations. – András Aszódi Nov 06 '16 at 15:05
  • What if everything is defined by absolute path and still I can't load the library? Any idea? – Royi Sep 02 '18 at 13:42
  • @Royi Read the system log for possible clues. One possibility is that the binary type of the dylib doesn't match the binary type of your program and you can check that with the "file" command. `file /path/to/dylib` and `file /path/to/program`. Other than that I don't know what the cause could be on macOS (though if you happen to be on iOS, sandboxing could be a likely cause). – mah Sep 03 '18 at 14:54
  • MATLAB can only handle Dynamic Libraries with `C` API (I'm not sure what the correct word here). I use `extern "C"` on my `C++` code and it works on Windows. On macOS for some reason MATLAB either gets the error above or says it can't find the function. – Royi Sep 03 '18 at 14:59