これは少し興味深いトピックなので、説明してみます。したがって、この例では、小さなライブラリjanssonをテスト用にインストールします。非標準のディレクトリにインストールするように構成します。
./configure --prefix=/home/ubuntu/mystuff
これを実行すると、次のmake install
警告が表示されます。
Libraries have been installed in:
/home/ubuntu/mystuff/lib
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
では、テスト スイート プログラムの 1 つを使用してリンクを試みます。
$ gcc test_dump.c -ljansson
test_dump.c:8:21: fatal error: jansson.h: No such file or directory
C が何を使用できるかを知るためには、まずインクルード ファイルについて知る必要があります。幸いなことに、これはコンパイル時にのみ行う必要があります。インクルード ファイルの場所を知っている-I
ので、インクルード ディレクトリを渡します。gcc
$ gcc test_dump.c -I/home/ubuntu/mystuff/include -ljansson
/usr/bin/ld: cannot find -ljansson
さて、リンクの問題に戻ります。LD_LIBRARY_PATH
それでは、リンクしながら試してみましょう:
$ LD_LIBRARY_PATH="/home/ubuntu/mystuff/lib" gcc test_dump.c -I/home/ubuntu/mystuff/include -ljansson
/usr/bin/ld: cannot find -ljansson
これは機能しません。これの背後にある理由は、次のコマンドを実行すると表示されるように、gcc が別のディレクトリを検索しているためです。
gcc -print-search-dirs
必要なディレクトリで動作するようにgccに指示するには、-L
次を使用します。
$ gcc test_dump.c -I/home/ubuntu/mystuff/include -L/home/ubuntu/mystuff/lib -ljansson
$
これで、と呼ばれるプログラムを使用して、ldd
リンク対象を確認できます。
$ ldd a.out
linux-vdso.so.1 => (0x00007fc4c872d000)
libjansson.so.4 => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc4c8366000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc4c872e000)
必要なライブラリが「見つかりません」と表示されていることに気付くでしょう。今、その問題を試してみてください:
$ LD_RUN_PATH="/home/ubuntu/mystuff/lib" gcc test_dump.c -I/home/ubuntu/mystuff/include -L/home/ubuntu/mystuff/lib -ljansson
これは を使用する 1 つの方法LD_RUN_PATH
です。ライブラリだけにリンクするのではなく、ライブラリへのフル パスにリンクします。もう一度実行ldd
すると、次のようになります。
$ ldd a.out
linux-vdso.so.1 => (0x00007fff481d7000)
libjansson.so.4 => /home/ubuntu/mystuff/lib/libjansson.so.4 (0x00007fe86b0dd000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe86ad18000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe86b2eb000)
これを関与せずに試してみると、次のLD_RUN_PATH
ようになります。
$ ./a.out
./a.out: error while loading shared libraries: libjansson.so.4: cannot open shared object file: No such file or directory
これを解決するにLD_LIBRARY_PATH
は、次を使用します。
$ LD_LIBRARY_PATH="/home/ubuntu/mystuff/lib" ./a.out
$
ただし、これはちょっとしたハックであり、眉をひそめています。David Barr は、この問題について素晴らしい記事を書いています。何が起こっているかというとld.so/ld-linux.so
、「プログラムに必要な共有ライブラリをロードし、実行するプログラムを準備してから実行する」動的ライブラリ ローダーがあるということです。ld.so
マンページを見ると、次のように記載されています。
The necessary shared libraries needed by the program are searched for in the following order
o Using the environment variable LD_LIBRARY_PATH (LD_AOUT_LIBRARY_PATH for a.out programs). Except if the executable is a setuid/setgid binary, in which case it is ignored.
o From the cache file /etc/ld.so.cache which contains a compiled list of candidate libraries previously found in the augmented library path. Libraries installed in hardware capabilities
directories (see below) are prefered to other libraries.
o In the default path /lib, and then /usr/lib.
その/etc/ld.so.cache
パスを入れたい場所です。このキャッシュは をldconfig
使用して生成され/etc/ld.so.conf
ます。Ubuntuでそのファイルを見ると:
include /etc/ld.so.conf.d/*.conf
それが言うすべてです。/etc/ld.so.conf.d
ディレクトリには、デフォルトで、glib、gcc のディレクトリがあり、/usr/local/lib
デフォルト パスの外にあるためです。必要なディレクトリをキャッシュに追加するには、そのディレクトリにファイルを追加するだけです。
$ sudo vim /etc/ld.so.conf.d/50-jansson.conf
- add /home/ubuntu/mystuff/lib to the file -
$ sudo ldconfig
これにより/etc/ld.so.cache
、ローダー用にそのファイルが再生成されます。ldconfig
キャッシュされたディレクトリを出力することで、ディレクトリが取得されたことを確認できます。
$ ldconfig -p | grep "mystuff"
libjansson.so.4 (libc6,x86-64) => /home/ubuntu/mystuff/lib/libjansson.so.4
libjansson.so (libc6,x86-64) => /home/ubuntu/mystuff/lib/libjansson.so
ここで、ldd
もう一度実行を試みると、次のようになります。
$ ldd a.out
linux-vdso.so.1 => (0x00007fff1e510000)
libjansson.so.4 => /home/ubuntu/mystuff/lib/libjansson.so.4 (0x00007f529da67000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f529d6a8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f529dc7b000)
最後にプログラムを実行します。
$ ./a.out
$
それはすべて動作します!これは、リンクを行っているときにバックエンドで何が起こっているかを調べたものです。詳細については、 および を参照することをお勧めしman ld.so
ますman ldconfig
。説明が必要な場合は、遠慮なくお尋ねください。