2016-08-24 6 views
11

私はCコンパイルをもう少し深く理解しようとしていますので、私はコンパイルして "手動で"リンクしています。最小限のCプログラムで "main"への未定義の参照

gcc -S main.c 
as main.s -o main.o 
ld main.o 

とリンクしようとすると、私が手::ここに私のコード

int main() 
{ 
    return 0; 
} 

そして、ここでは、私は私のコンソール(Windowsの場合)に入れている何です

main.o:main.c:(text+0x7): undefined reference to `__main' 
+2

'gcc -v main.c'を実行して、コンパイラが実際に実行するコマンドを確認します。 'ld'はコマンドラインよりもはるかに複雑なコマンドラインを実行します。 –

+0

GCCの極端に長い 'ld'引数は必ずしも必須ではありません。シンプルな 'Hello、world'プログラムは' ld -lc -lkernel32 src.o -o src.exe'とだけ完全にリンクできます。 –

+0

@RyanB「llcが見つかりません」というメッセージが表示されます。 –

答えて

12

あなたは必要なサポートライブラリのいずれにもリンクしていませんでした。 stdin、stdout、stderrのようなCグローバルオブジェクトは、どこからも出現しません。コマンド引数と環境変数は、オペレーティングシステムから取得されます。終了時には、atexit()関数が呼び出され、mainの戻りコードがexit(return_code)に渡されます。等

gcc -dumpspecs,gcc -print-libgcc-file-nameのコマンドをチェックしてください。そのディレクトリ内の他のすべてのライブラリを見てください。 dumpspecsの出力で参照される多くのライブラリとオブジェクトファイルが見つかります。私はそのスペックルールがいつ、どのように解釈されるかは正確にはわかりませんが、あなたはおそらくそのアイデアを得ることができます。そして、私はGCCの情報ページinfo gccは、あなたが十分に掘り下げれば詳細に説明していると思います。

info gccとし、「G」を押してから

「スペックファイル」を入力して、ジョナサン・レフラーはショートカットはverboseオプションではgccを実行することである、と述べたように:gcc -vとちょうどそれが使用されるコマンドかを参照してください。

+0

問題がサポートライブラリである場合、なぜ "__main"への未定義の参照ですか? –

+0

@JackMこれは、 'main'の実際の作業を行う関数です。例えば、https://gcc.gnu.org/onlinedocs/gccint/Collect2.html – deamentiaemundi

+0

を参照してください。また、ASMを掘り出したい場合は、練習は最適化をオフにすることです(-O0フラグ)。ここでは、何らかの機能や最適化が行われているので役に立たないが、私は指摘する価値があると思う。 –

関連する問題