dyld не может загружать dylibs - PullRequest
1 голос
/ 02 апреля 2011

У меня есть куча дилибов, которые мне нужно загрузить во время выполнения из комплекта приложений.Я заметил, что если я положил свои dylibs в папку /usr/lib, то приложение сможет загрузить его.Я ознакомился с install_name_tool руководством, но не понял, как заставить приложение загружать эти dylibs из папки .app/contents/Frameworks.

Может кто-нибудь помочь мне с этим?

1 Ответ

8 голосов
/ 05 августа 2011

Я только что имел дело с этой же проблемой вчера.

Что не очень понятно, так это то, что вы ожидаете, так как вы перетаскиваете свои dylibs в файловый браузер XCode, и так как вы добавляете фазу сборки, чтобы скопировать их в ваш исполняемый файл в комплекте, компоновщик «пишет» в приложение, чтобы сказать ему, куда найди этих дилибов. К сожалению, это не так.

По какой-либо исторической причине, или "почему кто-то знает, почему", вместо того, чтобы извлекать эту информацию из того, что вы делаете в XCode, он выводит ее из строки внутри самих dylibs. Тот, который XCode не трогает, и который вам нужно установить вручную с помощью инструмента командной строки.

Внутри каждого из dylibs есть строка, называемая id, по которой программа будет искать dylibs. Я думаю, что это будет скопировано в исполняемый файл во время ссылки. Чтобы узнать, что это за строка, вы можете выполнить следующее:

otool -L pathToMyDylib

Первая строка, которую выводит команда, - это строка, в которой exec ожидает, что она будет при запуске программы, которая называется "id". Я создал несколько библиотек надстроек, и выводом их идентификатора было просто имя файла. Более поздние строки, которые выводит команда, являются «зависимостями»; это другие библиотеки, от которых может зависеть ваш dylib. Часто, как и в случае с моей, это библиотеки, которые гарантированно находятся в любом дистрибутиве Mac, поэтому вам не нужно беспокоиться о необходимости их исправлять. Если бы они не были такими; если бы это были библиотеки, которые вы создали сами и собирались включить в свое приложение, вам также пришлось бы их исправлять. Итак, вывод для моего otool -L libboost_regex.dylib был:

libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.0.0)

Первая строка, которую нужно исправить, чтобы заглянуть внутрь моего исполняемого файла. Вы правы, что install_name_tool - это то, что нужно исправить. Чтобы исправить это, я использовал (с моим терминалом в том же каталоге, что и мой boost dylib):

install_name_tool -id "@executable_path/../Frameworks/libboost_regex.dylib" libboost_regex.dylib

Соответственно, первый параметр там (после флага -id) - это новый путь, а второй параметр - файл dylib, который нужно изменить.

Если вам нужно сделать аналогичную модификацию для одной из зависимостей, вы должны использовать:

install_name_tool -change oldpath newpath currentfile

И это нужно будет повторно применять для каждой отдельной зависимости.

Надеюсь, это поможет!

...