.dylib は macOS の動的ライブラリ拡張機能ですが、従来の Unix .so 共有オブジェクトを使用できない、または使用すべきでないことが私にはわかりませんでした。
私が抱いている疑問のいくつかは次のとおりです。
- 概念レベルで、.so と .dylib の主な違いは何ですか?
- どちらを優先して使用すべきですか?
- コンパイルのコツとヒント (たとえば、OSX では動作しない gcc -shared -fPIC の代替)
ベストアンサー1
Mac OS X が実行可能ファイルとライブラリに使用する Mach-O オブジェクト ファイル形式は、共有ライブラリと動的にロードされるモジュールを区別します。 を使用してotool -hv some_file
、のファイルタイプを確認しますsome_file
。
Mach-O 共有ライブラリは、ファイル タイプが でMH_DYLIB
、拡張子は .dylib です。これらは、通常の静的リンカー フラグ (例: libfoo.dylib) を使用してリンクできます。これらは、フラグをコンパイラに-lfoo
渡すことで作成できます。(はデフォルトであり、指定する必要はありません。)-dynamiclib
-fPIC
ロード可能なモジュールは、Mach-O では「バンドル」と呼ばれます。ファイル タイプは です。MH_BUNDLE
任意の拡張子を付けることができます。拡張子は.bundle
Apple によって推奨されていますが、ほとんどの移植されたソフトウェア.so
では互換性のために が使用されています。通常、バンドルはアプリケーションを拡張するプラグインに使用します。このような状況では、バンドルはアプリケーションのバイナリにリンクして、アプリケーションのエクスポートされた API にアクセスします。フラグを-bundle
コンパイラに渡すことで作成できます。
dl
dylib とバンドルは両方とも、API (例dlopen
: 、 )を使用して動的にロードできますdlclose
。バンドルを共有ライブラリのようにリンクすることはできません。ただし、バンドルを実際の共有ライブラリにリンクすることは可能です。バンドルがロードされると、それらの共有ライブラリも自動的にロードされます。
歴史的には、違いはもっと顕著でした。Mac OS X 10.0 では、ライブラリを動的にロードする方法はありませんでした。バンドルをロードおよびアンロードするための dyld API セット (例: NSCreateObjectFileImageFromFile
、NSLinkModule
) が 10.1 で導入されましたが、dylib では機能しませんでした。dlopen
バンドルで機能する互換性ライブラリは 10.3 で追加され、10.4 ではdlopen
dyld のネイティブな部分になるように書き直され、dylib のロード (アンロードはなし) のサポートが追加されました。最後に、10.5 では dylib での使用のサポートが追加されdlclose
、dyld API は非推奨になりました。
LinuxのようなELFシステムでは、どちらも同じファイル形式を使用します; 共有コードの任意の部分をライブラリとして使用したり、動的ロードに使用したりできます。
最後に、Mac OS Xでは、"バンドル"実行可能コードとそのコードで使用されるリソースを保持する標準化された構造を持つディレクトリを指すこともできます。概念的に重複する部分もありますが (特にプラグインなどの「ロード可能なバンドル」の場合、通常、Mach-O バンドルの形式で実行可能コードが含まれます)、上で説明した Mach-O バンドルと混同しないでください。
追加参考資料:
- Fink 移植ガイド、この回答の根拠です(ただし、Mac OS X 10.3 用に書かれたものなので、かなり古くなっています)。
- ld(1)そしてdlopen(3)
- 動的ライブラリプログラミングのトピック
- Mach-O プログラミングトピック