OSXでの.soと.dylibの違いは何ですか?


214

.dylibはOSXの動的ライブラリ拡張ですが、従来のUNIXの.so共有オブジェクトを使用できない、または使用してはならない場合、私にはわかりませんでした。

私が持っている質問のいくつか:

  • 概念的なレベルで、.soと.dylibの主な違いは何ですか?
  • いつどちらを使用できますか?
  • コンパイルのトリックとヒント(たとえば、osxでは機能しないため、gcc -shared -fPICの置き換え)

回答:


206

Mac OS Xで実行可能ファイルとライブラリに使用されるMach-Oオブジェクトファイル形式は、共有ライブラリ動的に読み込まれるモジュールを区別しますotool -hv some_fileのファイルタイプを確認するために使用しますsome_file

Mach-O共有ライブラリにはファイルタイプがMH_DYLIBあり、拡張子.dylib が付いています。それらは、たとえば-lfoolibfoo.dylibの場合など、通常の静的リンカーフラグとリンクできます。-dynamiclibフラグをコンパイラーに渡すことで作成できます。(-fPICデフォルトであり、指定する必要はありません。)

ロード可能なモジュールは、Mach-Oスピーチでは「バンドル」と呼ばれます。ファイルの種類がありますMH_BUNDLE。彼らはどんな拡張子も運ぶことができます。拡張機能.bundleはAppleによって推奨されていますが.so、互換性のためにほとんどの移植ソフトウェアが使用しています。通常、アプリケーションを拡張するプラグインにはバンドルを使用します。このような状況では、バンドルはアプリケーションバイナリにリンクして、アプリケーションのエクスポートされたAPIにアクセスします。-bundleフラグをコンパイラーに渡すことで作成できます。

dylibとバンドルの両方は、dlAPI(dlopenなどdlclose)を使用して動的にロードできます。バンドルを共有ライブラリのようにリンクすることはできません。ただし、バンドルが実際の共有ライブラリに対してリンクされている可能性があります。これらは、バンドルがロードされるときに自動的にロードされます。

歴史的に、違いはより重要でした。Mac OS X 10.0では、ライブラリを動的にロードする方法がありませんでした。バンドルをロードおよびアンロードするためにNSCreateObjectFileImageFromFile、dyld APIのセット(などNSLinkModule)が10.1で導入されましたが、dylibでは機能しませんでした。dlopenバンドルで動作する互換性ライブラリは10.3で追加されました。10.4では、dlopendyldのネイティブ部分に書き直され、dylibのロード(アンロードではない)のサポートが追加されました。最後に、10.5 dlcloseはdylibs での使用のサポートを追加し、dyld APIを非推奨にしました。

LinuxなどのELFシステムでは、どちらも同じファイル形式を使用します。共有コードの任意の部分をライブラリとして使用したり、動的ロードに使用したりできます。

最後に、Mac OS Xでは、「バンドル」は、実行可能コードとそのコードで使用されるリソースを保持する標準化された構造のディレクトリを指すこともあります。いくつかの概念的なオーバーラップがあります(特に、プラグインのような「ロード可能なバンドル」とは通常、Mach-Oバンドルの形式で実行可能コードが含まれています)が、上記のMach-Oバンドルと混同しないでください。

追加の参照:


1
この広範なコメントをありがとう:)それを正しく理解していますか?私が別のバンドルから1つのバンドルをロードすると(つまり、パスがapp->バンドルA->バンドルB)、バンドルBは何も表示できなくなりますバンドルAのシンボル?もしそうなら、どういうわけかこれを解決する方法はありますか?私はちょうど私が思うに、それをヒットしました:stackoverflow.com/questions/4193539/...
ミハイルEdoshin

4
@noloader:-dynamiclibGCCフラグです。コンパイラー-dylibをldに渡します。
マイル

Mac OSX上のldのマニュアルページの更新されたURL:manpages.info/macosx/ld.1.html
netpoetica

18

ファイル.soは、共有ライブラリのUNIXファイル拡張子ではありません。

それはたまたま一般的なものです。

ArnaudRecipes sharedlibページの 3b行目を確認してください

基本的に.dylibは、共有libを示すために使用されるmacファイル拡張子です。


9
@ninefingers。正しい。ただし、一部のツールは、明示的なものでない限り、デフォルト値を使用します。たとえば、-l <lib>フラグが使用されている場合、コンパイラーはプラットフォーム固有の共有libray拡張機能を使用します(実際のフラグはコンパイラー間で非常に異なる場合があります)。
マーティンヨーク

14

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で2つが同等である理由は、.soファイルタイプにコンパイルされる他のUNIX OSプログラムとの下位互換性のためです。

コンパイルに関する注意事項:.soファイルまたは.dylibファイルのどちらをコンパイルする場合でも、リンク手順中に動的ライブラリに正しいパスを挿入する必要があります。これを行うには、-install_nameとファイルパスをリンクコマンドに追加します。これを行わないと、この投稿に見られる問題に遭遇します:Mac Dynamic Library Craziness(May be Fortran Only)


バンドルファイルではなくファイル./configureを生成する方法を教えてください。 このタスクは行いません。.dylib.so./configure --enable-shared
Admia

私の経験では、構成ファイルは標準のUNIX / Linuxファイル名を使用しているため、Macのほとんどの構成ファイルは.soファイルまたは静的ライブラリファイルをビルドします。
Zachary Kraus

4

cmakeを使用してOSXで単純なコードをビルドしているときにちょうど観察したこと:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

.soファイルを作成します

ながら

cmake ... -DBUILD_SHARED_LIBS=ON ...

.dynlibファイルを作成します。

たぶん、これは誰にとっても役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.