C/C++ プログラムをリンクする必要があるライブラリを (Linux で) 判断する方法はありますか? プログラムの開始時に未定義のシンボルが検出されない状況でも、ライブラリを見逃すことはしたくありません。また、もちろん不要な依存関係は避けたいです。
私はこの質問を一般的に定式化しましたが、ここに具体的で重要な例があります: 最近まで、 Boost.Pythonで開発された Python モジュールのlibpythonにリンクする必要があると考えていました。ただし、これは正しくありません。Boost.Python でモジュールを作成します。Boost.Python だけでなく、Python C API の関数を使用する場合もあります。libboost_pythonへのリンクで十分です。これはまったく明白ではありません — 少なくとも文書化されていませんでした.Boost.Python モジュールが libpython に対して不必要にリンクしています。また、libboost_python.so は libpython を依存関係としてリストしていないため、これを検出するのは困難です。ldd
. (このインスタンスでは、Python ライブラリが動的に読み込まれると思います。)
[後で追加:これは Boost.Python とは無関係です。また、低レベルの Python C API を使用すると、Python モジュールをコンパイルしてlibpythonにリンクしなくても動作します。ただし、以下のコメントと回答を参照してください。それにもかかわらず、 libpythonにリンクする必要があることを示しています。]
では、試行錯誤する代わりに、どうすれば不要なリンクを体系的に見つけることができたのでしょうか。この例だけでなく、一般的な適切な手順は何ですか?
[後で追加:これが私の質問へのコメントから学んだことです。この質問を投稿したとき、以下の事実は私には明確ではありませんでした。そのため、将来このディスカッションにアクセスする人のために、これらのことが有益なコメント投稿者にとって明らかであっても、今それらを詳しく説明します. (ありがとう!)
シンボルの解決は、Linux では推移的な方法で機能します (ユーザー MvG と millimoose が指摘したように)。プログラムAがlibBとlibCからシンボルを解決する必要があるとします。さらに、Aが libB に対してリンクされ、libBがlibCに対してリンクされているとします。これで、 libCを直接参照しなくても、Aをロードして実行できます。
ただし、コメンテーターが指摘したように、この推移性に依存するのは悪い習慣です。C/C++ で書かれた Python モジュールの場合、これはlibpythonに対してリンクする必要があることを意味します。一般的な場合、目標は、リンクと実行に必要なライブラリの最小限のリストを特定することではなく(元の質問がどういうわけかほのめかしたように)、実際にはリンカに必要なライブラリを提供して、すべてのシンボルを直接解決できるようにすることです。
Salgar の回答を要約すると、この情報は通常、使用されているライブラリのドキュメントからのみ取得できます。さらに、GCC リンカー フラグ-Wl,--as-needed
は、本当に不要なライブラリを識別するのに役立ちます。]