【发布时间】:2018-10-12 16:10:55
【问题描述】:
我希望我的 Makefile 执行以下操作:
- 当主目标需要某个文件时,总是运行一些命令
- 如果依赖于该文件的所有内容发生更改(运行这些命令的结果),则重新构建它
在我的例子中,这个文件是一个 C 头文件,它应该包含版本信息;我希望 makefile 始终更新此版本标头并重建包含它的所有文件。
会发生什么: 当我运行 make 时,每次都会执行版本标头更新(如我所愿)。 但是依赖于这个头文件的文件只会每隔一段时间重新构建一次。
这是我精简的 Makefile:
SOURCES:= main.c
app.exe: $(SOURCES:%.c=%.o)
gcc -o $@ $^
# always recompile when dependency information is missing
$(SOURCES:%.c=%.o): %.o: %.c %.d
gcc -c $< -MMD
$(SOURCES:%.c=%.d):
version.h: update-version
update-version:
touch version.h
# include C/C++ header-dependencies
-include $(SOURCES:%.c=%.d)
.PHONY: update-version
# disables builtin suffix-rules
.SUFFIXES:
谁能帮我理解为什么这不是每次都重新编译,而是每次都重新编译一次?
make 是 GNU Make 4.2.1,remake 的行为完全相同。
【问题讨论】:
-
改进建议...而不是在每个地方都写出模式替换 (
$(SOURCES:%.c=%...)),我发现它更具可读性,例如OBJECTS:=$(SOURCES:%.c=%.o)和DEPENDS:=$(SOURCES:%.c=%.d)在顶部,以及使用它们的规则(例如-include $(DEPENDS))。 -- 此外,使用-MP选项,GCC 将为依赖文件inside 的每个依赖文件生成“虚拟”规则(不再需要$(SOURCES:%.c=%.d):)。 -
AFAICT,
-MP选项只会为所有 header 文件添加空规则,而不是*.d文件本身。 (在删除头文件后使用这个标志来防止错误仍然很好)。只需要空的*.d规则,因为我想在目标文件存在但*.d文件丢失/删除时强制重新编译。 -
你是对的,当然;好点子。根据您的需要,您可能希望
.o也依赖于 Makefile,因此您可以重新编译,例如当您更改警告列表时。