69,577 views
この記事は最終更新から 1034日 が経過しています。
1. やりたいこと
ldconfig コマンドを実際に使って体感したい。
プログラム実行時、OSは動的にリンクする共有ライブラリ(.soファイル)を探す。
「どこを探すか?」
の情報を .conf ファイルに記述しておき、これを OSの動作に反映してくれるのが ldconfig コマンドだ。
2. 仕組み
ちなみにOSは以下の順序でロードする共有ライブラリを探す。
(1) 環境変数で指定されたパス
LD_LIBRARY_PATH
LD_LIBRARY_PATH_64
(2) /etc/ld.so.conf に記述されたパス
(3) 通常ライブラリが置かれるパス
/lib (/usr/lib への symbolic link)
/lib64 (/usr/lib64 への symbolic link)
ldconfigコマンドは、上記(2) の情報をOSに伝えるためのコマンドだ。
CentOS6, CentOS7 の場合、/etc ディレクトリに ld.so.conf ファイルが存在する。
[user@]$ ls -l /etc/ld.so.conf -rw-r--r--. 1 root root 28 5月 5 04:22 2010 /etc/ld.so.conf [user@]$
このファイルの中身を見ると、更に下位の ld.so.conf.d ディレクトリにある *.conf を読み込んでいる。
[user@]$ cat /etc/ld.so.conf include ld.so.conf.d/*.conf [user@]$
なので、ライブラリ検索パスを追加したい場合、/etc/ld.so.conf.d ディレクトリ配下に拡張子が「.conf」のファイルを作成し、そのファイルの中にライブラリ検索パスを記述してやればよい。
ここでは 、/etc/ld.so.conf.d/my.conf を作成し、/home/user/mylib へのライブラリ検索パスを追加した。
[user@]$ cd /etc/ld.so.conf.d/ [user@]$ su パスワード: [root@]# echo /home/user/mylib >> my.conf
設定を有効にするためには ldconfig コマンドを実行する必要がある。
[user@]$ su パスワード: [root@]# ldconfig
追加登録したディレクトリが、ライブラリ検索パスとして正しく検出されるようになったかを確認する。
[user@]$ ldconfig -p
3. 簡単な実験で体感してみる
1) 共有ライブラリを作成
Helloと表示するだけの関数 say_hello() のみを実装した共有ライブラリ libmytest.so を作成する。
test.c
#include <stdio.h> void say_hello(void){ printf("Hello!\n"); }
コンパイル&リンクを実行し、共有ライブラリ libmytest.so を作成する。
gcc -shared -fPIC -o libmytest.so test.c
2) 共有ライブラリを使うEXEを作成
main.c
#include <stdio.h> extern void say_hello(void); int main(void){ say_hello(); return 0; }
コンパイル&リンクを実行し、実行体 myexe を作成する。
gcc -L./ -o myexe main.c -lmytest
3) 共有ライブラリを各所に配置
本投稿の最初に記した三つの方法でライブラリが検出されるようにしてみる。
sudo cp ./libmytest.so /lib64 cp ./libmytest.so ~/mylib export LD_LIBRARY_PATH=./
先に作成した実行体 test を実行すると、確かに共有ライブラリの関数を実行できている。
[user]$ ./test Hello!
4) 実験:どれがリンクされるか?
まずはこの状態で実行体 test にどこの共有ライブラリがリンクされたのか?
[user@]$ ldd test
linux-vdso.so.1 => (0x00007fff3f5ca000)
libmytest.so => ./libmytest.so (0x00007ff9997c3000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff9993e4000)
/lib64/ld-linux-x86-64.so.2 (0x000055b979479000)
LD_LIBRARY_PATH の指定が適用された。
では LD_LIBRARY_PATH の設定をクリアしてみたらどうか?
[user@]$ unset LD_LIBRARY_PATH
[user@]$ ldd test
linux-vdso.so.1 => (0x00007fff20bf8000)
libmytest.so => /home/user/mylib/libmytest.so (0x00007f84ec54b000)
libc.so.6 => /lib64/libc.so.6 (0x00007f84ec188000)
/lib64/ld-linux-x86-64.so.2 (0x00005591ed411000)
今度は /etc/ld.so.conf の設定が適用された。
では /etc/ld.so.conf の設定を解除してみたらどうか?
[user@]$ sudo rm /etc/ld.so.conf.d/my.conf
[user@]$ sudo ldconfig
[user@]$ ldd test
linux-vdso.so.1 => (0x00007fffba988000)
libmytest.so => /lib64/libmytest.so (0x00007ff00be4b000)
libc.so.6 => /lib64/libc.so.6 (0x00007ff00ba88000)
/lib64/ld-linux-x86-64.so.2 (0x0000564fcc6cd000)
今度は /lib64 に置かれたものが採用された。