如何编写Makefile编译自动生成的C文件及常规C文件?
正确的Makefile编写方案
首先明确核心需求:通过cperformer将特定文本文件(假设后缀为.perf,可根据实际修改)转换为C文件,再与手写的常规C文件一同编译链接为目标程序。以下是解决所有问题的Makefile实现:
# 定义目标程序名称 TARGET = myapp # 1. 找到所有需要生成C文件的文本源文件(这里假设后缀是.perf,按需修改) GEN_SOURCES = $(wildcard *.perf) # 2. 从文本源文件推导出生成的C文件列表 GEN_C_FILES = $(patsubst %.perf, %.c, $(GEN_SOURCES)) # 3. 收集所有常规手写C文件(排除生成的C文件) NORMAL_C_FILES = $(filter-out $(GEN_C_FILES), $(wildcard *.c)) # 4. 所有需要编译的C文件(生成的+常规的) ALL_C_FILES = $(GEN_C_FILES) $(NORMAL_C_FILES) # 5. 对应的目标文件列表 OBJS = $(patsubst %.c, %.o, $(ALL_C_FILES)) # 链接目标程序 $(TARGET): $(OBJS) gcc $^ -o $@ # 模式规则:从.perf文本文件生成对应的C文件(仅当.perf比.c新时才会执行) %.c: %.perf cperformer $< > $@ # 模式规则:编译C文件为目标文件 %.o: %.c gcc -c $< -o $@ # 清理生成的文件 .PHONY: clean clean: rm -f $(TARGET) $(OBJS) $(GEN_C_FILES)
方案解决的核心问题解释
- 解决Makefile 1的单一生成问题:通过
%.c: %.perf模式规则,每个.perf文本文件会独立生成对应的C文件,不会出现只生成单个文件的情况,确保GCC能找到所有需要的编译文件。 - 解决Makefile 2的无规则问题:通过
GEN_C_FILES明确推导出生成文件的列表,让Make知道需要构建这些文件,同时模式规则%.c: %.perf精准匹配生成逻辑,不会出现"无生成规则"的错误。 - 解决Makefile 3的全量重建问题:Make会自动检查
.perf源文件和生成的.c文件的时间戳,只有当源文本文件修改过(比生成的C文件新)时,才会重新执行cperformer生成对应C文件,避免不必要的全量重建。
自定义调整说明
- 如果你的文本源文件后缀不是
.perf,将GEN_SOURCES中的*.perf替换为实际后缀(比如*.txt),同时修改模式规则%.c: %.perf中的后缀。 - 如果
cperformer需要额外参数,调整生成命令为cperformer [参数] $< > $@。 - 若目标程序名称不是
myapp,修改TARGET变量的值即可。
内容的提问来源于stack exchange,提问作者fbourge
相关产品推荐
相关产品推荐

