これは奇妙なことです。libmへの参照を削除することで、以下のエラーを取得できたからです。
gcc -o example example.o -Wl -L/home/kensey/cdev/lib -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -L/usr/lib/x86_64-linux-gnu -lm -lrt -ldl -lcdev -L/home/kensey/www.tools/gplot-lib -lgplot -L/home/kensey/www.tools/Gd1_3ret -lgd -lxml2 -lcurl
/usr/bin/ld: /home/kensey/www.tools/gplot-lib/libgplot.a(set.o): undefined reference to symbol 'floor@@GLIBC_2.2.5'
/usr/bin/ld: note: 'floor@@GLIBC_2.2.5' is defined in DSO /usr/lib/x86_64-linux-gnu/libm.so so try adding it to the linker command line
/usr/lib/x86_64-linux-gnu/libm.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
したがって、コマンドの-lm
部分を削除しても、エラーは発生しません。ただし、必要なライブラリへの参照を削除するとこれが修正される理由について誰かが知っているのだろうか。リンカはどのライブラリを調べるべきかをどのようにして知るのですか?また、ビルドされた実行可能ファイルを照会し、「どのライブラリを「フロア」への参照を解決しましたか」と言う方法はありますか?明らかに、私が理解していないこと、そして私を悩ます何かが起こっています...
何が起こっているのかの説明は非常に簡単です。
libgplot.a
はlibm.so
に依存していますが、リンク行の-lm
と-lgplot
の順序が間違っています。リンク行のライブラリの順序doesmatter 。一般に、システムライブラリ(-lpthread
、-lm
、-lrt
、-ldl
)はfollowである必要がありますリンク行のその他すべて。
リンク行から-lm
を削除しても、libm.so.6
は、リンク行に後で表示される他のライブラリによってリンクに引き込まれます(libgd
、libxml2
またはlibcurl
)そのライブラリはlibm.so.6
に依存しているため。しかし、今ではlibm.so.6
はリンク行の正しい場所にあるため、すべてが機能します。
リンクコマンドの最後に-lmを付けて、最後のライブラリとしてリストすると、エラーは発生しません。
上記の説明を確認します。
export LDFLAGS="$LDFLAGS -lm"
で同じ問題を解決しました
おそらく、ライブラリ検索パス(/ usr/local/lib /または/ usr/lib /など)に64ビットlibmが含まれていないため、l
フラグで指定した場合、gccはそれを見つけることができません。ディレクトリのみを指定すると、正しいディレクトリを見つけることができるように見えます。だからあなたは試すことができます:
LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
そして、-lm
わかりにくい。コマンドラインにカスタムライブラリディレクトリがあるため、-lm
が互換性のない代替バージョンにリンクしていると考えられます。 -lm
がなければ、リンクするライブラリの1つで必要になるため、リンカーは別のバージョンを取り込むことができます。
strace
の両方の呼び出しを確認し、両方のケースでlibm.so
がどこから来ているかを確認します。
ところで、-Wl
スイッチは何もしないようで、-L/usr/lib/x86_64-linux-gnu
が2回言及されています。
回答のリストに追加するだけで、 http://fedoraproject.org/wiki/UnderstandingDSOLinkChange これは有益です。上記の質問には関係ありませんが、説明はエラーメッセージ/usr/bin/ld: note: 'some_reference' is defined in DSO some.so so try adding it to the linker command line
1つの説明couldは次のとおりです。
Libmの外部で定義された弱リンク関数foo
が、libmの内部で定義されたfoo
の強リンクバージョンに置き換えられている可能性があります。未定義関数を呼び出すのはこの強リンクバージョンです。
これは、ライブラリを追加すると未定義関数エラーが発生する原因を説明します。
同様の問題が発生しました。 gccの過去には、ライブラリの順序は重要ではありませんでした(少なくとも私が作業した場合は関係ありません)。 こちらの質問 誰かが、動作が4.4と4.5の間で変更されたように見えることに気付きました。
私の場合、次のリンクを実行してエラーメッセージを削除しました。
g++ -Wl,--copy-dt-needed-entries [options] [libraries] [object files] -o executable-file