如何在Makefile中移除硬编码的源/头文件名,自动编译指定目录源码生成可执行文件
需求可行性确认
这个需求完全可实现,通过Make内置的通配符匹配、字符串处理函数和自动变量即可实现仅指定源码、头文件目录,自动扫描编译所有对应文件,后续新增文件无需修改Makefile配置。
改造后的完整Makefile
# 仅需修改此处的目录配置即可适配不同目录结构 SRC_DIRS = . funcs HEADERS_DIR = headers TARGET = lh CC = cc # 自动扫描所有指定目录下的.c源文件 SRCS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.c)) # 自动将.c文件名替换为.o文件名,生成目标文件列表 OBJS = $(patsubst %.c, %.o, $(SRCS)) # 自动生成依赖文件列表,用于跟踪头文件修改 DEPS = $(patsubst %.c, %.d, $(SRCS)) # 编译选项:指定头文件搜索路径,开启自动依赖生成 CFLAGS = -I$(HEADERS_DIR) -MMD # 最终链接生成目标可执行文件 $(TARGET): $(OBJS) $(CC) -o $@ $^ # 通用的.c编译为.o的规则,无需逐个写源文件的编译规则 %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< # 清理规则,自动删除所有生成的目标文件、依赖文件和可执行文件 clean: rm -f $(TARGET) $(OBJS) $(DEPS) # 引入自动生成的依赖文件 -include $(DEPS)
核心实现逻辑说明
- 自动扫描源文件:通过
foreach遍历你指定的所有源码目录,再用wildcard函数匹配每个目录下所有.c后缀的文件,全程不需要手动写任何源文件名 - 自动生成目标文件列表:用
patsubst字符串替换函数,把扫到的所有.c文件名批量替换成.o后缀,作为链接阶段的输入 - 通用编译规则:用
%.o: %.c的模式匹配规则,所有.o文件的编译都复用这一条规则,不需要给每个源文件单独写编译配置 - 自动头文件依赖跟踪:编译时加
-MMD参数会自动生成对应.d依赖文件,记录每个源文件依赖的头文件,后续头文件修改时会自动重编对应的源文件,不需要手动配置头文件依赖 - 可维护性优化:所有目录、编译器、目标文件名都集中在开头的变量配置区,后续修改目录结构、换编译器、改目标名只需要修改开头的变量即可,不需要改动后面的逻辑
使用说明
后续新增源文件直接放到你指定的SRC_DIRS对应的任意目录下即可,新增头文件直接放到HEADERS_DIR目录下,执行make会自动识别新文件完成编译,不需要修改Makefile任何内容。
内容的提问来源于stack exchange,提问作者user786
相关产品推荐
相关产品推荐

