C语言 (.text+0x20): 对“main”的未定义引用和对函数的未定义引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20514587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:29:55  来源:igfitidea点击:

(.text+0x20): undefined reference to `main' and undefined reference to function

cgcccompilationcompiler-errorsmakefile

提问by user2644819

I am having issue getting my makefile to work without errors. The first issue i have is with an undefined reference to main. I have main in my producer.c file as a function. The second issue is an undefined reference to SearchCustomer().

我在让我的 makefile 正常工作时遇到问题。我遇到的第一个问题是对 main 的未定义引用。我的 producer.c 文件中有 main 作为函数。第二个问题是对 SearchCustomer() 的未定义引用。

error:

错误:

bash-4.1$ make
gcc -Wall -c producer.c shared.h
gcc -Wall -c consumer.c shared.h
gcc -Wall -c AddRemove.c shared.h
gcc -pthread -Wall -o producer.o consumer.o AddRemove.o
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
AddRemove.o: In function `AddRemove':
AddRemove.c:(.text+0xb1): undefined reference to `SearchCustomer'
AddRemove.c:(.text+0x1e9): undefined reference to `SearchCustomer'
AddRemove.c:(.text+0x351): undefined reference to `SearchCustomer'
collect2: ld returned 1 exit status
make: *** [producer] Error 1

makefile:

生成文件:

COMPILER = gcc
CCFLAGS = -Wall
all: main

debug:
    make DEBUG=TRUE


main: producer.o consumer.o AddRemove.o
    $(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o
producer.o: producer.c shared.h
    $(COMPILER) $(CCFLAGS) -c producer.c shared.h
consumer.o: consumer.c shared.h
    $(COMPILER) $(CCFLAGS) -c consumer.c shared.h
AddRemove.o: AddRemove.c shared.h
    $(COMPILER) $(CCFLAGS) -c AddRemove.c shared.h


ifeq ($(DEBUG), TRUE)
    CCFLAGS += -g
endif

clean:
    rm -f *.o

采纳答案by Jens

This rule

这个规则

main: producer.o consumer.o AddRemove.o
   $(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o

is wrong. It says to create a file named producer.o (with -o producer.o), but you want to create a file named main. Please excuse the shouting, but ALWAYS USE $@ TO REFERENCE THE TARGET:

是错的。它说要创建一个名为 producer.o(带有-o producer.o)的文件,但您想要创建一个名为main. 请原谅大喊大叫,但始终使用 $@ 来引用目标

main: producer.o consumer.o AddRemove.o
   $(COMPILER) -pthread $(CCFLAGS) -o $@ producer.o consumer.o AddRemove.o

As Shahbaz rightly points out, the gmake professionals would also use $^which expands to all the prerequisites in the rule. In general, if you find yourself repeating a string or name, you're doing it wrong and should use a variable, whether one of the built-ins or one you create.

正如 Shahbaz 正确指出的那样,gmake 专业人员也会使用$^which 扩展到规则中的所有先决条件。一般来说,如果您发现自己重复了一个字符串或名称,那么您就做错了,应该使用一个变量,无论是内置函数之一还是您创建的变量。

main: producer.o consumer.o AddRemove.o
   $(COMPILER) -pthread $(CCFLAGS) -o $@ $^

回答by Sourav Ghosh

This error means that, while linking, compiler is not able to find the definition of main()function anywhere.

此错误意味着,在链接时,编译器无法在main()任何地方找到函数的定义。

In your makefile, the mainrule will expand to something like this.

在您的 makefile 中,main规则将扩展为这样的内容。

main: producer.o consumer.o AddRemove.o
   gcc -pthread -Wall -o producer.o consumer.o AddRemove.o

As per the gccmanual page, the use of -oswitch is as below

根据gcc手册页-o开关的使用如下

-o file    Place output in file file. This applies regardless to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code. If -ois not specified, the default is to put an executable file in a.out.

-o file    将输出放在文件file 中。这适用于任何类型的输出,无论是可执行文件、目标文件、汇编程序文件还是预处理的 C 代码。如果-o未指定,则默认将可执行文件放入a.out.

It means, gcc will put the output in the filename provided immediate next to -oswitch. So, here instead of linking all the .ofiles together and creating the binary [main, in your case], its creating the binary as producer.o, linking the other .ofiles. Please correct that.

这意味着,gcc 会将输出放在-oswitch旁边提供的文件名中。因此,这里不是将所有.o文件链接在一起并创建二进制文件 [ main,在您的情况下],而是将二进制文件创建为producer.o,链接其他.o文件。请更正。