簡體   English   中英

macOS 上的 .so 和 .dylib 有什么區別?

[英]What are the differences between .so and .dylib on macOS?

.dylib 是 macOS 上的動態庫擴展,但是當我不能/不應該使用傳統的 unix .so 共享對象時,我一直不清楚。

我的一些問題:

  • 在概念層面上,.so 和 .dylib 之間的主要區別是什么?
  • 我什么時候可以/應該使用一個?
  • 編譯技巧和技巧(例如,替換 gcc -shared -fPIC,因為它不適用於 osx)

Mac OS X 用於可執行文件和庫的 Mach-O 目標文件格式區分共享庫動態加載的模塊 使用otool -hv some_file看到的文件類型some_file

Mach-O 共享庫的文件類型為MH_DYLIB ,擴展名為 .dylib。 它們可以與通常的靜態鏈接器標志鏈接,例如-lfoo用於 libfoo.dylib。 它們可以通過將-dynamiclib標志傳遞給編譯器來創建。 -fPIC是默認值,無需指定。)

可加載模塊在 Mach-O 語言中被稱為“包”。 它們的文件類型MH_BUNDLE 它們可以攜帶任何分機; 擴展名.bundle是 Apple 推薦的,但大多數移植的軟件為了兼容性而使用.so 通常,您將對擴展應用程序的插件使用捆綁包; 在這種情況下,bundle 將鏈接到應用程序二進制文件以訪問應用程序的導出 API。 它們可以通過將-bundle標志傳遞給編譯器來創建。

dylib 和包都可以使用dl API(例如dlopendlclose )動態加載。 不可能像捆綁共享庫一樣鏈接捆綁包。 但是,bundle 可能鏈接到真正的共享庫; 這些將在加載包時自動加載。

從歷史上看,差異更為顯着。 在 Mac OS X 10.0 中,無法動態加載庫。 10.1 中引入了一組 dyld API(例如NSCreateObjectFileImageFromFileNSLinkModule )來加載和卸載包,但它們不適用於 dylib。 在 10.3 中添加了一個與捆綁包一起使用的dlopen兼容性庫; 在 10.4 中, dlopen被重寫為 dyld 的本機部分,並添加了對加載(但不卸載)dylib 的支持。 最后,10.5 添加了對將dlclose與 dylibs 一起使用的支持,並棄用了 dyld API。

在像 Linux 這樣的 ELF 系統上,兩者都使用相同的文件格式 任何一段共享代碼都可以用作庫和用於動態加載。

最后,請注意,在 Mac OS X 中, “捆綁”可以指具有標准化結構的目錄,其中包含可執行代碼和該代碼使用的資源。 有一些概念上的重疊(特別是像插件這樣的“可加載包”,它們通常包含 Mach-O 包形式的可執行代碼),但它們不應與上面討論的 Mach-O 包混淆。

補充參考:

文件 .so 不是共享庫的 UNIX 文件擴展名。

它只是碰巧是一個常見的。

檢查ArnaudRecipes 共享庫頁面上的第3b 行

基本上 .dylib 是用於指示共享庫的 mac 文件擴展名。

mac os x 上的 .dylib 和 .so 之間的區別在於它們的編譯方式。 對於 .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 上等效的原因是為了與編譯為 .so 文件類型的其他 UNIX OS 程序向后兼容。

編譯注意事項:無論編譯.so文件還是.dylib文件,都需要在鏈接步驟中將正確的路徑插入到動態庫中。 您可以通過將 -install_name 和文件路徑添加到鏈接命令來完成此操作。 如果你不這樣做,你會遇到這篇文章中看到的問題: Mac Dynamic Library Craziness (May be Fortran Only)

只是我在使用 cmake 在 OSX 上構建原始代碼時所做的觀察:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

創建.so文件

盡管

cmake ... -DBUILD_SHARED_LIBS=ON ...

創建.dynlib文件。

也許這對任何人都有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM