それをコンパイルしようとすると、特定のエラーが表示されます。しかし、私は正しいフラグを使用しているため、それは不可能です。 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
オブジェクトファイルとライブラリのみをリンクする場合は、オブジェクトファイルの後にライブラリをリストします。
_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
_が必要であることを認識し、共有ライブラリが実行時に確実にロードされるようにしました。
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に関する多くの質問で、この噂を裏付ける証拠を見つけることができます。
コンパイル時に-pthreadを使用します。それを試してみてください、あなたはあなたの問題を解決します