0

私は現在、多くのライブラリが含まれているより大きなプロジェクトに取り組んでいます。Linuxでのgccがそのように動作する理由についていくつか質問があります。

まず、ご存知かもしれませんが、gcc / g ++への「-lxyz」リンカーフラグを使用して、一部のシステムパスでlibxyz.soを検索し、それにリンクすることができます。ただし、これは静的ライブラリの場合には機能しません。つまり、libxyz.aに対してリンクする場合は、オブジェクトファイルとして/usr/lib/libxyz.aを明示的に追加する必要があります。

私の問題は次のとおりです。プロジェクトにpkg-configスタイルの.pcファイルを含めたい場合、ユーザーが静的ライブラリを構築することを選択した場合、何を入れる必要がありますか?

また、gcc /g++がライブラリの依存関係を期待どおりに処理しないのはかなり面倒です。

プログラムをlibabc.soにリンクし、lddがlibabc.soがlibxyz.soに依存していると言った場合、gcc /g++はlibxyz.soにもリンクできるほど賢いはずだと思います。悲しいことに、これはそうではないようです。これが機能しない正当な理由はありますか、またはgcc / g ++にこれらの依存関係を考慮するように強制する可能性はありますか?

4

1 に答える 1

1

必要がない場合は静的ライブラリのフルパスを指定する必要はありませんが、動的ライブラリではなく静的ライブラリに対してリンクすることをリンカに通知する必要があります。

これは、への-Bstatic引数をld使用して実行できます。これは、gccまたはg ++を介して渡すことができます-Wl,-Bstatic(バリアントがあります。を参照してくださいman ld)。

例えば:

gcc -o main main.c -Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar

とリンクmainしますlibfoo.alibbar.so。動的は、if(GNU ldの場合)をサポートするプラットフォームのデフォルトです。そのようなものを設定などに入れる場合はpkg-config、静的ライブラリの後でデフォルトにリセットするのが礼儀です。

質問の2番目の部分については、少なくともLinuxでは必要ない(または実際には良い習慣ではない)ため、少し不可解です。実行可能ファイルにはNEEDED、直接依存するライブラリのエントリのみが含まれている必要があります。ランタイムリンカは、必要に応じてそれらの依存関係のロードを処理します。(これが良い習慣である理由バグを紹介します。)

たとえば、で関数を呼び出すものがあり、その関数がたまたまで関数mainを呼び出すと想像してみてください。実行可能ファイルに登録される「正しい」依存関係:libfoo.solibbar.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)
于 2013-01-01T16:34:14.923 に答える