共有ライブラリとは:静的リンクとの違い

ライブラリとは、複数のプログラムから共通して呼び出される、汎用的な処理をまとめたコード集です。ライブラリをプログラムに組み込む方法には、大きく分けて2種類があります。

方式説明
静的リンク(static linking)プログラムのビルド時にライブラリのコードを実行ファイルの中に埋め込む方式。実行ファイル単体で動作するが、サイズが大きくなり、ライブラリの更新に個別の再ビルドが必要になる
動的リンク(dynamic linking)実行ファイルにはライブラリの参照情報だけを持たせ、プログラムの実行時にライブラリを読み込む方式。複数のプログラムで同じライブラリファイルを共有でき、ライブラリの更新(セキュリティ修正等)が各プログラムの再ビルド無しに反映される

Linuxで一般的に使われるのは共有ライブラリ(shared library、動的リンクの対象となるライブラリ)で、多くはlibfoo.so.1のように.soに続けてバージョン番号を持つファイル名です。

システムライブラリの典型的な配置場所

共有ライブラリは、慣習的に次のようなディレクトリに配置されます。

ディレクトリ役割
/lib(/lib64)システムの起動やコマンド実行に必要な基本的な共有ライブラリ
/usr/lib(/usr/lib64)一般的なアプリケーション向けの共有ライブラリ
/usr/local/lib管理者が個別にインストールしたソフトウェア向けの共有ライブラリ

多くの現代的なディストリビューションでは、/libは/usr/libへのシンボリックリンクとして統合されています。

ldd:プログラムが依存する共有ライブラリを調べる

lddは、指定した実行ファイルが実行時にどの共有ライブラリに依存しているかを一覧表示するコマンドです。

ldd /bin/ls

実行すると、依存するライブラリ名と、実際に解決されたファイルパスが表示されます。

lddを信頼できない実行ファイルに対して使ってはいけません。 lddの実装によっては、対象のプログラムを実際に実行して依存関係を調べることがあるため、悪意のある実行ファイルに対して使うと、任意のコードが実行されてしまう危険があります出典:man7.org「ldd(1)」。信頼できない実行ファイルの依存関係を確認したい場合は、objdump -p(直接の依存関係のみ表示、プログラムを実行しない)等の代替手段が推奨されています。[1]。

ldconfigとキャッシュ:共有ライブラリを高速に見つける仕組み

プログラムを実行するたびに、ディスク上のライブラリを毎回探し回るのは非効率です。そこでLinuxでは、共有ライブラリのキャッシュ(/etc/ld.so.cache)をあらかじめ作成しておき、動的リンカがこのキャッシュを参照することで高速にライブラリを見つけられるようにしています。

/etc/ld.so.conf:キャッシュ対象のディレクトリを指定する

/etc/ld.so.confは、キャッシュに含めるべき共有ライブラリの検索対象ディレクトリを、1行に1つずつ列挙する設定ファイルです(多くのディストリビューションでは、個別の設定を/etc/ld.so.conf.d/以下の複数のファイルに分割し、/etc/ld.so.conf側でincludeする構成が使われます)。

ldconfig:キャッシュを再構築する

ldconfigは、/etc/ld.so.conf(および標準的なディレクトリである/lib・/usr/lib)を走査し、見つかった共有ライブラリの情報を/etc/ld.so.cacheに書き込むコマンドです。

オプション効果
(オプション無し)設定ファイルに基づいてキャッシュを再構築する
-p現在のキャッシュの内容(ディレクトリとライブラリの一覧)を表示する
-v詳細モードで、スキャンしたディレクトリや作成したリンクの情報を表示しながら実行する
ldconfig             # /etc/ld.so.confの内容に基づいてキャッシュを再構築する
ldconfig -p           # 現在のキャッシュの内容を表示する

新しい共有ライブラリを、/etc/ld.so.confに列挙されているディレクトリ以外の場所にインストールした場合は、そのディレクトリを/etc/ld.so.confまたは/etc/ld.so.conf.d/以下の設定ファイルに追加してから、ldconfigを実行してキャッシュを更新します。追加せずにldconfigを実行しても、そのライブラリはキャッシュに登録されず、動的リンカが見つけられないことがあります。

LD_LIBRARY_PATH:一時的にライブラリの検索先を追加する

LD_LIBRARY_PATH環境変数を設定すると、動的リンカがライブラリを検索する際に、通常は標準の場所(/etc/ld.so.cacheや/lib・/usr/lib)よりも優先して検索するディレクトリを、一時的に追加指定できます。ただし、実行ファイルのRPATHなどの設定によっては検索順が異なる場合があります。

LD_LIBRARY_PATH=/opt/myapp/lib ./myapp    # myappの実行時だけ、/opt/myapp/libを優先的に検索させる

LD_LIBRARY_PATHはシステム全体の設定を変更するものではなく、それを設定したシェル・プロセスの実行時だけに影響する一時的な指定であるという点が、恒久的な設定である/etc/ld.so.conf(+ldconfig)との違いです。動作確認用に別バージョンのライブラリを試す場合等によく使われますが、システム全体で恒久的にライブラリの検索先を追加したい場合は/etc/ld.so.confを編集してldconfigを実行する方法が適切です。


補足

  1. 出典:man7.org「ldd(1)」。信頼できない実行ファイルの依存関係を確認したい場合は、objdump -p(直接の依存関係のみ表示、プログラムを実行しない)等の代替手段が推奨されています。 ↩