リンカーとライブラリ

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

「命名規約」では、リンク編集中に共有オブジェクトを入力するための最も一般的な手法は、-l オプションを使用する方法であると述べました。このオプションは、リンカーのライブラリ検索機構を使用して接頭辞 lib と接尾辞 .so が付いた共有オブジェクトを探します。

ただし、実行時に、共有オブジェクト依存関係は、そのバージョンアップファイル名形式で存在していなければなりません。これらのオブジェクトのバージョンを管理するための最も一般的な手法は、これらの命名規約に従う 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 を処理します。

一連のソフトウェアリリースに対して、この共有オブジェクトの新しいバージョンが変更されたインタフェースによって配布される場合、コンパイル環境はシンボルリンクを変更することで適用可能なインタフェースを使用するように構築することができます。次に例を示します。


$ 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 を検索し、結果として、これはこのシンボルリンクが指すすべてのファイルに結合されます。

依存関係として記録される正しい実行時名を指定するには、共有オブジェクト 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 機構は、コンパイル環境と実行時環境の共有オブジェクト命名規約の間に強固な同期を確立しました。これによって、リンク編集中に処理されたインタフェースは、生成された出力ファイルに正確に記録されます。この記録によって、意図したインタフェースが実行時に提供されます。