I recently had to deal with linking and runtime loading libraries on Mac OS, which I found to work quite a bit differently than windows and linux systems, so I thought I would share my notes on the matter.
An executable’s dependent libraries can usually be identified by inspecting the executable using otool:
The tool works on libraries as well. You will notice the library paths appear in 3 forms:
- Absolute path: the system will only look in the specified location for the library
- Relative path: the system will look in the working directory of the application, a set of known paths, in DYLD_LIBRARY_PATH and DYLD_FALLBACK_LIBRARY_PATH
Prefixed path with one of the following 3 keywords:
- @executable_path - relative to the application’s executable
- @loader_path - relative to the plug-in’s code (plug-ins may not actually know where they are going to be installed, relative to the application, so knowing @executable_path wouldn’t be enough here)
@rpath - the dynamic linker will search a list of paths in order to locate the library. The @rpaths the application will look can be viewed at the end of the output given by: otool -l
@rpath allows a bit of flexibility on this matter, it would even a library to be present into multiple destinations. @rpath’s are given during the build process, by the “-Wl” flag which works on both clang and gcc.
The paths can also be altered afterwards, using the install_name_tool:
install_name_tool -change “libfoo.1.dylib” “@rpath/libfoo.1.dylib” <file>
The tool can also be used to add @rpath locations:
install_name_tool -add_rpath "@loader_path/../lib" <file>