web-dev-qa-db-ja.com

libpthread.so.0:シンボル追加時のエラー:DSOがコマンドラインにありません

Openvswitch-1.5.0をコンパイルしているときに、次のようなコンパイルエラーが発生しました。

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith
     -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init  -g -O2 -export-dynamic ***-lpthread***  -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
 /home/jyyoo/src/dpdk/build/lib/librte_eal.a
 /home/jyyoo/src/dpdk/build/lib/libethdev.a
 /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a
 /home/jyyoo/src/dpdk/build/lib/librte_hash.a
 /home/jyyoo/src/dpdk/build/lib/librte_lpm.a
 /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a
 /home/jyyoo/src/dpdk/build/lib/librte_ring.a
 /home/jyyoo/src/dpdk/build/lib/librte_mempool.a
 /home/jyyoo/src/dpdk/build/lib/librte_malloc.a -lrt -lm 
     /usr/bin/ld: /home/jyyoo/src/dpdk/build/lib/librte_eal.a(eal.o): undefined reference
     to symbol 'pthread_create@@GLIBC_2.2.5'
     /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from 
     command line

私がlibpthreadのシンボルを見ようとすれば、それはうまく見えます。

$ readelf -s /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
   199: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2.5
   173: 0000000000008220  2814 FUNC    LOCAL  DEFAULT   13 __pthread_create_2_1
   462: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2

ヒントや指示を教えてください。

173
jaeyong

あなたは、コマンドラインafterでコンパイルされるオブジェクトファイルにライブラリを言及するべきです:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init \
     -g -O2 -export-dynamic -o utilities/ovs-dpctl utilities/ovs-dpctl.o \
     lib/libopenvswitch.a \
     /home/jyyoo/src/dpdk/build/lib/librte_eal.a /home/jyyoo/src/dpdk/build/lib/libethdev.a /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a /home/jyyoo/src/dpdk/build/lib/librte_hash.a /home/jyyoo/src/dpdk/build/lib/librte_lpm.a /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a /home/jyyoo/src/dpdk/build/lib/librte_ring.a /home/jyyoo/src/dpdk/build/lib/librte_mempool.a /home/jyyoo/src/dpdk/build/lib/librte_malloc.a \
     -lrt -lm -lpthread 

説明:リンクはモジュールの順序に依存しています。最初にシンボルが要求され、次にそれらを持つライブラリからリンクされます。そのため、最初にライブラリを使用するモジュールを指定し、その後にライブラリを指定する必要があります。このような:

gcc x.o y.o z.o -la -lb -lc

さらに、循環的な依存関係がある場合は、コマンドラインで同じライブラリを複数回指定する必要があります。 libblibcからのシンボルを必要とし、libclibbからのシンボルを必要とする場合、コマンドラインは次のようになります。

gcc x.o y.o z.o -la -lb -lc -lb
131
Michael Pankov

エラーメッセージはディストリビューション/コンパイラのバージョンによって異なります。

Ubuntu Saucy:

/usr/bin/ld: /mnt/root/ffmpeg-2.1.1//libavformat/libavformat.a(http.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line

Ubuntu Raring :(より有益)

/usr/bin/ld: note: 'uncompress' is defined in DSO /lib/x86_64-linux-gnu/libz.so.1 so try adding it to the linker command line

解決策: リンク段階で、コンパイルステップでライブラリが見つからない可能性があります。私の場合は、makefile/GCCフラグに '-lz'を追加しました。

背景: DSOは動的共有オブジェクトまたは共有ライブラリです。

44
kevinf

私は別の事件を見つけたので、私はあなたがすべて間違っていると思います。

これは私が持っていたものです:

/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: eggtrayicon.o: undefined reference to symbol 'XFlush'
/usr/lib64/libX11.so.6: error adding symbols: DSO missing from command line

問題は、コマンドラインDIDに-lX11が含まれていないことです。ただし、引数にGTKおよびGNOMEライブラリも含まれていたため、libX11.soを依存関係として追加する必要があります。

それで、私にとっての唯一の説明は、このメッセージがhelp youを意図していたかもしれないということですが、それは正しくしませんでした。これはおそらく簡単でした。シンボルを提供するライブラリがコマンドラインに追加されていません。

