Соединение с библиотекой .dylib из командной строки с помощью clang - PullRequest
0 голосов
/ 25 октября 2018

Я пытаюсь написать программу на C, используя библиотеку.Библиотека предоставила каталоги include/ и lib/ с заголовочными файлами и .dylib файлами соответственно.

Мой файл находится в том же каталоге, что и include/ и lib/.Я пытаюсь скомпилировать его с помощью следующей команды:

clang -I"./include/" -L"./lib/" -lcsfml-graphics -lcsfml-window test.c

Однако, когда я запускаю свою программу, я получаю следующую ошибку:

% ./a.out 
dyld: Library not loaded: @rpath/libcsfml-graphics.2.4.dylib
  Referenced from: ~/src/CSFML-2.4-osx-clang/./a.out
  Reason: image not found
zsh: abort      ./a.out

Что является правильнымспособ компиляции с использованием этих библиотек?Я предпочел бы просто использовать командную строку, когда я пишу небольшую программу, без необходимости настраивать Xcode и т. Д.

% ls -l lib/
-rwxr-xr-x@ 1  staff   50296 Mar  1  2017 libcsfml-audio.2.4.0.dylib*
lrwxr-xr-x@ 1  staff      26 Mar  1  2017 libcsfml-audio.2.4.dylib@ -> libcsfml-audio.2.4.0.dylib
lrwxr-xr-x@ 1  staff      24 Mar  1  2017 libcsfml-audio.dylib@ -> libcsfml-audio.2.4.dylib
-rwxr-xr-x@ 1  staff  163680 Mar  1  2017 libcsfml-graphics.2.4.0.dylib*
lrwxr-xr-x@ 1  staff      29 Mar  1  2017 libcsfml-graphics.2.4.dylib@ -> libcsfml-graphics.2.4.0.dylib
lrwxr-xr-x@ 1  staff      27 Mar  1  2017 libcsfml-graphics.dylib@ -> libcsfml-graphics.2.4.dylib
-rwxr-xr-x@ 1  staff   67272 Mar  1  2017 libcsfml-network.2.4.0.dylib*
lrwxr-xr-x@ 1  staff      28 Mar  1  2017 libcsfml-network.2.4.dylib@ -> libcsfml-network.2.4.0.dylib
lrwxr-xr-x@ 1  staff      26 Mar  1  2017 libcsfml-network.dylib@ -> libcsfml-network.2.4.dylib

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Кажется, что после исправления rpath с помощью clang -I"./include/" -L"./lib/" -lcsfml-graphics -lcsfml-window -Wl,-rpath,"@executable_path/lib" test.c вам все еще не хватает библиотек SFML.Я только что проверил, что CSFML зависит от SFML, и, исходя из вашего ls -l lib/ списка, SFML явно отсутствует в lib /.Я предполагаю, что после исправления rpath вы, возможно, не заметили, что отсутствующая зависимость изменилась на @rpath/libsfml-graphics.2.4.dylib вместо @rpath/libcsfml-graphics.2.4.dylib.Пожалуйста, загрузите библиотеки SFML и поместите их в lib /.

Теперь к вашему вопросу, как собрать MacOS из командной строки.Ваши шаги по построению верны, поэтому я предполагаю, что сложная часть состоит в том, как dyld ищет зависимости, а не как они связаны с ld.

Краткая теория.

Существует 4 способадвоичный файл (исполняемый файл или динамическая библиотека) ссылается на свои зависимости:

  • по абсолютному или относительному пути (последний относительно вашего рабочего каталога);
  • по @executable_path,расширение до пути к исполняемому файлу, который является корнем дерева зависимостей (в случае, если у вас есть рекурсивные зависимости);
  • от @loader_path, расширение до пути к исполняемому файлу или библиотеке, для которой ищется зависимостьт. е. это путь прямого родителя в дереве зависимостей;
  • на @rpath, который поочередно заменяется каждым rpath, найденным в вашем двоичном файле, и это наиболее гибкий способ, поскольку вы можете искать в несколькихкаталоги, имеющие несколько rpath.

Теперь вопрос заключается в том, как обеспечить правильную ссылку на зависимостид.Как указал @mattmilten, для этого есть 2 способа:

  • заставить вашу систему сборки / скрипт сборки / команды ручной сборки убедиться, что ссылки верны;
  • использовать install_name_tool для исправлениянеработающие ссылки.

Автоматическая сборка во время сборки.

Для того, чтобы первый метод заработал, необходимо убедиться, что идентификационные имена зависимостибиблиотеки правильные.Предположим, вы связываете двоичный файл с некоторой библиотекой libA.dylib.Идентификационное имя libA.dylib является ссылкой по умолчанию, которая будет использоваться компоновщиком (ld) при сборке вашего двоичного файла.Вы можете найти его, посмотрев в первую строку otool -L libA.dylib (или, альтернативно, в разделе LC_ID_DYLIB otool -l libA.dylib).В случае libcsfml-graphics.2.4.dylib это @rpath/libcsfml-graphics.2.4.dylib и оно было передано a.out при связывании, поэтому вы видите его в сообщении об ошибке, когда dyld не может его встретить.

Установка правильного идентификационного имени является обязанностью авторов libA.dylib.Он устанавливается в соответствии с их ожиданиями относительно того, где может быть размещен libA.dylib (использование @rpath - хороший выбор), а также схемой управления версиями (в случае CSFML-версии 2.4.0 можно заменить на 2.4.x без потери двоичного кода).совместимость).Если вы создаете libA.dylib самостоятельно, вы можете установить его с параметром -install_name (например, clang -Wl,-dylib -Wl,-install_name,@executable_path/libA.dylib -o libA.dylib liba.c).Если это сторонняя библиотека, вы можете изменить ее на install_name_tool -id @rpath/libA.dylib libA.dylib.

Идентификационное имя, насколько мне известно, используется только во время компоновки и не используется при загрузке двоичного файла, поэтому, если вы предпочитаете второеметод исправления неправильных ссылок с помощью install_name_tool. Вы можете игнорировать его.

Ручное исправление.

Исправить ссылки с помощью install_name_tool просто, но утомительно.Вам, вероятно, понадобится скрипт, когда есть много неправильных ссылок.Все, что вам нужно, это следующий набор команд (заполнитель binary, очевидно, должен быть заменен действительным двоичным именем):

  • install_name_tool -change @executable_path/libA.dylib @rpath/libA.dylib binary для изменения ссылки @executable_path/libA.dylib -> @rpath/libA.dylib;
  • install_name_tool -add_rpath @executable_path/lib binary для добавления @executable_path/lib к rpaths;
  • install_name_tool -delete_rpath @executable_path/lib binary для удаления @executable_path/lib из rpaths;
  • otool -l binary для проверки существующих rpaths (просто посмотритев разделах LC_RPATH).
0 голосов
/ 31 октября 2018

Вы должны проверить переменную окружения DYLD_LIBRARY_PATH.Он должен содержать путь к libcsfml-graphics.2.4.dylib.Другим решением может быть добавление этого пути к вашей переменной PATH.

Вы можете проверить пути вашего двоичного файла с помощью otool -L и изменить их с помощью install_name_tool -change.В идеале, однако, вы должны собрать свой бинарный файл, содержащий правильный rpath и его зависимости, используя -R при компоновке / компиляции.

...