必要がない場合は静的ライブラリのフルパスを指定する必要はありませんが、動的ライブラリではなく静的ライブラリに対してリンクすることをリンカに通知する必要があります。
これは、への-Bstatic
引数をld
使用して実行できます。これは、gccまたはg ++を介して渡すことができます-Wl,-Bstatic
(バリアントがあります。を参照してくださいman ld
)。
例えば:
gcc -o main main.c -Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar
とリンクmain
しますlibfoo.a
がlibbar.so
。動的は、if(GNU ldの場合)をサポートするプラットフォームのデフォルトです。そのようなものを設定などに入れる場合はpkg-config
、静的ライブラリの後でデフォルトにリセットするのが礼儀です。
質問の2番目の部分については、少なくともLinuxでは必要ない(または実際には良い習慣ではない)ため、少し不可解です。実行可能ファイルにはNEEDED
、直接依存するライブラリのエントリのみが含まれている必要があります。ランタイムリンカは、必要に応じてそれらの依存関係のロードを処理します。(これが良い習慣である理由バグを紹介します。)
たとえば、で関数を呼び出すものがあり、その関数がたまたまで関数main
を呼び出すと想像してみてください。実行可能ファイルに登録される「正しい」依存関係:libfoo.so
libbar.so
$ readelf -d libbar.so | grep Shared
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -d libfoo.so | grep Shared
0x0000000000000001 (NEEDED) Shared library: [libbar.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ readelf -d a.out | grep Shared
0x0000000000000001 (NEEDED) Shared library: [libfoo.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
ldd
(ランタイムリンカーを呼び出してその仕事をします)すべてを理解することができます:
$ ldd a.out
linux-vdso.so.1 (0x00007fff813ff000)
libfoo.so => ./libfoo.so (0x00007f48ee99d000)
libc.so.6 => /lib64/libc.so.6 (0x00007f48ee5c8000)
libbar.so => ./libbar.so (0x00007f48ee3c6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f48eeb9f000)