C语言从零开发FTP服务器:Makefile编译报错及目录结构需求
解决FTP服务器Makefile编译报错及目标文件目录规划问题
问题背景
项目目录结构:
. ├── include/ ├── src/ ├── main.c └── Makefile
- 原Makefile执行
make时报错:make: *** No rule to make target 'obj/main.o', needed by 'myftp'. Stop. - 临时修改
OBJ变量为$(SRC:%.c=%.o)后编译正常,但目标文件与源码混放,需将.o文件统一放到obj/目录、.d依赖文件放到dep/目录,且复刻源码的目录层级(如src/下的文件编译后对应obj/src/目录)。
最终Makefile实现
以下是满足需求的Makefile,包含完整的编译、依赖管理和清理逻辑:
# 编译目标 TARGET := myftp # 收集所有源码文件:根目录main.c + src下所有.c文件 SRC := main.c $(wildcard src/*.c) # 映射目标文件路径:将每个.c文件对应到obj目录下的同名.o,保留源码目录结构 OBJ := $(patsubst %.c, obj/%.o, $(SRC)) # 映射依赖文件路径:将每个.c文件对应到dep目录下的同名.d DEP := $(patsubst %.c, dep/%.d, $(SRC)) # 编译参数:指定头文件目录,开启警告,自动生成依赖文件 CFLAGS := -Iinclude -Wall -Wextra -MMD -MP # 默认执行目标:生成最终可执行文件 all: $(TARGET) # 链接生成可执行文件 $(TARGET): $(OBJ) $(CC) $^ -o $@ # 编译规则:将任意.c文件编译为obj目录下对应的.o文件,自动创建子目录 obj/%.o: %.c @mkdir -p $(dir $@) $(CC) $(CFLAGS) -c $< -o $@ # 引入依赖文件,让make自动处理头文件更新 -include $(DEP) # 清理编译产物 clean: rm -rf $(TARGET) obj dep
核心逻辑说明
- 路径映射:通过
patsubst函数将源码路径转换为obj/和dep/下的对应路径,比如src/ftp_conn.c会生成obj/src/ftp_conn.o和dep/src/ftp_conn.d,完美复刻源码目录结构。 - 自动创建目录:
mkdir -p $(dir $@)确保编译时目标文件所在的子目录存在,避免因目录缺失导致的编译错误。 - 依赖管理:
-MMD -MP选项让GCC自动生成头文件依赖的.d文件,-include $(DEP)让make在编译时自动检测头文件变化,触发重新编译。 - 彻底清理:
rm -rf直接删除整个obj和dep目录,确保清理所有编译产物,不会残留零散文件。
使用验证
- 执行
make:自动创建obj/、dep/目录,其中obj/包含main.o和src/子目录(存放源码编译的.o文件),最终生成myftp可执行文件。 - 执行
make clean:清除所有编译产物,恢复到项目初始状态。
内容的提问来源于stack exchange,提问作者Baptiste LEROYER
相关产品推荐
相关产品推荐

