C 将头文件与makefile链接:未定义引用错误

C 将头文件与makefile链接:未定义引用错误,c,makefile,C,Makefile,我有一个包含以下文件的项目,所有文件都在同一个文件夹中 client.c server.c reliable_udp.h reliable_udp.c conf.h 在其他库中,client.c还包括reliable_udp.h(#包括“reliable_udp.h”),以便使用函数packet_send和print_conf(在reliable_udp.c中实现) 我是Makefiles新手,我正在尝试编写一个: CC = gcc CFLAGS = -Wall -Wextra -Wpedan

我有一个包含以下文件的项目,所有文件都在同一个文件夹中

client.c
server.c
reliable_udp.h
reliable_udp.c
conf.h
在其他库中,
client.c
还包括
reliable_udp.h
#包括“reliable_udp.h”
),以便使用函数
packet_send
print_conf
(在
reliable_udp.c
中实现)

我是
Makefile
s新手,我正在尝试编写一个:

CC = gcc
CFLAGS = -Wall -Wextra -Wpedantic -O3
SRC = client.c server.c
OBJ = $(SRC:.c=.o)

all: $(OBJ)
        ${CC} ${CLFAGS} client.o -o client
        ${CC} ${CLFAGS} server.o -o server

client.o: reliable_udp.h

clean:
        rm -f *.o core

cleanall:
        rm -f *.o core client server
如果我尝试运行
make
,我会得到以下输出:

gcc -Wall -Wextra -Wpedantic -O3   -c -o client.o client.c
gcc  client.o -o client
client.o: In function `main':
client.c:(.text.startup+0x84): undefined reference to `packet_send'
client.c:(.text.startup+0x8b): undefined reference to `print_conf'
collect2: error: ld returned 1 exit status
Makefile:7: recipe for target 'all' failed
make: *** [all] Error 1

显然,我没有正确编写
Makefile
。我该怎么修为什么会出现此错误?

一个快速修复方法是修改Makefile,如下所示:

all: $(OBJ)
        ${CC} ${CLFAGS} reliable_udp.o client.o -o client
        ${CC} ${CLFAGS} reliable_udp.o server.o -o server
但这并不漂亮,在“现实世界”中,更好的选择可能是为“可靠的_udp”创建一个共享库,或者至少重构一点Makefile

错误的原因是“reliable_udp”没有编译到最终的二进制文件中,因为它没有在makefile的任何地方显式指定。

为什么会出现此错误

因为链接配方不包括'reliable_udp.0'对象,而且makefile中的任何内容都不会将'reliable_udp.c编译为'reliable_udp.o'`

发布的makefile包含几个问题,如对问题的注释所示

下面是一个建议的简单makefile,它应该执行所需的功能

注意:用制表符替换

注意:在以下makefile中,调用命令可以是:

make          -- to generate both 'client' and 'server'
                 as it will use the first target, which is 'all'
make all      -- to generate both 'client' and 'server'
make client   -- to only generate the 'client' executable
make server   -- to only generate the 'server' executable
make clean    -- to delete the object files
make cleanall -- to delete the object files and the executables
现在是提议的makefile

#use ':=' rather than '=' so macros only evaluated once

#assure the desired utilities are used
CC := /usr/bin/gcc
RM := /usr/bin/rm -f

CFLAGS := -Wall -Wextra -Wpedantic -std=GNU11 -O3

#generate a list of all the source files
SRC := client.c server.c reliable_udp.c

#generate a list of all the object file names
OBJ := $(SRC:.c=.o)

#let make know that the target 'all' will not produce a file of the same name
#notice the 'all' target dependencies are the final executables
.PHONY: all
all: client server

#this will perform all the compiles
#while expecting the user supplied header files to be in the local directory
%.o:%.c
<tab>$(CC) -c $(CFLAGS) $^ -o $@ -I.

#link the 'client' executable
client: client.o reliable_udp.o
<tab>${CC}  $^ -o $@

#link the 'server' executable
server: server.o reliable_udp.o
<tab>${CC}  $^ -o $@

#let make know that this target will not produce a file of the same name
.PHONY: clean
clean:
<tab>$(RM) $(OBJ) core

#let make know that this target will not produce a file of the same name
.PHONY: cleanall
cleanall:
<tab>$(RM) $(OBJ) core client server
#使用“:=”而不是“=”,这样宏只计算一次
#确保使用所需的实用程序
抄送:=/usr/bin/gcc
RM:=/usr/bin/RM-f
CFLAGS:=-Wall-Wextra-Wpedantic-std=GNU11-O3
#生成所有源文件的列表
SRC:=client.c server.c reliable_udp.c
#生成所有对象文件名的列表
对象:=$(SRC:.c=.o)
#让我们知道目标“all”不会生成同名文件
#请注意,“所有”目标依赖项是最终的可执行文件
冒牌货:全部
全部:客户端服务器
#这将执行所有编译
#同时希望用户提供的头文件位于本地目录中
%.o:%.c
$(CC)-c$(CFLAGS)$^-o$@-I。
#链接“客户端”可执行文件
客户端:client.o可靠的_udp.o
${CC}$^-o$@
#链接“服务器”可执行文件
服务器:server.o可靠的_udp.o
${CC}$^-o$@
#请确保此目标不会生成同名文件
.假冒:干净
清洁:
$(RM)$(OBJ)核心
#请确保此目标不会生成同名文件
.假的:干净利落
清洁所有:
$(RM)$(OBJ)核心客户端服务器

我看不到您的品牌中提到的“reliable_udp.c”的可能重复。它应该如何编译?@Yunnosch我该怎么说?我认为,
client.o:reliable\u udp.h
足够您想要的client.o在reliable\u udp.h更改时更新。怎么用?这应该如何涉及到可靠的udp.c?或者换句话说,为什么
SRC=client.cserver.c
没有提到可靠的udp.c?我想说的是,你应该解释你的makefile的逻辑,以便更容易回答你的问题。谢谢你的回答。无需在
Makefile
中提及
reliable_udp.h
?这令人惊讶me@Robb1,您声明所有文件都在同一目录中。编译.c文件的方法有一个选项:
-I.
,它表示在本地目录中查找头文件。这是所有必要的