makefile: 对 main 的未定义引用

makefile: undefined reference to main

我正在开发一个生成 2 个可执行文件的简单项目,main 和 Server。

Main.c 中的程序通过头文件 user_interface.h 使用了 user_interface.c 中的代码。

我写的Makefile如下,

all: main user_interface.o Server

main: user_interface.o main.c
    gcc main.c user_interface.o -o main

user_interface.o: user_interface.c user_interface.h
    gcc user_interface.c -o user_interface.o

Server: Server.c
    gcc Server.c -o Server

clean:
    rm -rf main *.o Server

当我在终端上输入 make 时,出现以下错误:

gcc user_interface.c -o user_interface.o
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [Makefile:18: user_interface.o] Error 1

如何解决这个错误?

您对 user_interface.o 的规则是错误的。您需要使用 -c 选项来告诉它它正在创建目标文件而不是可执行文件,因此它不需要 main() 函数。

all: main Server

main: user_interface.o main.o
    gcc main.o user_interface.o -o main

main.o: main.c
    gcc -c main.c

user_interface.o: user_interface.c
    gcc -c user_interface.o

Server: Server.c
    gcc Server.c -o Server

clean:
    rm -rf main *.o Server

make 实际上有一个 built-in 规则用于将 .c 编译为 .o,所以你实际上不需要这些规则。

我认为您没有正确使用 makefile。

因此您的 makefile 的一部分可能如下所示:

core: WitchCraft NeuralServer AmoebaServer CDS NLPServer HollyServer

test: ENiX4NeuralCLI DataInjector NNTestServer ENiX4AmoebaCLI CLINLPTest

WitchCraft: ENiX_Net.o ENiX_IPC.o ENiX_SHM.o ENiX_Seq.o ENiX_Packet.o WitchCraft.o ENiX_Config.o ENiX_Disk.o ENiX_Binary.o
        g++ -ggdb -O0 ENiX_Net.o ENiX_IPC.o ENiX_SHM.o ENiX_Seq.o ENiX_Packet.o WitchCraft.o ENiX_Config.o ENiX_Disk.o ENiX_Binary.o -o WitchCraft.bin -std=c++11 -lreadline

冒号前的这些东西,叫做目标。可以调用:

make <target>

例如

make WitchCraft

所以对于目标的第一行,出于某种原因你在里面有源文件,看起来你正试图将 user_interface.o 编译为二进制文件,而不是对象,但是你不会 link 将其发送到 main.o。

所以我怀疑你想要这样的东西:

main: main.o user_interface.o
    gcc main.o user_interface.o -o main

而应该做的是使 make 查找 main.o(即 main.c)的源代码,同样地查找 interface.o(即 interface.c)的源代码,然后将这些编译成目标文件(即 .o 文件)。

然后你会 link 将这些目标文件转换成二进制文件,使用带有 -o 的 gcc 指定二进制输出文件,在本例中为“main”。

并且您需要对服务器执行类似的操作。