Как распространять Mac OS X с зависимыми библиотеками?

У меня есть программа (в частности, моя статья для вызова приложения SO DevDays Countdown), которая опирается на несколько динамических библиотек, а именно libSDL, libSDL_ttf и другие. У меня эти библиотеки установлены под /opt/local/lib через MacPorts, и многие люди их не установят (а некоторые могут установить их, но не в этом месте).

Как я могу распространять мою программу, чтобы люди без этих библиотек могли запускать ее из коробки? Очевидно, мне придется распространять различные .dylib файлы, но этого недостаточно. Динамический загрузчик по-прежнему ищет библиотеки, установленные в местах, в которых я их установил. Есть ли способ указать динамическому загрузчику, чтобы он смотрел в текущем каталоге исполняемого файла, например, что Windows делает с DLL? Люди не должны изменять какие-либо переменные среды (например, DYLD_LIBRARY_PATH), так как снова я хочу, чтобы это работало "из коробки".

3 ответа

Решение

Как вы упоминали, вы не используете XCode, так что это немного сложно. Вот варианты в моем порядке предпочтений:

  1. Переключиться на Xcode. Используйте рамки. Библиотеки SDL уже доступны в качестве фреймворков, и я видел более пары коммерческих игр с libsdl.framework в комплекте приложений.

  2. Используйте фреймворки, но сохраняйте ваши Makefiles. Загрузите базовые версии ваших библиотек SDL (или соберите их самостоятельно) и свяжите с ними с помощью флага компоновщика -framework. Распространяйте фреймворки с вашим приложением или нет, и попросите своих пользователей поместить их в ~/Library/Frameworks или в /Library/Frameworks. Я не стал бы беспокоиться с установщиком для этого.

  3. Статически ссылка против SDL. В Makefile вам придется указывать путь к статическим библиотекам, а не использовать флаг -l, например, вы запускаете "ld blah blah /opt/local/lib/libsdl.a". Я не знаю, как сказать -l, чтобы он предпочитал статические, а не разделяемые библиотеки, и, поверьте, я посмотрел.

Основной подход к этому состоит в том, чтобы отправить их в комплекте.app. Затем вы измените местоположение, которое компоновщик ищет в общих библиотеках, чтобы включить это.

Шаги:

  1. Создайте новую фазу сборки файлов копирования для своей цели, которая скопирует эти файлы в каталог Frameworks пакета.app.

  2. Измените параметр конфигурации сборки "Пути поиска пути", чтобы включить @executable_path/../Frameworks

Если вы создадите свой исполняемый файл с этими изменениями, а затем посмотрите, вы обнаружите, что в Foo.app/Contents/Framework каталог и работает otool -L Foo.app/Contents/MacOS/Foo должен дать и запись с префиксом @rpath для этих dylibs.

Из этого сообщения Cocoabuilder:

В общем, @loader_path предпочтительнее @executable_path, как это
позволяет встроенным фреймворкам работать как в исполняемом файле, так и в пакете,
плагин или подкаркас. Единственным недостатком является то, что @loader_path
Требуется 10.4 или новее. Если вы на 10,5 или выше, @rpath даже
лучше чем @loader_path,

Статически связать библиотеки.

Другие вопросы по тегам