リンカーとライブラリ

追加ライブラリとのリンク

通常、コンパイラドライバによって、適切なライブラリがリンカーに指定されているかどうかが確認されますが、ほとんどの場合、自分独自のライブラリを指定することが必要です。共有オブジェクトとアーカイブは、リンカーに必要な入力ファイルに明示的に命名することによって指定できますが、より一般的で柔軟性のある方法として、リンカーの -l オプションを使用する方法があります。

ライブラリの命名規約

規則により、通常、共有オブジェクトは接頭辞 lib と接尾辞 .so で指定され、アーカイブは接頭辞 lib と接尾辞 .a で指定されます。たとえば、libc.so とは、コンパイル環境で使用可能になった標準 C ライブラリの共有オブジェクトバージョンで、libc.a とは、そのアーカイブバージョンです。

これらの規則は、リンカーの -l オプションによって認識されます。このオプションは、通常、追加ライブラリをリンク編集に供給する場合に使用します。次の例では、リンカーに libfoo.so を検索するように指示し、これが検出できない場合には、libfoo.a を検索してから次の検索ディレクトリに移動するように指示しています。


$ cc -o prog file1.c file2.c -lfoo

注 -

命名規約には、共有オブジェクトの「コンパイル」環境での使用に関するものと、共有オブジェクトの実行時環境での使用に関するものがあります。コンパイル環境では、単に .so 接尾辞を使用するのに対し、実行時環境では、通常、追加のバージョン番号を指定した接尾辞を使用します。詳細については、「命名規約」および 「バージョンアップファイル名の管理」を参照してください。


動的モードでリンク編集を行う場合、共有オブジェクトとアーカイブとを組み合わせたものへのリンクを選択できます。静的モードでリンク編集を行う場合、入力を受け入れるのはアーカイブライブラリだけです。

動的モードで、ライブラリの検索を可能にする -l オプションを使用すると、リンカーは、まず、指定されたディレクトリ内で、指定された名前と一致する共有オブジェクトを検索します。一致するものが見つからない場合、リンカーは、次に同じディレクトリ内でアーカイブライブラリを検索します。静的モードで -l オプションを使用する場合は、アーカイブライブラリだけが検索されます。

共有オブジェクトとアーカイブとの混合体へのリンク

動的モードでのライブラリ検索メカニズムでは、指定されたディレクトリを調べて共有オブジェクトを検索し、次にアーカイブライブラリを検索しますが、-B オプションを使用すると必要な検索タイプのより適切なコントロールを保存できます。

コマンド行上に -Bdynamic-Bstatic オプションを必要な回数だけ指定することによって、ライブラリ検索は共有オブジェクトまたはアーカイブをそれぞれ切り替えることができます。たとえば、アーカイブ libfoo.a と共有オブジェクト libbar.so とリンクするには、次のコマンドを発行します。


$ cc -o prog main.o file1.c -Bstatic -lfoo -Bdynamic -lbar 

キーワード -Bstatic-Bdynamic は、正確には対称ではありません。-Bstatic を指定すると、リンカーは、次の -Bdynamic の発生まで入力として共有オブジェクトを受け入れませんが、-Bdynamic を指定すると、リンカーは、指定されたディレクトリ内で、まず最初に共有オブジェクトを検索し、次にアーカイブを検索します。

上記の例をより正確に説明すると、リンカーは、最初に libfoo.a を検索し、次に libbar.so を検索します。そしてこれに失敗すると libbar.a を検索します。最後に、libc.so を検索し、これに失敗すると libc.a を検索します。

コマンド行上のアーカイブの位置

コマンド行上のアーカイブの位置は、作成される出力ファイルに影響を及ぼします。リンカーがアーカイブを検索する唯一の目的は、以前に参照したことのある定義されていない仮の外部リファレンスを解析することです。この検索が完了し、必要な再配置可能オブジェクトが抽出されると、このアーカイブは、コマンド行上のアーカイブに続く入力ファイルから入手した新しいシンボルの解析には使用できません。たとえば、次のコマンドでは、file1.c から入手したことのあるシンボルリファレンスを解析するためだけに、libfoo.a を検索するように、リンカーに指示しています。


