.soや.dylibや.aファイル、共有ライブラリなどについて調べてみた
MacPortsでswftools@0.9.2を入れようとしたら失敗した - kanonjiの日記、MacPortsで入れる代わりに自前でビルドしたライブラリを使ってswftoolsをビルドしてみた - kanonjiの日記で、ビルドする時のライブラリについての知識が足りず困ったので、ちょっと調べてみました。基本的にLinuxについて調べてて、Macについても分かったところがあるって感じです。
ちゃんとまとめるほど理解出来てるわけじゃないので、分かった事を並べる感じで書きます。勘違いしてたり、ちょっと用語がおかしかったりするかもしれません。
LinuxとMacでは仕組みが違う
LinuxではELF(Executable and Linking Format)という実行ファイルフォーマットがあって、この辺を調べていくとよくELFという単語を見かけます。
Macはというと、Mach-Oという実行ファイルフォーマットが採用されています。
別にUnix(Mac)とLinuxで分かれているわけじゃなく、ELFはBSD系の一部とかSolarisでも使われているんだとか。
Linuxのライブラリの分類
Interactive shell for blockdiag
Linux 動的ライブラリーの徹底調査にあった画像を元に、調べた補足も加えつつ図を描きなおしました。後でリンク切れになってもやだし。
.a
ファイルはStaticライブラリ.so
はShared Objectで、Sharedライブラリ。- 厳密には共有ライブラリって言葉はSharedライブラリの事だと思うけど、Dynamic Linking(動的リンク)して使う方を指す事が多い。
- Dynamic Loadingも*1共有ライブラリの一種。
- Dynamic Loadingはダイナミックライブラリと呼ばれる事もある。
共有ライブラリのDynamic LinkingとDynamic Loadingについて
図の参考にしたIBMの記事が英語だったから、そのまま書いてるけど、Dynamic Linkingとは動的リンクして使う共有ライブラリって事だと思う。逆にDynamic Loadingは動的ローディングして使う共有ライブラリだと思います。
共有ライブラリは、プログラムの実行時にロードされます。マシンによっては、 その共有ライブラリがなかったり、バージョンが違ったりして、動作しないことがあります。 .so と .sa で終わるファイルです。.sa は、古い a.out 形式で使われた共有ライブラリです。
CuÌîbm¯
ダイナミックライブラリは、共有ライブラリの1種です。実行時に 関数を使って ロードしたり、アンロードしたりできます。
ただ、Dynamic Loadingを共有ライブラリと呼んで、Dynamic Loadingをダイナミックライブラリと呼んで分けている記事もありました。
Mac、Mach-Oでは
Mach-0 の仕様の一つで,多くの人を驚かせるものとして, 共有ライブラリ と 動的ローダブル・モジュールを厳密に区別する点があります. ELF システムでは両者は同質で,共有コードのどの部分でも,ライブラリとしても動的ローディングにも使うことができます.
Mach-O 共有ライブラリ のファイルタイプは MH_DYLIB で,拡張子は .dylib となります. これは通常の静的リンカフラグ,例えば libfoo.dylib の場合は -lfoo でリンクすることができます. しかし,モジュールとしてロードすることはできません.
Fink - 移植 - 共有コード
まず、Dynamic Loadingの事を動的ローダブル・モジュールと、モジュールと呼んでます。なので、この記事では、共有ライブラリ=Dynamic Linkingになるっぽい。
- LinuxではDynamic LinkingもDynamic Loadingも同じ物で、使い方の問題として、Dynamic LinkingとDynamic Loadingがある。
- Dynamic Loadingで使う場合、ライブラリとしてというより、モジュールとしてという捉え方が正しいのかもしれない。
- MacではDynamic LinkingとDynamic Loadingは厳密に区別されている。
ローダブル・モジュールは Mach-O の用語では"バンドル"と言われ,ファイルタイプは MH_BUNDLE です. これを用いるコンポーネントは拡張子を気にしないので,拡張子は何でも構いません. .bundle という拡張子が Apple の推奨ですが,移植されたソフトウェアのほとんどは,互換性のため .so を使っています. バンドルは dyld API を用いて動的にロード/アンロードされることができますし,この API の上に dlopen() をエミュレートするラッパもあります. バンドルを 共有ライブラリ のようにリンクすることはできませんが,バンドルを 共有ライブラリ にリンクさせることは可能です. この場合,バンドルがロードされた際に両者ともロードされます.
Fink - 移植 - 共有コード
同じ記事の続き。
余談
よく知らない分野の事で、同じことを指す言葉が色々あって、とりあえず最初に見かけたのを軸にしてみたけど、すっごい分かりにくいね。Dynamic LinkingとDynamic Loadingじゃ無くて別の言葉を軸にすればよかったかも。この2つ、どう呼ぶのが多くの人に分かりやすいんだろう?
書いた日
2012-08-11
例によって下書きのまま放置してた
*1:前述の通り共有ライブラリといえばDynamic Linkingの事を指す事が多いけど