Каковы различия между .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.