リンカーとライブラリ

バージョン管理ファイル名の管理

リンク編集では、一般的にリンカーの-l オプションを使用して共有オブジェクトの依存関係を参照します。このオプションは、リンカーのライブラリ検索メカニズムを使用して接頭辞 lib と接尾辞 .so が付いた共有オブジェクトを探します。

ただし、実行時に、共有オブジェクト依存関係は、バージョン管理ファイル名として存在していなければなりません。2 つの命名規約に従う 2 つの異なる共有オブジェクトを維持するのではなく、2 つのファイル名間にファイルシステムリンクを作成します。

たとえば、シンボリックリンクを使用すれば、共有オブジェクト libfoo.so.1 をコンパイル環境で利用できるようにすることができます。コンパイルファイル名は、実行時ファイル名へのシンボリックリンクになります。


$ cc -o libfoo.so.1 -G -K pic foo.c
$ ln -s libfoo.so.1 libfoo.so
$ ls -l libfoo*
lrwxrwxrwx  1 usr grp          11 1991 libfoo.so -> libfoo.so.1
-rwxrwxr-x  1 usr grp        3136 1991 libfoo.so.1

シンボリックリンクまたはハードリンクを使用できます。ただし記述および診断目的としては、シンボリックリンクの方が有効です。

共有オブジェクト libfoo.so.1 は、実行時環境用に生成されています。シンボリックリンク libfoo.so は、コンパイル環境でのこのファイルの使用も有効にしています。


$ cc -o prog main.o -L. -lfoo

リンカーは、シンボリックリンク libfoo.so を追って見つける共有オブジェクト libfoo.so.1 によって記述されたインタフェースを使用して、再配置可能オブジェクト main.o を処理します。

一連のソフトウェアリリースにわたって、libfoo.so の新しいバージョンをインタフェースを変更して配布できます。シンボリックリンクを変更することによって、適用可能なインタフェースを使用するよう、コンパイル環境を構築することができます。


$ ls -l libfoo*
lrwxrwxrwx  1 usr grp          11 1993 libfoo.so -> libfoo.so.3
-rwxrwxr-x  1 usr grp        3136 1991 libfoo.so.1
-rwxrwxr-x  1 usr grp        3237 1992 libfoo.so.2
-rwxrwxr-x  1 usr grp        3554 1993 libfoo.so.3

この例では、共有オブジェクトの 3 つの主要バージョンが使用できます。libfoo.so.1libfoo.so.2 の 2 つのバージョンは、既存アプリケーションに対する依存関係を提供します。libfoo.so.3 は、新しいアプリケーションを作成して実行するための最新主要リリースを提供します。

このシンボリックリンクのメカニズムを使用するだけでは、コンパイル環境での共有オブジェクトが実行時バージョン管理ファイル名と同期をとることができません。例が示しているように、リンカーは、動的実行可能ファイル prog に、リンカーが処理した共有オブジェクトのファイル名を記録します。この場合、リンカーで表示されるファイル名はコンパイル環境のファイルです。


$ dump -Lv prog

prog:
 **** DYNAMIC SECTION INFORMATION ****
.dynamic:
[INDEX] Tag      Value
[1]     NEEDED   libfoo.so
.........

アプリケーション prog が実行されると、実行時リンカーは、依存関係 libfoo.so を検索します。prog は、このシンボリックリンクが指すすべてのファイルに結合されます。

正しい実行時名を依存関係として記録するには、共有オブジェクト libfoo.so.1 を「soname」定義によって構築する必要があります。この定義は、共有オブジェクトの実行時名を識別します。この名前は、共有オブジェクトに対してリンクするすべてのオブジェクトによって、依存関係名として使用されます。この定義は、共有オブジェクトの作成中に -h オプションを使用して与えることができます。


$ cc -o libfoo.so.1 -G -K pic -h libfoo.so.1 foo.c
$ ln -s libfoo.so.1 libfoo.so
$ cc -o prog main.o -L. -lfoo
$ dump -Lv prog

prog:
 **** DYNAMIC SECTION INFORMATION ****
.dynamic:
[INDEX] Tag      Value
[1]     NEEDED   libfoo.so.1
.........

このシンボリックリンクと「soname」メカニズムは、コンパイル環境と実行時環境の共有オブジェクト命名規約の間に強固な同期を確立します。リンク編集中に処理されたインタフェースは、生成された出力ファイルに正確に記録されます。この記録によって、意図したインタフェースが実行時に提供されます。