スタティックリンクとダイナミックリンク
C 言語等では、演算や制御などの基本的な機能以外について、プログラム本体からライブラリの機能 (関数) を利用するが、これをリンクと言う。
スタテッィックリンクは、コンパイル時点で、コンパイラがライブラリを実行ファイル内に埋め込む方式であるば、実行ファイル内にライブラリの機能が埋め込まれるため、よく使用されるライブラリの機能が、様々な実行ファイルに重複して入ることになる。
一方、実行ファイルへライブラリを埋め込むことはせず、実行時にライブラリをの機能を呼び出す方法がダイナミックリンクと呼ばれる。
ダイナミックリンクによって呼び出されるライブラリのことを共有ライブラリと呼び、共有ライブラリは libreadline.so.5 のように、“lib ~ .so ~” という名前がつけられている。
共有ライブラリファイルは通常 /lib (/lib64) もしくは /usr/lib 以下に配置されている。
$ ls -l /lib64/lib* | head
lrwxrwxrwx. 1 root root 15 Mar 23 17:41 /lib64/libacl.so.1 -> libacl.so.1.1.0
-rwxr-xr-x. 1 root root 37056 Sep 21 2017 /lib64/libacl.so.1.1.0
-rwxr-xr-x. 1 root root 19840 Feb 5 15:39 /lib64/libanl-2.17.so
lrwxrwxrwx. 1 root root 14 Mar 23 17:41 /lib64/libanl.so.1 -> libanl-2.17.so
lrwxrwxrwx. 1 root root 14 Mar 23 17:41 /lib64/libapol.so.4 -> libapol.so.4.4
-rwxr-xr-x. 1 root root 232872 Oct 19 2017 /lib64/libapol.so.4.4
-rwxr-xr-x. 1 root root 32904 Dec 20 23:13 /lib64/libasm-0.170.so
lrwxrwxrwx. 1 root root 15 Mar 23 17:42 /lib64/libasm.so.1 -> libasm-0.170.so
lrwxrwxrwx. 1 root root 18 May 9 01:45 /lib64/libasound.so.2 -> libasound.so.2.0.0
-rwxr-xr-x. 1 root root 1058424 Oct 22 2017 /lib64/libasound.so.2.0.0
必要な共有ライブラリの確認
実行ファイルが必要としている共有ライブラリは ldd コマンドで調べることができる。
以下の例では sleep コマンドが必要な共有ライブラリを表示している。
$ ldd /bin/sleep
linux-vdso.so.1 => (0x00007ffce3b64000)
libc.so.6 => /lib64/libc.so.6 (0x00007f96d6458000)
/lib64/ld-linux-x86-64.so.2 (0x00007f96d6825000)
プログラム実行時には ld.so リンカ及びローダが実行時にリンクする共有ライブラリを検索し、必要なライブラリをロードする。
/lib や /usr/lib いk街のライブラリも検索する場合は、そのリストを /etc/ld.so.conf に記述する。
$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
$ ls /etc/ld.so.conf.d/
kernel-3.10.0-862.el7.x86_64.conf mariadb-x86_64.conf
$ cat /etc/ld.so.conf.d/*
# Placeholder file, no vDSO hwcap entries used in this kernel.
/usr/lib64/mysql
プログラムを実行するたびにこれらのディレクトリを検索するのは非効率であるため、実際はバイナリのキャッシュファイルである /etc/ld.so.cache が参照される。ldconfig コマンドは /etc/ld.so.conf ファイルに基づいて、/etc/ld.so.cache を再構築する。
共有ライブラリを変更した場合は ldconfig コマンドを実行してキャッシュを更新する必要がある。
$ sudo ldconfig
その他のディレクトリも検索対象に加えたい場合は、環境変数 LDLIBRARYPATH にディレクトリリストを記述する。
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library
ld.so リンカが共有ライブラリを検索する順序は以下。
- LDLIBRARYPATH
- /etc/ld.so.cache
- /lib /usr/lib