私はプログラム(es3と呼ばれる)をコンパイルしようとしていますが、ターミナルから書くとき:
gcc es3.c -o es3
次のメッセージが表示されます。
/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
何ができますか?
これは、es3.c
がmain
関数を定義しておらず、その関数から実行可能ファイルを作成しようとしていることを意味します。実行可能ファイルにはエントリポイントが必要であるため、リンカがエラーを出します。
オブジェクトファイルのみにコンパイルするには、-c
オプションを使用します。
gcc es3.c -c
gcc es3.o main.c -o es3
上記はes3.c
をオブジェクトファイルにコンパイルしてから、main
関数を含むファイルmain.c
をコンパイルし、リンカーはes3.o
とmain.o
をマージして、 es3
という実行可能ファイル。
おそらく、あなたのmain
関数は、たとえば前処理。前処理が何をしているのかを知るには、gcc -C -E es3.c > es3.i
を試してから、生成されたファイルes3.iをエディターで調べます(そしてその中のmain
を検索します)。
まず、常に(あなたは初心者なので)コンパイルする必要があります
gcc -Wall -g -c es3.c
gcc -Wall -g es3.o -o es3
-Wall
フラグは非常に重要であり、常に使用する必要があります。これは、コンパイラに(ほぼ)すべての警告を出すように指示します。また、常に警告に耳を傾ける必要があります。つまり、警告が表示されなくなるまでソースコードファイルes3.C
を修正する必要があります。
-g
フラグも重要です。これは、gcc
にデバッグ情報をオブジェクトファイルと実行可能ファイルに入れるように要求するためです。その後、デバッガー(gdb
など)を使用してプログラムをデバッグできます。
オブジェクトファイルまたは実行可能ファイル内のシンボルのリストを取得するには、nm
を使用できます。
もちろん、GNU/Linuxシステムを使用すると仮定しています(まだ使用していない場合は、GNU/Linuxを使用することをお勧めします)。
これまで言及されていない可能性の1つは、自分が自分だと思うファイルを編集していない可能性があることです。つまり、あなたのエディターはあなたが思っていたものとは異なるcwdを持っているかもしれません。
コンパイルしているファイルで「more」を実行し、希望する内容が実際に含まれていることを再確認します。お役に立てば幸いです!
実行可能ファイルにはメイン関数が必要です。以下のHello Worldデモをご覧ください。
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
ご覧のとおり、主な機能があります。このメイン関数がない場合、ldは「メインへの未定義参照」を報告します
私の結果を確認してください:
$ cat es3.c
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
$ gcc -Wall -g -c es3.c
$ gcc -Wall -g es3.o -o es3
~$ ./es3
Hello world!
$ objdump -t es3.o
を使用して、メインシンボルがあるかどうかを確認してください。以下は私の結果です。
$ objdump -t es3.o
es3.o: file format elf32-i386
SYMBOL TABLE:
00000000 l df *ABS* 00000000 es3.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .debug_abbrev 00000000 .debug_abbrev
00000000 l d .debug_info 00000000 .debug_info
00000000 l d .debug_line 00000000 .debug_line
00000000 l d .rodata 00000000 .rodata
00000000 l d .debug_frame 00000000 .debug_frame
00000000 l d .debug_loc 00000000 .debug_loc
00000000 l d .debug_pubnames 00000000 .debug_pubnames
00000000 l d .debug_aranges 00000000 .debug_aranges
00000000 l d .debug_str 00000000 .debug_str
00000000 l d .note.GNU-stack 00000000 .note.GNU-stack
00000000 l d .comment 00000000 .comment
00000000 g F .text 0000002b main
00000000 *UND* 00000000 puts
私の場合、メイン関数宣言のvoid
が見つからないことがわかりました。
以前はWindowsでVisual Studioを使用していましたが、これが問題になることはなかったので、今は省略してもよいと考えました。
この問題を解決するには、main
関数を追加するだけです。と同じように:
int main()
{
return 0;
}