共有ライブラリ管理

May 09, 2018

スタティックリンクとダイナミックリンク

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 リンカが共有ライブラリを検索する順序は以下。

  1. LDLIBRARYPATH
  2. /etc/ld.so.cache
  3. /lib /usr/lib

 © 2023, Dealing with Ambiguity