POSIXのリンケージに関する3つの重要な規則に注意してください。

  • 動的ライブラリには依存関係が定義されているので、依存関係の上位からのライブラリだけがどんな順序で提供されるべきです(静的ライブラリの後ですが)。
  • 静的ライブラリには未定義のシンボルしかありません - それらの依存関係を知り、それらすべてをコマンドラインで指定するのはあなた次第です。
  • static ライブラリ内の順序は常に要求者が最初プロバイダが従うです。それ以外の場合は、ライブラリをコマンドラインに追加するのを忘れたときのように、未定義のシンボルメッセージが表示されます。
  • ライブラリを-l<name>で指定すると、それがlib<name>.solib<name>.aのどちらをとるのかわかりません。動的ライブラリが見つかった場合はそれが優先され、静的ライブラリはコンパイラオプションでしか適用できません - それがすべてです。上記のように問題があるかどうかは、静的ライブラリか動的ライブラリかによって異なります。
  • 動的ライブラリでは、依存関係が欠如していることがあります。D
14
Ethouris

私は私が同じエラーをしていたことがわかりました。私はlapackとblasの両方でコードをコンパイルしていました。 2つのライブラリを呼び出す順番を入れ替えると、エラーがなくなりました。

"LAPACK_LIB = -llapack-lblas"は、 "LAPACK_LIB = -lblas -llapack"が上記のエラーを表示するのに対して機能しました。

6
user3112632

私も同じ問題に遭遇しました。私はなぜかわからない、私はちょうどコンパイラに-lpthreadオプションを追加し、すべて大丈夫です。

古い:

$ g++ -rdynamic -m64 -fPIE -pie  -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt

以下のエラーが発生しました。上記のコマンドに-lpthreadオプションを追加すればOKです。

/usr/bin/ld: /tmp/node/out/Release/obj.Host/v8_libbase/deps/v8/src/base/platform/condition-variable.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
4
osexp2003

追加してください:CFLAGS="-lrt"LDFLAGS="-lrt"

2
劉大為

私が発見したのは、リンカが文句を言うライブラリが、問題を起こしているライブラリではないということです。問題がどこにあるかを突き止める賢い方法があるかもしれませんが、これは私がすることです:

  • Linkコマンドですべてのリンクライブラリをコメントアウトします。
  • すべての.o、.soなどを消去します(通常はmake cleanで十分ですが、再帰的なfind + rmなどを実行することをお勧めします)。
  • Linkコマンドのライブラリを1つずつコメント解除し、必要に応じて順番を並べ替えます。

@peter karasev:私はCentOS7でのgcc 4.8.2 cmakeプロジェクトで同じ問題に出会いました。 target_link_librariesセクションのライブラリの順序は重要です。私はcmakeがそのままリストをそのままリンカに渡すと思います、すなわちそれは正しい順序を試みませんし、うまくいきません。これは理にかなっています - あなたがそれについて考えるとき、リンクが正常に完了するまでcmakeは正しい順序が何であるかを知ることができません。

2
AhrB

バックグラウンド

DSO missing from command lineメッセージは、リンカが通常の検索で必要なシンボルを見つけられなかったが、そのシンボルが直接指定された動的ライブラリの依存関係の1つで利用可能である場合に表示されます。

過去には、リンカは指定された言語の依存関係にあるシンボルが利用可能であると考えていました。しかし、それは将来のバージョンで変更され、リンカは利用可能なものについてより厳密な見方を強制します。したがって、メッセージはその移行を支援することを目的としています。

何をすべきか?

あなたがソフトウェアのメンテナである場合

必要なシンボルを満たすために必要なすべてのライブラリがリンカコマンドラインで直接指定されていることを確認することで、この問題を解決する必要があります。順序がしばしば重要であることにも留意してください。

ソフトウェアをコンパイルしようとしているだけの場合

回避策として、オプション-Wl,--copy-dt-needed-entriesを使用することによって、どのシンボルが利用可能であるかのより寛容なビューに戻ることが可能です。

これをビルドにインジェクトする一般的な方法は、configureを実行する前にLDFLAGSをエクスポートすることです。

export LDFLAGS="-Wl,--copy-dt-needed-entries"

LDFLAGS="-Wl,--copy-dt-needed-entries"を直接makeに渡すこともうまくいくかもしれません。

1
textshell

distccを使用してc ++プロジェクトを作成したときにも、同じ問題が起こりました。最後に私はexport CXX="distcc g++"でそれを解決しました。

1
Jason Geng

g++を使用している場合は、代わりにgccを実行していないことを確認してください。

0
Martin R.

HPCCベンチマーク(HPLと他​​のいくつかのベンチマークを含む)をインストールしていたときにも同じことが起こりました。ビルドスクリプトのコンパイラフラグに-lmを追加すると、正常にコンパイルされました。

0
Jon Doh