Как создать динамическую библиотеку (dylib) с помощью Xcode?

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

Нужно ли мне творить чудеса, чтобы получить символы экспорта libpng?

Связан ли этап сборки «Связать двоичный файл с библиотеками» статически?

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


Думаю, я разобрался:

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

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

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


person Kornel    schedule 11.10.2008    source источник
comment
Я хотел бы предложить тег mach-o, но не думаю, что стоит удалять какие-либо из существующих тегов в пользу него.   -  person ephemient    schedule 12.10.2008


Ответы (4)


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

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

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

person Chris Hanson    schedule 12.10.2008
comment
Что, если у меня есть простая функция на чистом C, и я хочу предоставить ей динамическую библиотеку. Как я могу это сделать (я легко сделал это с помощью Visual Studio в Windows)? - person Royi; 23.02.2017

Динамическое связывание в 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), но мало примеров или программ с режимом «скажите мне, что вы делаете».

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

Справочная информация: Обзор яблочных библиотек , Википедия 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.)

person denis    schedule 05.02.2009
comment
Ницца. что, если у вас уже есть файлы .o, но есть, скажем, 9 из них в 3 папках, но все они являются частью одной и той же структуры ... это призыв к оружию для липо, или что? кстати, я пытаюсь сделать libg7221 разделяемой библиотекой, в этом случае ... - person Alex Gray; 08.09.2011
comment
@alex grey, не знаю, извините; задать это как новый вопрос? - person denis; 08.09.2011

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

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

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

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

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

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

person Brock Woolf    schedule 23.11.2008
comment
@wintermute: ненужный комментарий. Я уверен, что каждый пользователь этого сайта слышал раньше миллион раз. - person Brock Woolf; 04.08.2010
comment
Мертвая ссылка. В архиве https://web-beta.archive.org/web/20100620075647/http://brockwoolf.com:80/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod - person original_username; 29.03.2017

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

person Jonathan Leffler    schedule 12.10.2008