Кажется, что после исправления 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).