web-dev-qa-db-ja.com

「pthread_create」への未定義の参照—リンカーコマンドオプションの順序(ライブラリはオブジェクトファイルの前/後ですか?)

それをコンパイルしようとすると、特定のエラーが表示されます。しかし、私は正しいフラグを使用しているため、それは不可能です。 server.cライブラリがありますpthread.h。では、どうすればリンクの問題を解決できますか? Linux(Ubuntu)を使用しています。

make
gcc -c -Wall -Wunused -ansi -pedantic -ggdb  -o Server1.o Server.c
gcc -c -Wall -Wunused -ansi -pedantic -ggdb  Util.c
gcc -o Server1.exe -Wall -Wunused -ansi -pedantic -ggdb -lpthread -lm Server1.o Util.o
Server1.o: In function `main':
/home/ruggero/ruggero_fine/Server.c:1002: undefined reference to `pthread_create'
collect2: ld returned 1 exit status
make: *** [Server1.exe] Errore 1
13
rschirin

オブジェクトファイルの後にライブラリをリストする

オブジェクトファイルとライブラリのみをリンクする場合は、オブジェクトファイルの後にライブラリをリストします。

_gcc -o Server1.exe -Wall -Wunused -ansi -pedantic -ggdb  Server1.o Util.o -lpthread -lm
_

リンクコマンドにソースファイルが含まれている場合は、ライブラリの前にソースファイルとオブジェクトファイル(存在する場合)をリストします。したがって、_-l_オプションはコマンドラインの最後にあります。ライブラリの場所を指定する関連する_-L_オプションは、ライブラリを指定する_-l_オプションの前に置く必要があります。

副次的な質問は次のとおりです。

なぜ機能するのですか?

Cコンパイラがリンカーを呼び出すと、_crt0.o_のような名前のシステムオブジェクトファイルを取り込むようリンカーに指示し、シンボルmain(または_main()、ローカルの命名規則によって異なります)。また、コマンドラインで指定した順序でオブジェクトファイルとライブラリを提供します。オブジェクトファイルに出くわすと、リンカーはそれが提供する定義と、それが行う不満のある参照に注意します。ライブラリに出くわすと、ライブラリをスキャンして、満たされていない参照を満たすことができるかどうかを確認します。ライブラリがまだ満たされていない参照を提供できる場合は、「実行可能ファイル」にライブラリ(の関連部分)が含まれます。共有ライブラリの場合、リンカーは実行時にライブラリが確実に読み込まれるようにします。静的ライブラリの場合、リンカーは、少なくとも1つの参照を満たすライブラリからのオブジェクトファイルを含め、満たすことができる参照がなくなるまで再スキャンします。ライブラリが参照を満たさない場合は無視されます。プロセスが完了したときに、参照がまだ満たされていない場合は、エラーメッセージが表示されます。

したがって、あなたのシナリオでは、_-lpthread_または_Server1.o_の前に_Util.o_がありました。 _-lpthread_はmain関数を提供せず、それが唯一の関連する満たされていない記号だったため、無視されました。数学ライブラリ_-lm_も無視されているか、または数学ライブラリがメインCライブラリから分離されている他のシステム用に考案されたコードを保持する空のスタブである可能性があります。次に、リンカーはオブジェクトファイルを読み取り、pthread_create()への参照を見つけました。その後、Cライブラリ_-lc_(_libc.so_)をスキャンしたときに、_pthread_create_以外のすべてを満たすシンボルが見つかりました。

ライブラリがオブジェクトファイルの後にリストされている場合、リンカは_pthread_create_をスキャンしたときに_-lpthread_が必要であることを認識し、共有ライブラリが実行時に確実にロードされるようにしました。

GNU ldおよび_--as-needed_オプション

上記の議論は本質的にプラットフォームに中立です。 「オブジェクトファイル後のライブラリ」ルールに従うと、リンカー行がすべてのプラットフォームで正しく動作する可能性が最大になります。

GNU binutilsパッケージを使用しているシステム、特にGNU ldコマンドを使用している場合、別の行動を見つける。

Sourceware のマニュアル(--- http://www.gnu.org/software/binutils/manuals を試行するとリダイレクトされる場所)には、次の情報が含まれています。

_--as-needed_
_--no-as-needed_
このオプションは、コマンドラインで_--as-needed_オプションの後に記述されている動的ライブラリのELF DT_NEEDEDタグに影響します。通常、リンカーは、ライブラリが実際に必要かどうかに関係なく、コマンドラインで指定された各ダイナミックライブラリに対してDT_NEEDEDタグを追加します。 _--as-needed_は、リンクのその時点で、通常のオブジェクトファイルからの弱くない未定義のシンボル参照を満たすライブラリに対してのみ、またはライブラリが他のDT_NEEDEDリストに見つからない場合に、DT_NEEDEDタグが発行されるようにしますライブラリ、別の動的ライブラリからの弱くない未定義のシンボル参照。問題のライブラリの後にコマンドラインに表示されるオブジェクトファイルまたはライブラリは、ライブラリが必要に応じて表示されるかどうかには影響しません。これは、アーカイブからオブジェクトファイルを抽出するためのルールに似ています。 _--no-as-needed_はデフォルトの動作を復元します。

異なるシステムの異なるバージョンが_as-needed_オプションに異なる値を使用しているようです。 _--no-as-needed_の動作は、ライブラリとオブジェクトファイルをコマンドラインでほぼ任意の順序で並べ替えることができるという点で便利ですが、コマンドラインにリストされているすべてのライブラリが実行時にロードされることも意味します。ライブラリから実際に使用されているシンボルがない場合(したがって、_--no-as-needed_は架空の_--whether-needed-or-not_フラグと同等です)。 _--as-needed_オプションの使用は、古典的で移植可能な動作です。

一部のLinuxディストリビューションでは、システムのデフォルトの動作を_--no-as-needed_から_--as-needed_に過去5年ほどの間に変更したとの噂があります(3千年紀の20年の前半、引数)。 SOに関する多くの質問で、この噂を裏付ける証拠を見つけることができます。

33

コンパイル時に-pthreadを使用します。それを試してみてください、あなたはあなたの問題を解決します

3
Samblg