7

次のような簡単な C++ コードがあります。

#include <boost/timer/timer.hpp>

int main(void) {
    boost::timer::auto_cpu_timer t;
    return 0;
}

次のようにコンパイルしてリンクしようとしました(gcc 4.8.1およびGNU ld 2.23.52.20130828を使用):

$ g++ -o test test.cc -lboost_timer
/usr/bin/ld: /tmp/cc2jP1jv.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
/usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

-lboost_system1 つの解決策は、コマンド ラインで明示的に言及することです。これは機能します。ただし、次のこともできます。

$ g++ -Wl,--copy-dt-needed-entries -o test test.cc -lboost_timer

ld のドキュメントによると、「出力バイナリに必要なシンボルを解決するために、コマンド ラインで指定された --copy-dt-needed-entries 動的ライブラリは、他のライブラリへの DT_NEEDED タグに続いて再帰的に検索されます」ということで、これはすべてが理にかなっています: ld は、すべてのシンボルを解決するために、boost_system にもリンクする必要があることを boost_timer から把握しています。

ただし、これも機能することに気付きました。

$ g++ -fPIC -shared -o test test.cc -lboost_timer

明らかに、実行可能ファイルではなく共有オブジェクトを生成しました。ただし、ld は共有オブジェクトを boost_system にリンクする必要があることを認識できたようです。

$ ldd test | grep boost_system
        libboost_system.so.1.54.0 => /usr/lib/libboost_system.so.1.54.0 (0x00007f385246e000)

私の質問は次のとおりです。共有オブジェクトと実行可能ファイルをビルドするときに、シンボルの解決が異なるのはなぜですか? 指定せずに共有オブジェクトをboost_systemにリンクする必要があることをldはどのように判断でき--copy-dt-needed-entriesますか?

4

2 に答える 2

0

関連する可能性のある collect2 コマンドの相違点があります。さまざまなコマンドがhttp://imgur.com/eMr2tY2で比較されています。右側は共有ライブラリ (-fPic -shared) を作成し、左側は通常のコンパイルです。

于 2013-10-09T13:07:00.003 に答える