$ cc -o prog file1.c -Bstatic -lfoo file2.c file3.c -Bdynamic 

libfoo.a は、file2.c または file3.c のシンボルリファレンスを解析するためには、使用できません。


注 -

原則として、コマンド行の最後にアーカイブを指定するのが最善の方法です。ただし、最後にアーカイブを配置するには、複数の定義を重複させる必要がある場合は除きます。


リンカーが検索するディレクトリ

ここまでの例はすべて、リンカーが、コマンド行上にリストされたライブラリを検索する場所を認識していることを前提としています。デフォルトでは、32 ビットオブジェクトをリンクする場合、リンカーがライブラリを検索するディレクトリとして認識しているのは、2 つの標準的なディレクトリ /usr/ccs/lib/usr/lib です。64 ビットオブジェクトのリンクの場合は、1 つの標準的なディレクトリ /usr/lib/64 のみが使用されます。これ以外のディレクトリを検索させたい場合には、リンカーの検索パスに明示的に付加する必要があります。

リンカー検索パスを変更するには、コマンド行オプションを使用するか、環境変数を使用するという 2 種類の方法があります。

コマンド行オプションの使用

-L オプションを使用すると、ライブラリ検索に新しいパス名を追加できます。このオプションは、コマンド行上で遭遇したその地点で、検索パスに影響を与えます。たとえば、次のコマンドは、path1 (次に /usr/ccs/lib/usr/lib) を検索し、libfoo を検出しますが、libbar を検出する場合は、path1path2 (次に /usr/ccs/lib/usr/lib) を検索します。


$ cc -o prog main.o -Lpath1 file1.c -lfoo file2.c -Lpath2 -lbar

-L オプションを使用して定義されたパス名は、リンカー専用で、実行時リンカーが使用するために作成される出力ファイルイメージ内には記録されません。


注 -

カレントディレクトリ内のライブラリの検索にリンカーを使用する場合は、-L を指定する必要があります。ピリオド (.) を使用して、カレントディレクトリを示すことができます。


-Y オプションを使用すると、リンカーが検索するデフォルトのディレクトリを変更できます。このオプションに指定する引数は、ディレクトリのリストをコロンで区切った書式で示します。たとえば、次のコマンドは、ディレクトリ /opt/COMPILER/lib/home/me/lib 内だけを調べて libfoo を検索します。


$ cc -o prog main.c -YP,/opt/COMPILER/lib:/home/me/lib -lfoo

-Y オプションを使用して指定したディレクトリは、-L オプションを使用して補足できます。

環境変数の使用

コロンで区切られたディレクトリリストをとる環境変数 LD_LIBRARY_PATH を使用しても、リンカーのライブラリ検索パスを付加できます。この最も一般的な書式 LD_LIBRARY_PATH では、セミコロンで区切られた 2 つのディレクトリリストをとります。最初のリストは、コマンド行上に指定されたリストよりも前に検索され、2 番目のリストはコマンド行上のリストよりも後に検索されます。

ここでは、LD_LIBRARY_PATH の設定と、いくつかの -L オプションを指定したリンカーの呼出しを組み合わせています。


$ LD_LIBRARY_PATH=dir1:dir2;dir3
$ export LD_LIBRARY_PATH
$ cc -o prog main.c -Lpath1 ... -Lpath2 ... -Lpathn -lfoo

有効な検索パスは、次のとおりです。

dir1:dir2:path1:path2... pathn:dir3:/usr/ccs/lib:/usr/lib

LD_LIBRARY_PATH 定義の一部にセミコロンが指定されてない場合は、指定されたディレクトリリストは、-L オプションの後で解釈されます。次に例を示します。


