Каковы различия между.so и.dylib на osx?
.dylib - это динамическое расширение библиотеки в OSX, но мне никогда не было ясно, когда я не могу / не должен использовать традиционный общий объект unix.so.
Некоторые из вопросов, которые у меня есть:
- На концептуальном уровне, каковы основные различия между.so и.dylib?
- Когда можно / нужно использовать один поверх другого?
- Советы и рекомендации по компиляции (например, замена gcc -shared -fPIC, так как это не работает на osx)
4 ответа
Формат объектного файла Mach-O, используемый Mac OS X для исполняемых файлов и библиотек, различает общие библиотеки и динамически загружаемые модули. использование otool -hv some_file
чтобы увидеть тип файла some_file
,
Общие библиотеки Mach-O имеют тип файла MH_DYLIB
держи расширение.dylib. Они могут быть связаны с обычными статическими флагами компоновщика, например -lfoo
для libfoo.dylib. Они могут быть созданы путем передачи -dynamiclib
флаг для компилятора. (-fPIC
является значением по умолчанию и не должно быть указано.)
Загружаемые модули называются "связками" в Mach-O. У них есть тип файла MH_BUNDLE
, Они могут нести любое расширение; расширение .bundle
рекомендуется Apple, но большинство портированных программ использует .so
ради совместимости. Как правило, вы будете использовать пакеты для плагинов, которые расширяют приложение; в таких ситуациях пакет будет связываться с двоичным файлом приложения, чтобы получить доступ к экспортированному API приложения. Они могут быть созданы путем передачи -bundle
флаг для компилятора.
Как dylibs, так и комплекты могут быть загружены динамически с помощью dl
API (например, dlopen
, dlclose
). Невозможно связать пакеты, как если бы они были общими библиотеками. Однако возможно, что пакет связан с реальными общими библиотеками; они будут загружены автоматически при загрузке пакета.
Исторически различия были более значительными. В Mac OS X 10.0 не было возможности динамически загружать библиотеки. Набор API для Dyld (например, NSCreateObjectFileImageFromFile
, NSLinkModule
) были добавлены 10.1 для загрузки и выгрузки пакетов, но они не работали для dylibs. dlopen
библиотека совместимости, которая работала со связками, была добавлена в 10.3; в 10,4, dlopen
была переписана, чтобы быть родной частью dyld и добавлена поддержка загрузки (но не выгрузки) dylibs. Наконец, 10.5 добавлена поддержка использования dlclose
с dylibs и устаревшими API-интерфейсами dyld.
В системах ELF, таких как Linux, обе используют один и тот же формат файла; любой фрагмент общего кода может быть использован как библиотека и для динамической загрузки.
Наконец, имейте в виду, что в Mac OS X "пакет" может также ссылаться на каталоги со стандартизованной структурой, которая содержит исполняемый код и ресурсы, используемые этим кодом. Существует некоторое концептуальное перекрытие (особенно с "загружаемыми пакетами", такими как плагины, которые обычно содержат исполняемый код в форме пакета Mach-O), но их не следует путать с пакетами Mach-O, описанными выше.
Дополнительные ссылки:
- Руководство по портированию Fink, основа для этого ответа (хотя и устарела, как было написано для Mac OS X 10.3).
- лд (1) и длопен (3)
- Темы программирования динамических библиотек
- Темы программирования Mach-O
Разница между.dylib и.so в Mac OS X заключается в том, как они компилируются. Для файлов.so вы используете -shared, а для.dylib вы используете -dynamiclib. И.so, и.dylib взаимозаменяемы как файлы динамических библиотек и имеют тип DYLIB или BUNDLE. Вот отсчет для разных файлов, показывающих это.
libtriangle.dylib:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 17 1368 NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS
libtriangle.so:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 17 1256 NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS
triangle.so:
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL 0x00 BUNDLE 16 1696 NOUNDEFS DYLDLINK TWOLEVEL
Причина, по которой они эквивалентны в Mac OS X, заключается в обратной совместимости с другими программами UNIX OS, которые компилируются в тип файла.so.
Замечания по компиляции: независимо от того, компилируете ли вы файл.so или файл.dylib, вам нужно вставить правильный путь в динамическую библиотеку на этапе компоновки. Это можно сделать, добавив -install_name и путь к файлу к команде связывания. Если вы этого не сделаете, вы столкнетесь с проблемой, описанной в этом посте: Mac-Dynamic Library Craziness (может быть только Fortran).
Просто замечание, которое я только что сделал при создании простого кода для OSX с помощью cmake:
cmake... -DBUILD_SHARED_LIBS = OFF...
создает.so файлы
в то время как
cmake ... -DBUILD_SHARED_LIBS=ON ...
создает файлы.dynlib.
Возможно, это кому-нибудь поможет.
Файл.so не является расширением UNIX для общей библиотеки.
Просто так получилось.
Проверьте строку 3b на странице общей библиотеки ArnaudRecipes
В основном.dylib - это расширение файла Ma c, используемое для обозначения общей библиотеки.