Как распространять Mac OS X с зависимыми библиотеками?
У меня есть программа (в частности, моя запись для SO DevDays Countdown app), которая опирается на несколько динамических библиотек, а именно libSDL, libSDL_ttf и другие. У меня эти библиотеки установлены под /opt/local/lib
через MacPorts, и многие люди не будут иметь эти установленные (и некоторые из них могут быть установлены, но не в этом месте).
Как распространять мою программу, чтобы люди, не имеющие этих библиотек, могли запускать ее из коробки? Очевидно, мне придется распространять различные файлы .dylib
, но этого недостаточно. Динамический загрузчик по-прежнему ищет библиотеки, установленные в местах, где я их установил. Есть ли способ сказать динамическому загрузчику посмотреть в текущем каталоге исполняемого файла, например, что делает Windows с DLL? Людям не нужно изменять какие-либо переменные среды (например, DYLD_LIBRARY_PATH
), так как снова я хочу, чтобы это работало готово.
Ответы
Ответ 1
Как вы уже упоминали, вы не используете Xcode, так что это немного сложно. Вот варианты в моем порядке предпочтения:
-
Переключитесь на Xcode. Используйте рамки. Библиотеки SDL уже доступны в качестве фреймворков, и я видел больше, чем пару коммерческих игр с libsdl.framework внутри пакета приложений.
-
Используйте фреймворки, но сохраняйте свои Make файлы. Загрузите версии фреймворков ваших SDL-библиотек (или создайте их самостоятельно) и свяжите их с флагом -framework-линкером. Распределите фреймворки с вашим приложением или нет, и сообщите своим пользователям, чтобы они помещали их в ~/Library/Frameworks или в /Library/Frameworks. Я бы не потрудился с установщиком для этого.
-
Статическая ссылка на SDL. В Makefile вам нужно будет указать путь к статическим библиотекам, а не использовать флаг -l, например, вы запустите "ld blah blah/opt/local/lib/libsdl.a". Я не знаю, как я могу сказать -l предпочитать статические над разделяемыми библиотеками, и, поверьте, я посмотрел.
Ответ 2
Основной подход к этому - отправить их в пакет .app. Затем вы измените местоположение, в которое компоновщик будет искать общие библиотеки, чтобы включить это.
Шаги:
-
Создайте новую фазу сборки файлов копий для своей цели, которая копирует эти файлы в каталог Frameworks пакета .app.
-
Измените настройку конфигурации сборки "Пути поиска пути", чтобы включить @executable_path/../Frameworks
Если вы создаете свой исполняемый файл с этими изменениями и затем смотрите, вы должны обнаружить, что dylib существуют в каталоге Foo.app/Contents/Framework
, а запуск otool -L Foo.app/Contents/MacOS/Foo
должен содержать и запись, префиксную с помощью @rpath для этих dylib.
Из этого Сообщение Cocoabuilder:
В общем случае @loader_path
предпочтительнее @executable_path
, так как он
позволяет встроенным фреймворкам работать как в исполняемом файле, так и в комплекте,
плагин или подрамник. Единственным недостатком является то, что @loader_path
требуется 10.4 или новее. Если вы на 10.5 или новее, @rpath
даже
лучше, чем @loader_path
.
Ответ 3
Статически связывать библиотеки.