Каковы различия между .so и .dylib на osx?


214

.dylib - это динамическое расширение библиотеки в OSX, но мне никогда не было ясно, когда я не могу / не должен использовать традиционный общий объект unix .so.

Некоторые из вопросов, которые у меня есть:

  • На концептуальном уровне, каковы основные различия между .so и .dylib?
  • Когда можно / нужно использовать один поверх другого?
  • Рекомендации и рекомендации по компиляции (например, замена gcc -shared -fPIC, так как он не работает на osx)

Ответы:


206

Формат объектного файла Mach-O, используемый Mac OS X для исполняемых файлов и библиотек, различает общие библиотеки и динамически загружаемые модули . Используйте, otool -hv some_fileчтобы увидеть тип файла some_file.

MH_DYLIBОбщие библиотеки Mach-O имеют тип файла и имеют расширение .dylib. Они могут быть связаны с обычными статическими флагами компоновщика, например, -lfooдля libfoo.dylib. Они могут быть созданы путем передачи -dynamiclibфлага компилятору. ( -fPICявляется значением по умолчанию и не должно быть указано.)

Загружаемые модули называются «связками» в Mach-O. У них есть тип файла MH_BUNDLE. Они могут нести любое расширение; .bundleApple рекомендует это расширение , но большинство переносимого программного обеспечения использует его .soдля совместимости. Как правило, вы будете использовать пакеты для плагинов, которые расширяют приложение; в таких ситуациях пакет связывается с двоичным файлом приложения, чтобы получить доступ к экспортированному API приложения. Они могут быть созданы путем передачи -bundleфлага компилятору.

Как библиотеки, так и пакеты могут быть динамически загружены с помощью dlAPI (например 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, описанными выше.

Дополнительные ссылки:


1
Спасибо за этот обширный комментарий :) Правильно ли я понимаю, что если я загружу один пакет из другого пакета (т. Е. Путь app -> пакет A -> пакет B), то пакет B не сможет увидеть символы в пачке A? И если да, есть ли способы как-то решить эту проблему? Я только что ударил, я думаю: stackoverflow.com/questions/4193539/…
Михаил Едошин

4
@noloader: -dynamiclibэто флаг GCC. Это заставляет компилятор перейти -dylibна ld.
Майлз

Обновлен URL-адрес для страницы руководства
netpoetica

18

Файл .so не является расширением UNIX для общей библиотеки.

Просто так получилось.

Проверьте строку 3b на странице общей библиотеки ArnaudRecipes

В основном .dylib - это расширение файла Mac, используемое для обозначения общей библиотеки.


9
@ninefingers. Верный. Но некоторые инструменты будут использовать значения по умолчанию, если что-то не очень явно. Например, компиляторы будут использовать расширение общей библиотеки для конкретной платформы, когда используется флаг -l <lib> (фактический флаг может сильно различаться у разных компиляторов).
Мартин Йорк

14

Разница между .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) .


Как я могу сделать, ./configureчтобы генерировать .dylibфайлы, а не связывать файлы .so? ./configure --enable-sharedне выполняет эту задачу.
Адмиа

Исходя из моего опыта, большинство файлов конфигурации на Mac будет либо создавать файл .so, либо файл статической библиотеки, потому что файлы конфигурации используют стандартные имена файлов unix / linux.
Захария Крауса

4

Просто замечание, которое я только что сделал при создании простого кода для OSX с помощью cmake:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

создает .so файлы

пока

cmake ... -DBUILD_SHARED_LIBS=ON ...

создает файлы .dynlib .

Возможно, это кому-нибудь поможет.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.