0

最初の例は機能しませんが、2 番目の例は機能します。これにより、リンク時にコンパイルする適切な方法は何ですか? 適切なリンクに関する詳細情報はありますか?

非稼働:gcc $(curl-config --libs --cflags) prog.c -o prog

働く:gcc prog.c $(curl-config --libs --cflags) -o prog

4

2 に答える 2

5

C コンパイラ (GCC であろうと他のコンパイラであろうと大した問題ではありません) は、複雑な生き物です。実際には、別々のプロセスを呼び出して、作業のさまざまな部分を実行します。パーサーがあり、これにはプリプロセッサー部分が含まれる場合があり (最近では通常含まれています)、通常はアセンブラーへのコード生成、アセンブラーによるオブジェクト生成、最後にプログラムのリンク (通常ldはローダーの と呼ばれるプログラムによる) があります。詳細な構成は異なる場合があります。ここでの重要な点は、ローダーが以前のフェーズで作成されたオブジェクト ファイルと、操作するように指示されたライブラリに対して動作することです。

実行可能ファイルをリンクする呼び出しを記述する場合、コードをオブジェクト ファイルにコンパイルする場合としない場合があります。あなたの例では、コンパイルprog.cしてprog.o; 多くの場合、link コマンドはオブジェクト ファイルのみをリストし、ソース ファイルはリストしません。

リンカは、C コンパイラによって追加されたオプション (場合によってはオブジェクト ファイル) を使用して呼び出されます。次に、コマンド ラインで指定した順序で、オブジェクト ファイルとライブラリ、およびリンク関連のオプションが呼び出されます。

リンクには、静的リンクと動的リンクの 2 種類があります。静的リンクを使用すると、実行可能ファイルには、実行時に動的にロードされるものを除いて、実行時に使用するすべてのオブジェクト コードが含まれます。リンカーは、オブジェクト ファイルとライブラリを検出すると処理します。多くの場合、最初のオブジェクト ファイルは次のようcrt0.oに呼ばれ、コンパイラによって提供されます。への参照が含まれていますmain()。リンカーは、定義されているシンボルと、定義されていないシンボルを参照して、オブジェクト ファイルを処理します。

静的リンクの場合、ライブラリを検出するとスキャンします。ライブラリが現在未定義のシンボルを提供する場合、関連するコードをライブラリから取得し、必要に応じて再スキャンして、参照されているがまだ定義されていない他のシンボルを見つけます。未定義のシンボルが のみmain()で、ライブラリに a が含まれていない場合main()(これは正常です)、ライブラリは事実上スキップされます。

動的リンク (共有オブジェクトまたは動的にリンクされたライブラリ、別名 DLL を使用) の場合、(一部のマシンでは) リンク行でライブラリについて言及すると、すべてのシンボルが定義されているかどうかにかかわらず自動的に定義済みとして扱われていました。使用するかどうか。最近では、ライブラリがスキャンされるリンク プロセスの時点で関連するシンボルが含まれていない場合、コンパイラはライブラリを無視します。

あなたの作業例は、正しいリンク順序を示しています—オブジェクトファイルの後のライブラリ。確かに、コマンドラインの例ではソースファイルをリストしますが、コンパイラはコマンドを変換して、ソースから作成したばかりのオブジェクトファイルを参照し、ライブラリとその他のリンカーフラグをコマンドラインと同じ順序でリストします。未定義の参照を満たしているかどうかに関係なく、共有オブジェクトの使用を記録する古いスタイルのリンカがある場合、「動作していない」行もリンク OK になります。ただし、信頼できるものではありませんでした。ライブラリのいずれかが静的ライブラリである場合、通常は問題が発生します。

したがって、ルールは単純です。

  • プログラムをリンクするとき、オブジェクト ファイルをライブラリの前にリストします。

常に機能します — 新旧のリンカー、静的および動的ライブラリ。他の方法で行うと、一部のプラットフォームでは遅かれ早かれ失敗する可能性があります。

于 2013-06-05T01:48:35.367 に答える
0

これは gcc 構文です。最初のものは機能せず、2番目のものは次の理由を理解していただければ幸いです。

GCC 構文

$ gcc [オプション] [ソース ファイル] [オブジェクト ファイル] [-o 出力ファイル]

于 2013-06-05T00:54:56.220 に答える