$ LD_LIBRARY_PATH=dir1:dir2
$ export LD_LIBRARY_PATH
$ cc -o prog main.c -Lpath1 ... -Lpath2 ... -Lpathn -lfoo

ここでは、有効な検索パスは次のとおりです。

path1:path2... pathn:dir1:dir2:/usr/ccs/lib:/usr/lib


注 -

この環境変数は、実行時リンカーの検索パスを拡張する場合にも使用できます (詳細は、「実行時リンカーによって検索されるディレクトリ」を参照)。この環境変数がリンカーに影響しないようにするには、-i オプションを使用します。


実行時リンカーが検索するディレクトリ

デフォルトでは、実行時リンカーがライブラリを検出する場所として認識する標準的な場所は 1 つだけで、32 ビットオブジェクトを処理する場合は/usr/lib、64 ビットオブジェクトを処理する場合は /usr/lib/64 です。この他のディレクトリを検索する場合は、実行時リンカーの検索パスに明示的に追加する必要があります。

動的な実行可能ファイルまたは共有オブジェクトは、付加された共有オブジェクトとリンクされ、これらの共有オブジェクトは、実行時リンカーによるプロセスの実行中に再び配置される必要がある従属物として記録されます。リンク編集中には、1 つまたは複数のパス名を出力ファイル内に記録できます。これらのパス名は、実行時リンカーが共有オブジェクトの従属物を検索する場合に使用されます。この記録されたパス名は、「実行パス」と呼ばれます。

-z nodefaultlib オプションを使用してオブジェクトを作成すると、実行時に、標準的な場所 (/usr/lib あるいは /usr/lib/64) を検索しないようにできます。このオプションを使用すると、オブジェクトのすべての依存関係はその実行パスを使用して検索されます。多くの場合はこのオプションを使用せず、ユーザーが実行時リンカーのライブラリ検索パスをどのように修正しても、最後の構成要素は必ず、32 ビットオブジェクトの場合は /usr/lib、64 ビットオブジェクトの場合は /usr/lib/64 です。


注 -

-デフォルトの検索パスは、実行時構成ファイルを使用して管理できます (「デフォルトの検索パスの設定」を参照)。ただし、オブジェクト作成者はこのファイルの存在に頼らず、実行パスあるいは標準的なシステムのデフォルト設定のみを使用して、オブジェクトがその依存関係を検索できるようにしてください。


コロンで区切られたディレクトリリストを伴う、-R オプションを使用すると、動的実行可能ファイルまたは共有ライブラリ内に実行パスを記録できます。次に例を示します。


$ cc -o prog main.c -R/home/me/lib:/home/you/lib -Lpath1 ¥
-Lpath2 file1.c file2.c -lfoo -lbar

上記の例では、動的実行可能ファイル prog 内に、実行パス /home/me/lib:/home/you/lib が記録されます。実行時リンカーは、共有オブジェクトの依存関係を配置する場合に、これらのパスを使用してから、デフォルトのロケーション /usr/lib を使用します。この場合、この実行パスは、libfoo.so.1libbar.so.1 の配置に使用されます。

リンカーは、複数の -R オプションを受け取り、コロンで区切られたこれらの指定内容をそれぞれ結合します。そのため、上記の例は、次のようにも示すこともできます。


$ cc -o prog main.c -R/home/me/lib -Lpath1 -R/home/you/lib ¥
-Lpath2 file1.c file2.c -lfoo -lbar

さまざまな場所にインストールされる可能性のあるオブジェクトについては、$ORIGIN 動的ストリングトークンを使用して、柔軟に実行パスを記録できます。「関連する依存関係の配置」を参照してください。


注 -

以前は、-R オプションの指定に代わるものとして、環境変数 LD_RUN_PATH を設定してリンカーがこれを使用できるようにする方法がありました。LD_RUN_PATH および -R の適用範囲と機能は全く同じですが、この両方を指定した場合は、-R によって LD_RUN_PATH は上書きされます。