установите инструмент имя для обновления исполняемого файла для поиска 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")