Які відмінності між .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.

Бібліотеки спільного користування Mach-O мають тип файлу MH_DYLIBі несуть розширення .dylib. Вони можуть бути пов'язані із звичайними прапорцями статичного лінкера, наприклад, -lfooдля libfoo.dylib. Їх можна створити, передавши -dynamiclibпрапор компілятору. ( -fPICє типовим і не потрібно вказувати.)

Модулі, що завантажуються, називаються "розшаруваннями" в мові Mach-O. Вони мають тип файлу MH_BUNDLE. Вони можуть нести будь-яке розширення; розширення .bundleрекомендується компанією Apple, але більшість портативних програм використовується .soдля сумісності. Зазвичай ви будете використовувати пакети для плагінів, які розширюють додаток; у таких ситуаціях пакет буде зв’язуватися з бінарним додатком, щоб отримати доступ до експортованого API програми. Їх можна створити, передавши -bundleпрапор компілятору.

І диліби, і пучки можуть динамічно завантажуватися за допомогою dlAPI (наприклад dlopen, dlclose). Неможливо зв’язати їх з наборами, як якщо б вони були спільними бібліотеками. Однак можливо, що пакет пов'язаний з реальними спільними бібліотеками; вони завантажуватимуться автоматично, коли пакет буде завантажений.

Історично розбіжності були більш істотними. У Mac OS X 10.0 не було можливості динамічно завантажувати бібліотеки. Набір кольорів API (наприклад NSCreateObjectFileImageFromFile, NSLinkModule) було введено з 10.1 для завантаження та вивантаження пакетів, але вони не працювали для дилібів. dlopenБібліотеки сумісності , яка працювала з пучками була додана в 10.3; у 10.4, dlopenбуло переписано як нативну частину dyld та додано підтримку для завантаження (але не вивантаження) дилібів. Нарешті, 10.5 додала підтримку для використання dlcloseз dylibs та застаріла API dild.

У системах ELF, таких як Linux, обидва використовують однаковий формат файлів ; будь-який фрагмент спільного коду може використовуватися як бібліотека та для динамічного завантаження.

Нарешті, майте на увазі, що в Mac OS X "пакет" також може посилатися на каталоги зі стандартизованою структурою, що містить виконуваний код та ресурси, використовувані цим кодом. Існує певна концептуальна дублювання (зокрема, з "завантажуваними пакетами", такими як плагіни, які, як правило, містять виконуваний код у вигляді пакету Mach-O), але їх не слід плутати з розглянутими вище пакетами Mach-O.

Додаткові посилання:


1
Дякую за цей обширний коментар :) Чи правильно я розумію, що якщо я завантажую один пакет із іншого (тобто шлях - додаток -> пакет A -> пакет B), пакет B не зможе побачити жодного символи в пакеті A? І якщо так, чи є способи як-небудь вирішити це? Я просто вдарив його, я думаю: stackoverflow.com/questions/4193539 / ...
Михайло Edoshin

4
@noloader: -dynamiclibпрапор GCC. Це змушує компілятор перейти -dylibдо ld.
Майлз

Оновлена ​​URL-адреса для чоловічої сторінки для ld на Mac OSX: manpages.info/macosx/ld.1.html
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 Craziness Library (може бути лише 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.