web-dev-qa-db-ja.com

メインへの未定義の参照-collect2:ldが1つの終了ステータスを返しました

私はプログラム(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

何ができますか?

39
noobsharp

これは、es3.cmain関数を定義しておらず、その関数から実行可能ファイルを作成しようとしていることを意味します。実行可能ファイルにはエントリポイントが必要であるため、リンカがエラーを出します。

オブジェクトファイルのみにコンパイルするには、-cオプションを使用します。

gcc es3.c -c
gcc es3.o main.c -o es3

上記はes3.cをオブジェクトファイルにコンパイルしてから、main関数を含むファイルmain.cをコンパイルし、リンカーはes3.omain.oをマージして、 es3という実行可能ファイル。

49

おそらく、あなたの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を使用することをお勧めします)。

13

これまで言及されていない可能性の1つは、自分が自分だと思うファイルを編集していない可能性があることです。つまり、あなたのエディターはあなたが思っていたものとは異なるcwdを持っているかもしれません。

コンパイルしているファイルで「more」を実行し、希望する内容が実際に含まれていることを再確認します。お役に立てば幸いです!

3
matthewatabet

実行可能ファイルにはメイン関数が必要です。以下の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
3
Daniel

私の場合、メイン関数宣言のvoidが見つからないことがわかりました。

以前はWindowsでVisual Studioを使用していましたが、これが問題になることはなかったので、今は省略してもよいと考えました。

1
silicoin

この問題を解決するには、main関数を追加するだけです。と同じように:

int main()
{
    return 0;
}
0
贫贫贫贫僧