установите инструмент имя для обновления исполняемого файла для поиска dylib в Mac OS X
у меня есть динамический libray libtest.dylib, который установлен в /PATH/lib
и двоичный файл выполнения myapp, который использует dylib, установленный в /PATH/bin
.
я могу запустить myapp
чтобы найти dylib следующим образом (можно ли использовать DYLD_LIBRARY_PATH в Mac OS X? И каков алгоритм поиска динамической библиотеки?):
DYLD_LIBRARY_PATH="/PATH/lib" myapp
я думаю, что могу использовать install_name_tool
чтобы обновить библиотеку и исполняемый файл, чтобы библиотеку можно было найти с помощью rpath. Я подсказки в этом посте -как я могу указать rpath в 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
.
однако, когда я выполнил myapp
на bin
каталог, у меня есть сообщения об ошибках.
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
при компиляции и времени ссылки, но я хотел знать, как сделать то же самое, что и изменение generatd dylib и двоичного файла выполнения.
из lib:
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
1 ответов
С otool -l
, Я проанализировал, что следует добавить или изменить из исходной библиотеки и двоичного файла.
dylib нужна
изменение в 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
. Он загружает библиотеку, и идентификатор библиотеки @rpath/libtest.dylib
здесь @rpath
установлено значение @loader_path/../lib
в исполняемый файл, чтобы сделать матч.
ссылка
Cmake
при использовании CMake мы можем автоматизировать процесс со следующим добавлением в CMakeLists.txt-файл.
Библиотекаидентификатор должен быть добавлен.
# 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")