2

Ubuntu 12.04でCERNのROOTを操作しているときに、この非常に厄介な問題に遭遇しましたが、より一般的な問題だと思います。

次のmakefileを使用してコンパイルおよびリンクする外部参照を含むC++コードがいくつかあります。OS X 10.8を搭載したMacとSL5を搭載したサーバーでは、これは正常に機能します。

CXX=clang++
CXXFLAGS=-Wall -O2 -g $(shell root-config --cflags --libs)

testroot: testroot.cc

に評価します

clang++ -Wall -O2 -g -pthread -m64 -I/opt/ROOT/5.34.05/include/root -L/opt/ROOT/5.34.05/lib/root -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -rdynamic    testroot.cc   -o testroot

これにより、Ubuntuサーバーで未定義の参照とリンカーエラーが発生します。私はすでにライブラリを設定しようとしましLDFLAGSたが、同じ結果が得られます。手動でコンパイルし、ソースファイルと-oオプションをライブラリの前に置くと、問題なくコンパイルされます。

他のスレッドから、コマンドの順序が重要である可能性があることを理解しましたが、なぜそれが一部のマシンで機能し、他のマシンでは機能しないのか疑問に思います。make順序が重要だったとしても、私はそれを自分で理解するのに十分賢いと思いました。

今の質問は次のとおりです。どうすればこれを回避できますか?別のバージョンのmakeまたはldを使用する必要がありますか?makefileを変更する必要がありますか?

前もって感謝します!

4

3 に答える 3

5

-lに引数を追加しLDFLAGSないでください(言及すらしませんCXXFLAGS)。リンクライブラリの適切な変数は、makefileのような暗黙のmakeルールLDLIBSの場合です。

一部のマシンでは、GNU ldでは静的ライブラリまたはオプションが有効になっている場合にのみ重要であるため、順序は重要ではありません--as-needed(一部のシステムではデフォルトで有効になっています)。

于 2013-03-22T12:16:14.503 に答える
2

のオプションを組み合わせないでくださいroot-config。そのはず:

CXXFLAGS = -Wall -O2 -g $(shell root-config --cflags)
LIBS     = $(shell root-config -libs -glibs)

次に、必要に応じてこれらのオプションを使用します。(たとえば、$(LIBS)コンパイルするだけで、リンクしない場合は使用しません。)

なぜそれが別のシステムで動作するのですか?システムが異なればリンカーも異なり、動作も異なります。あるいは、一部のシステムに追加のライブラリは必要ないかもしれません。これは間違いなく伝統に反しますが、現代のシステムでは必ずしもすべてを入れるのは不合理ではありませんlibc.so

最後にmake、これをどのように理解できるでしょうか。Makeは、実行するコマンドを文字通り何も知りません。それらは、シェルに渡される単なる文字列です。

于 2013-03-22T12:20:15.060 に答える
0

発生する問題は、ldが外部参照を解決するために使用するアルゴリズムに関連しています。別のldを試すこともできますが、ライブラリのリストを並べ替えることも同様に役立ちます。最初にベースライブラリ(依存関係のないライブラリ)を配置し、次にすでにリストされているライブラリに依存するライブラリなどを配置します。

于 2013-03-22T12:19:33.023 に答える