On OS X, the loader
Sometimes, we want to install a third-party library to a location, which is not system-defined, not /usr/local/lib nor /usr/lib, for some personal reasons or when you did not have root privilege. Suppose it was libdummy. If libdummy‘s install_name was just libdummy.1.dylib or so, and you were building a program which links against libdummy. After the compilation, you checked the shared libraries your program used:
then you could see libdummy.1.dylib in the output, just libdummy.1.dylib in that line. Ja, the linker stored install_name there, not the location of the library.
Then you let the program run, but the
On Linux, we could modify /etc/ld.so.conf in order to include some other directories when the loader searches for a library. However, on OS X things are different. Also, we would not like to set DYLD_ variables every time launching the program, nor add those variables in .zshrc, .bashrc, …
De facto, as we know install_name matters, we could simply employ it.
On Darwin platform,
1 | gcc -o libdummy.dylib -install_name ${PREFIX}/lib/libdummy.dylib ... |
would set install_name for libdummy.dylib to a well-defined path. Next time when linking your program against libdummy, the linker would store that path. Use
Besides absolute paths, we could use other techniques as well:
@executable_path, @loader_path, @rpath. This article describes these very well.
For already built libraries and programs, there is no need to rebuild them. On OS X, there is a very useful tool:
- change install_name for a library:
install_name_tool -id “new_install_name” libdummy.dylib - change linked install_name in a program:
install_name_tool -change “old_install_name” “new_install_name” program
One more thing. If you use
1 | SET(CMAKE_INSTALL_NAME_DIR @executable_path) |
Replace @executable_path with your own choice.