7

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がlibBlibCからシンボルを解決する必要があるとします。さらに、Aが libB に対してリンクされ、libBlibCに対してリンクされているとします。これで、 libCを直接参照しなくても、Aをロードして実行できます

ただし、コメンテーターが指摘したように、この推移性に依存するのは悪い習慣です。C/C++ で書かれた Python モジュールの場合、これはlibpythonに対してリンクする必要があることを意味します。一般的な場合、目標は、リンクと実行に必要なライブラリの最小限のリストを特定することではなく(元の質問がどういうわけかほのめかしたように)、実際にはリンカに必要なライブラリを提供して、すべてのシンボルを直接解決できるようにすることです。

Salgar の回答を要約すると、この情報は通常、使用されているライブラリのドキュメントからのみ取得できます。さらに、GCC リンカー フラグ-Wl,--as-neededは、本当に不要なライブラリを識別するのに役立ちます。]

4

3 に答える 3

5

どのヘッダーを含めるかを魔法のように知る方法がないように、どのライブラリを含めるかを魔法のように知る方法はありません。

10 の異なるライブラリが存在する可能性があり、それらはすべて同じ名前の関数を持ち、すべてがまったく異なることを行います。どちらを使用するかはあなた次第です。

一般的にはそうではありませんが、デモンストレーションのポイントにはなります。

通常、boost ライブラリまたは他の同様のライブラリを使用している場合、それらのドキュメントには、リンクする必要があるライブラリが記載されています。

上記の誰かが上で述べたように、必要に応じて --as-needed フラグを過剰に含めて使用することができますが、多くの人が問題を抱えています。通常、ライブラリに対してリンクすると、起動時にそのライブラリからすべてのグローバル変数が取り込まれます。初期化されます。これらのグローバル変数が必要かどうかは、リンカーにとって混乱を招く可能性があります。

要するに、答えは一般的にドキュメントを読むことです。または、コードをコンパイルして、発生するリンカー エラーを確認し、そこから作業して、必要なライブラリを特定します。

于 2013-04-04T11:07:37.757 に答える