Apa perbedaan antara .so dan .dylib di osx?

214

.dylib adalah ekstensi pustaka dinamis pada OSX, tetapi belum pernah jelas bagi saya ketika saya tidak bisa / tidak boleh menggunakan objek unix .so yang dibagikan secara tradisional.

Beberapa pertanyaan yang saya miliki:

  • Pada level konseptual, apa perbedaan utama antara .so dan .dylib?
  • Kapan saya bisa / harus menggunakan satu di atas yang lain?
  • Trik & tip kompilasi (Misalnya, penggantian untuk gcc-shared -fPIC, karena itu tidak berfungsi di osx)
Trent Davies
sumber

Jawaban:

206

Format file objek Mach-O yang digunakan oleh Mac OS X untuk executable dan pustaka membedakan antara pustaka bersama dan modul yang dimuat secara dinamis . Gunakan otool -hv some_fileuntuk melihat tipe file dari some_file.

Pustaka bersama Mach-O memiliki tipe file MH_DYLIBdan membawa ekstensi .dylib. Mereka dapat dihubungkan dengan flag tautan statis biasa, misalnya -lfoountuk libfoo.dylib. Mereka dapat dibuat dengan mengirimkan -dynamiclibbendera ke kompiler. ( -fPICadalah default dan tidak perlu ditentukan.)

Modul yang dapat dimuat disebut "bundel" dalam bahasa Mach-O. Mereka memiliki tipe file MH_BUNDLE. Mereka dapat membawa ekstensi apa pun; ekstensi .bundledirekomendasikan oleh Apple, tetapi sebagian besar perangkat lunak porting menggunakan .sodemi kompatibilitas. Biasanya, Anda akan menggunakan bundel untuk plug-in yang memperpanjang aplikasi; dalam situasi seperti itu, bundel akan terhubung dengan biner aplikasi untuk mendapatkan akses ke API yang diekspor aplikasi. Mereka dapat dibuat dengan mengirimkan -bundlebendera ke kompiler.

Baik dylib dan bundel dapat dimuat secara dinamis menggunakan dlAPI (mis. dlopen, dlclose). Tidak mungkin untuk menautkan ke bundel seolah-olah mereka adalah perpustakaan bersama. Namun, ada kemungkinan bahwa bundel terkait dengan perpustakaan bersama nyata; itu akan dimuat secara otomatis ketika bundel dimuat.

Secara historis, perbedaannya lebih signifikan. Di Mac OS X 10.0, tidak ada cara untuk memuat pustaka secara dinamis. Serangkaian API dyld (misalnya NSCreateObjectFileImageFromFile, NSLinkModule) diperkenalkan dengan 10.1 untuk memuat dan membongkar bundel, tetapi mereka tidak bekerja untuk dylibs. Sebuah dlopenperpustakaan kompatibilitas yang bekerja dengan bundel ditambahkan di 10.3; pada 10.4, dlopenditulis ulang menjadi bagian asli dari dyld dan menambahkan dukungan untuk memuat (tetapi tidak menurunkan) dylibs. Akhirnya, 10,5 menambahkan dukungan untuk digunakan dlclosedengan dylibs dan tidak lagi menggunakan API yang sudah digunakan.

Pada sistem ELF seperti Linux, keduanya menggunakan format file yang sama ; setiap bagian dari kode bersama dapat digunakan sebagai perpustakaan dan untuk pemuatan dinamis.

Akhirnya, ketahuilah bahwa di Mac OS X, "bundle" juga dapat merujuk ke direktori dengan struktur standar yang menyimpan kode yang dapat dieksekusi dan sumber daya yang digunakan oleh kode itu. Ada beberapa tumpang tindih konseptual (terutama dengan "bundel yang dapat dimuat" seperti plugin, yang umumnya berisi kode yang dapat dieksekusi dalam bentuk bundel Mach-O), tetapi mereka tidak harus bingung dengan bundel Mach-O yang dibahas di atas.

Referensi tambahan:

Miles
sumber
1
Terima kasih atas komentar yang luas ini :) Apakah saya memahaminya dengan benar, bahwa jika saya memuat satu bundel dari bundel lain (yaitu path adalah app -> bundle A -> bundle B), maka bundel B tidak akan dapat melihat simbol dalam bundel A? Dan jika ya, apakah ada cara untuk menyelesaikan masalah ini? Saya baru saja memukulnya, saya pikir: stackoverflow.com/questions/4193539/...
Mikhail Edoshin
4
@noloader: -dynamiclibadalah bendera GCC. Itu membuat kompiler lolos -dylibke ld.
Mil
URL yang diperbarui untuk halaman manual untuk ld di Mac OSX: manpages.info/macosx/ld.1.html
netpoetica
18

File .so bukan ekstensi file UNIX untuk pustaka bersama.

Kebetulan itu adalah yang biasa.

Periksa baris 3b di halaman ArnaudRecipes sharedlib

Pada dasarnya .dylib adalah ekstensi file mac yang digunakan untuk menunjukkan lib bersama.

Martin York
sumber
9
@ninefingers. Benar. Tetapi beberapa alat akan menggunakan nilai default kecuali ada sesuatu yang sangat eksplisit. misal Compiler akan menggunakan ekstensi libray bersama yang ada di platform khusus saat flag -l <lib> digunakan (flag aktual mungkin sangat melintasi kompiler).
Martin York
14

Perbedaan antara .dylib dan .so pada mac os x adalah bagaimana mereka dikompilasi. Untuk file .so Anda menggunakan-shared dan untuk .dylib Anda menggunakan -dynamiclib. Baik .so dan .dylib dapat dipertukarkan sebagai file perpustakaan dinamis dan memiliki tipe sebagai DYLIB atau BUNDLE. Inilah pembacaan untuk berbagai file yang menunjukkan ini.

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

Alasan keduanya setara pada Mac OS X adalah untuk kompatibilitas mundur dengan program OS UNIX lain yang mengkompilasi ke tipe file .so.

Catatan kompilasi: apakah Anda mengkompilasi file .so atau file .dylib Anda harus memasukkan jalur yang benar ke perpustakaan dinamis selama langkah penautan. Anda melakukan ini dengan menambahkan -install_name dan path file ke perintah penautan. Jika Anda tidak melakukan ini, Anda akan mengalami masalah yang terlihat di posting ini: Mac Dynamic Library Craziness (Mungkin Fortran Only) .

Zachary Kraus
sumber
bagaimana saya bisa membuat ./configureuntuk menghasilkan .dylibfile daripada file bundel .so? ./configure --enable-sharedtidak melakukan tugas ini.
Admia
dari pengalaman saya sebagian besar file konfigurasi pada mac akan membangun file .so atau file perpustakaan statis karena file konfigurasi menggunakan nama file unix / linux standar.
Zachary Kraus
4

Hanya pengamatan yang baru saja saya buat sambil membuat kode naif di OSX dengan cmake:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

membuat file .so

sementara

cmake ... -DBUILD_SHARED_LIBS=ON ...

membuat file .dynlib .

Mungkin ini bisa membantu siapa saja.

pengguna2996950
sumber