Как мне создать динамическую библиотеку (dylib) с Xcode? - PullRequest
28 голосов
/ 11 октября 2008

Я строю несколько утилит командной строки в Xcode (обычный C, без какао). Я хочу, чтобы все они использовали мою настроенную версию libpng, и я хочу сэкономить место, разделяя одну копию библиотеки среди всех исполняемых файлов (я не против перераспределить .dylib с ними). ​​

Нужно ли использовать магию для получения экспортных символов libpng?

Связывает ли бинарный файл с библиотеками статическую фазу сборки?

В документах Apple упоминается загрузка библиотек во время выполнения с dlopen, но как я могу заставить Xcode создавать исполняемые файлы, не жалуясь на пропущенные символы?


Думаю, я понял это:

  • libpng неправильно связывался, потому что я собрал 32/64-битные исполняемые файлы и 32-битную библиотеку. Настройки сборки библиотеки и исполняемых файлов должны совпадать.

  • libpng config.h должен иметь множество определений, таких как #define FEATURE_XXX_SUPPORTED

  • «Связать двоичные файлы с библиотеками» фаза сборки прекрасно обрабатывает динамические библиотеки, а DYLD_FALLBACK_LIBRARY_PATH переменная окружения необходима для загрузки .dylib s из комплекта приложения.

Ответы [ 4 ]

50 голосов
/ 05 февраля 2009

Динамическое связывание в Mac OS X, крошечный пример

Шаги:

  1. создать библиотеку libmylib.dylib, содержащую mymod.o
  2. скомпилируйте и свяжите "callmymod", который вызывает его
  3. вызовите mymod из callmymod, используя DYLD_LIBRARY_PATH и DYLD_PRINT_LIBRARIES

Проблема: вы просто хотите создать библиотеку для использования другими модулями. Однако есть огромная куча программ - gcc, ld, macosx libtool, dyld - с миллионами опций, гнилым компостом и различиями между MacOSX и Linux. Есть тонны страниц руководства (я считаю 7679 + 1358 + 228 + 226 строк в 10.4.11 ppc) но не так много примеров или программ с режимом «скажи мне, что ты делаешь».

(Самое важное в понимании - это сделать упрощенный ОБЗОР для себя: нарисуйте несколько картинок, приведите несколько небольших примеров, объясните это кому-то еще).

Фон: apple, ОбзорOfDynamicLibraries , Википедия Dynamic_library


Шаг 1, создайте libmylib.dylib -

mymod.c:
    #include <stdio.h>
    void mymod( int x )
    {
        printf( "mymod: %d\n", x );
    }
gcc -c mymod.c  # -> mymod.o
gcc -dynamiclib -current_version 1.0  mymod.o  -o libmylib.dylib
    # calls libtool with many options -- see man libtool
    # -compatibility_version is used by dyld, see also cmpdylib

file libmylib.dylib  # Mach-O dynamically linked shared library ppc
otool -L libmylib.dylib  # versions, refs /usr/lib/libgcc_s.1.dylib

Шаг 2, скомпилировать и связать callmymod -

callmymod.c:
    extern void mymod( int x );
    int main( int argc, char** argv )
    {
        mymod( 42 );
    }
gcc -c callmymod.c
gcc -v callmymod.o ./libmylib.dylib -o callmymod
    # == gcc callmymod.o -dynamic -L. -lmylib
otool -L callmymod  # refs libmylib.dylib
nm -gpv callmymod  # U undef _mymod: just a reference, not mymod itself

Шаг 3, запустите callmymod со ссылкой на libmylib.dylib -

export DYLD_PRINT_LIBRARIES=1  # see what dyld does, for ALL programs
./callmymod
    dyld: loaded: libmylib.dylib ...
    mymod: 42

mv libmylib.dylib /tmp
export DYLD_LIBRARY_PATH=/tmp  # dir:dir:...
./callmymod
    dyld: loaded: /tmp/libmylib.dylib ...
    mymod: 42

unset DYLD_PRINT_LIBRARIES
unset DYLD_LIBRARY_PATH

На этом заканчивается один крошечный пример; надеюсь, это поможет понять шаги.
(Если вы делаете это много, см. GNU Libtool который является glibtool на Mac, и SCons .)
веселит
- Денис

7 голосов
/ 12 октября 2008

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

Кроме того, когда ваша динамическая библиотека собирается, в нее включается имя установки , которое по умолчанию является путем, по которому она создается. Впоследствии все, что ссылается на него, будет сначала искать его по указанному пути, и только потом искать (небольшой) набор путей по умолчанию, описанных в DYLD_FALLBACK_LIBRARY_PATH на странице руководства dyld(1) .

Если вы собираетесь поместить эту библиотеку рядом с вашими исполняемыми файлами, вам следует изменить имя ее установки, чтобы оно ссылалось на это. Просто поиск в Google по «имени для установки» должен получить массу информации об этом.

6 голосов
/ 23 ноября 2008

К сожалению, по моему опыту, документация Apple устарела, избыточна и в ней отсутствует много общей информации, которая вам обычно нужна.

Я написал об этом на своем сайте, где мне нужно было установить FMOD (Sound API) для работы с моей кроссплатформенной игрой, которую мы разработали в универе. Это странный процесс, и я удивлен, что Apple не добавляет больше информации в свои документы для разработчиков.

К сожалению, как бы ни были «злы» Microsoft, на самом деле они гораздо лучше заботятся о своих разработчиках с документацией (это исходит от евангелиста Apple).

Я думаю, что в основном вы не делаете, ПОСЛЕ того как вы скомпилировали свой .app Bundle. Затем вам нужно выполнить команду в исполняемом двоичном файле /MyApp.app/contents/MacOS/MyApp, чтобы изменить, где исполняемый файл ищет свой библиотечный файл. Вы должны создать новый этап сборки, который может запустить скрипт. Я не буду объяснять этот процесс снова, я уже сделал это подробно здесь:

http://brockwoolf.com/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod

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

5 голосов
/ 12 октября 2008

Вам известна справочная страница Apple Темы программирования динамической библиотеки ? Он должен охватывать большую часть того, что вам нужно. Имейте в виду, что есть общие библиотеки, которые загружаются безоговорочно при запуске программы, и динамически загружаемые библиотеки (комплекты, IIRC), которые загружаются по требованию, и они несколько отличаются в MacOS X от аналогов в Linux или Solaris.

...