install_name_tool 更新可执行文件以在 Mac OS X 中搜索 dylib
install_name_tool to update a executable to search for dylib in Mac OS X
我有一个安装在 /PATH/lib
中的动态库 libtest.dylib,以及一个使用安装在 /PATH/bin
中的动态库的执行二进制文件 myapp。
我可以运行 myapp
找到 dylib 如下 (Is it OK to use DYLD_LIBRARY_PATH on Mac OS X? And, what's the dynamic library search algorithm with it?):
DYLD_LIBRARY_PATH="/PATH/lib" myapp
我想我可以使用 install_name_tool
更新库和可执行文件,以便可以使用 rpath 找到库。我使用了这个 post - How can I specify the rpath in a dylib? 中的提示。
在lib中,我执行了这个命令来添加rpath。
install_name_tool -id "@rpath/libtest.dylib" libtest.dylib
install_name_tool -add_rpath "@executable_path/../lib/" libtest.dylib
在bin中,我执行了install_name_tool -add_rpath "@executable_path/../lib/" myapp
。
但是,当我在 bin
目录中执行 myapp
时,出现错误消息。
dyld: Library not loaded: libtest.dylib
Referenced from: /PATH/bin/./myapp
Reason: image not found
Trace/BPT trap: 5
otool -l myapp
显示 rpath 在 myapp 中正确更新。
Load command 16
cmd LC_RPATH
cmdsize 40
path @executable_path/../lib/ (offset 12)
同理libtest.dylib
Load command 13
cmd LC_RPATH
cmdsize 40
path @executable_path/../lib/ (offset 12)
可能出了什么问题?
已添加
当然,我可以在编译时使用cc -install_name
,在编译时使用link,但我想知道如何通过修改generatd dylib 和执行二进制文件来做同样的事情。
来自库:
cc -install_name "@loader_path/../lib/libtest.dylib" -dynamiclib -o libtest.dylib test.c
或者,install_name 可以使用@rpath:
cc -install_name "@rpath/libtest.dylib" -dynamiclib -o libtest.dylib test.c
来自垃圾箱:
cc -I../lib -c main.c
cc -o main main.o ../lib/libtest.dylib -Wl,-rpath -Wl,@loader_path/../lib
或者只有一行:
cc -I../lib -L../lib -o main main.c -ltest -Wl,-rpath -Wl,@loader_path/../lib
从otool -l
开始,我分析了从原来的库和二进制文件应该添加或修改的内容。
动态库
变化在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)
这是完成更改的命令:
install_name_tool -id "@loader_path/../lib/libtest.dylib" libtest.dylib
或使用 rpath:
install_name_tool -id "@rpath/libtest.dylib" libtest.dylib
可执行文件
有两个变化:rpath和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)
这是完成更改的命令
install_name_tool -change libtest.dylib @loader_path/../lib/libtest.dylib myapp
我还需要添加 rpath
Load command 14
cmd LC_RPATH
cmdsize 32
path @loader_path/../lib (offset 12)
这是完成加法的命令:
install_name_tool -add_rpath "@loader_path/../lib" myapp
想法
二进制文件试图找到库,它知道它位于 install_name_tool -add_rpath "@loader_path/../lib" myapp
的位置。它加载库,库的 id 是 @rpath/libtest.dylib
,其中 @rpath
在可执行二进制文件中设置为 @loader_path/../lib
以进行匹配。
参考
- Can you please help me understand how Mach-O libraries work in Mac Os X?
Cmake
使用 CMake 时,我们可以通过在 CMakeLists.txt 文件中添加以下内容来自动化该过程。
图书馆
应该加上id。
# https://cmake.org/pipermail/cmake/2006-October/011530.html
SET_TARGET_PROPERTIES (test
PROPERTIES BUILD_WITH_INSTALL_RPATH 1
INSTALL_NAME_DIR "@rpath"
)
可执行
应指定 rpath:
SET(CMAKE_INSTALL_RPATH "@loader_path/../lib/libtest.dylib")
我有一个安装在 /PATH/lib
中的动态库 libtest.dylib,以及一个使用安装在 /PATH/bin
中的动态库的执行二进制文件 myapp。
我可以运行 myapp
找到 dylib 如下 (Is it OK to use DYLD_LIBRARY_PATH on Mac OS X? And, what's the dynamic library search algorithm with it?):
DYLD_LIBRARY_PATH="/PATH/lib" myapp
我想我可以使用 install_name_tool
更新库和可执行文件,以便可以使用 rpath 找到库。我使用了这个 post - How can I specify the rpath in a dylib? 中的提示。
在lib中,我执行了这个命令来添加rpath。
install_name_tool -id "@rpath/libtest.dylib" libtest.dylib
install_name_tool -add_rpath "@executable_path/../lib/" libtest.dylib
在bin中,我执行了install_name_tool -add_rpath "@executable_path/../lib/" myapp
。
但是,当我在 bin
目录中执行 myapp
时,出现错误消息。
dyld: Library not loaded: libtest.dylib
Referenced from: /PATH/bin/./myapp
Reason: image not found
Trace/BPT trap: 5
otool -l myapp
显示 rpath 在 myapp 中正确更新。
Load command 16
cmd LC_RPATH
cmdsize 40
path @executable_path/../lib/ (offset 12)
同理libtest.dylib
Load command 13
cmd LC_RPATH
cmdsize 40
path @executable_path/../lib/ (offset 12)
可能出了什么问题?
已添加
当然,我可以在编译时使用cc -install_name
,在编译时使用link,但我想知道如何通过修改generatd dylib 和执行二进制文件来做同样的事情。
来自库:
cc -install_name "@loader_path/../lib/libtest.dylib" -dynamiclib -o libtest.dylib test.c
或者,install_name 可以使用@rpath:
cc -install_name "@rpath/libtest.dylib" -dynamiclib -o libtest.dylib test.c
来自垃圾箱:
cc -I../lib -c main.c
cc -o main main.o ../lib/libtest.dylib -Wl,-rpath -Wl,@loader_path/../lib
或者只有一行:
cc -I../lib -L../lib -o main main.c -ltest -Wl,-rpath -Wl,@loader_path/../lib
从otool -l
开始,我分析了从原来的库和二进制文件应该添加或修改的内容。
动态库
变化在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)
这是完成更改的命令:
install_name_tool -id "@loader_path/../lib/libtest.dylib" libtest.dylib
或使用 rpath:
install_name_tool -id "@rpath/libtest.dylib" libtest.dylib
可执行文件
有两个变化:rpath和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)
这是完成更改的命令
install_name_tool -change libtest.dylib @loader_path/../lib/libtest.dylib myapp
我还需要添加 rpath
Load command 14
cmd LC_RPATH
cmdsize 32
path @loader_path/../lib (offset 12)
这是完成加法的命令:
install_name_tool -add_rpath "@loader_path/../lib" myapp
想法
二进制文件试图找到库,它知道它位于 install_name_tool -add_rpath "@loader_path/../lib" myapp
的位置。它加载库,库的 id 是 @rpath/libtest.dylib
,其中 @rpath
在可执行二进制文件中设置为 @loader_path/../lib
以进行匹配。
参考
- Can you please help me understand how Mach-O libraries work in Mac Os X?
Cmake
使用 CMake 时,我们可以通过在 CMakeLists.txt 文件中添加以下内容来自动化该过程。
图书馆应该加上id。
# https://cmake.org/pipermail/cmake/2006-October/011530.html
SET_TARGET_PROPERTIES (test
PROPERTIES BUILD_WITH_INSTALL_RPATH 1
INSTALL_NAME_DIR "@rpath"
)
可执行
应指定 rpath:
SET(CMAKE_INSTALL_RPATH "@loader_path/../lib/libtest.dylib")