.soや.dylibや.aファイル、共有ライブラリなどについて調べてみた

MacPortsでswftools@0.9.2を入れようとしたら失敗した - kanonjiの日記MacPortsで入れる代わりに自前でビルドしたライブラリを使ってswftoolsをビルドしてみた - kanonjiの日記で、ビルドする時のライブラリについての知識が足りず困ったので、ちょっと調べてみました。基本的にLinuxについて調べてて、Macについても分かったところがあるって感じです。
ちゃんとまとめるほど理解出来てるわけじゃないので、分かった事を並べる感じで書きます。勘違いしてたり、ちょっと用語がおかしかったりするかもしれません。

LinuxMacでは仕組みが違う

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 形式で使われた共有ライブラリです。
ダイナミックライブラリは、共有ライブラリの1種です。実行時に 関数を使って ロードしたり、アンロードしたりできます。

ƒ‰ƒCƒuƒ‰ƒŠ‚ÌŠî‘b’mŽ¯

ただ、Dynamic Loadingを共有ライブラリと呼んで、Dynamic Loadingをダイナミックライブラリと呼んで分けている記事もありました。

MacMach-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 Loadingに当たるものは、Mac側ではバンドルと呼ばれる。
  • Dynamic Linkingな共有ライブラリは.soではなく.dylibファイル。
  • Dynamic Loadingの方は.bundleが推奨されるが、Linuxからの移植の場合、拡張子は.soのままな事が多い。

余談

よく知らない分野の事で、同じことを指す言葉が色々あって、とりあえず最初に見かけたのを軸にしてみたけど、すっごい分かりにくいね。Dynamic LinkingとDynamic Loadingじゃ無くて別の言葉を軸にすればよかったかも。この2つ、どう呼ぶのが多くの人に分かりやすいんだろう?

書いた日

2012-08-11
例によって下書きのまま放置してた

*1:前述の通り共有ライブラリといえばDynamic Linkingの事を指す事が多いけど