From otool -l
, I analyzed what should be added or modified from the original library and binary.
Dylib
The change is in id:
Load command 2 <-- OLD
cmd LC_ID_DYLIB
cmdsize 40
name libtest.dylib (offset 24)
time stamp 1 Wed Dec 31 18:00:01 1969
Load command 2 <-- NEW
cmd LC_ID_DYLIB
cmdsize 64
name @loader_path/../lib/libtest.dylib (offset 24)
This is the command to accomplish the change:
install_name_tool -id "@loader_path/../lib/libtest.dylib" libtest.dylib
Or use rpath:
install_name_tool -id "@rpath/libtest.dylib" libtest.dylib
The executable
There are two changes: rpath and load_dylib
Load command 12 <-- OLD
cmd LC_LOAD_DYLIB
cmdsize 40
name libtest.dylib (offset 24)
Load command 12 <-- NEW
cmd LC_LOAD_DYLIB
cmdsize 64
name @loader_path/../lib/libtest.dylib (offset 24)
This is the command to accomplish the change
install_name_tool -change libtest.dylib @loader_path/../lib/libtest.dylib myapp
Also I needed to add the rpath
Load command 14
cmd LC_RPATH
cmdsize 32
path @loader_path/../lib (offset 12)
This is the command to accomplish the addition:
install_name_tool -add_rpath "@loader_path/../lib" myapp
The idea
The binary tries to find the library, it knows where it is located from install_name_tool -add_rpath "@loader_path/../lib" myapp
. It loads the library, and the library’s id is @rpath/libtest.dylib
where @rpath
is set to @loader_path/../lib
in the executable binary to make the match.
Reference
- Can you please help me understand how Mach-O libraries work in Mac Os X?
Cmake
When using CMake, we can automatize the process with the following addition in CMakeLists.txt file.
Library
The id should be added.
# https://cmake.org/pipermail/cmake/2006-October/011530.html
SET_TARGET_PROPERTIES (test
PROPERTIES BUILD_WITH_INSTALL_RPATH 1
INSTALL_NAME_DIR "@rpath"
)
Executable
The rpath should be specified:
SET(CMAKE_INSTALL_RPATH "@loader_path/../lib/libtest.dylib")