我正在使用gmake和gcc -MM
跟踪the manual之后的标头依赖关系。该机制依赖于makefile include
指令来导入计算的依赖项。
由于makefile包含.d
个文件,因此它们必须存在才能生成任何目标,包括clean
。因此,在clean
能够做正确的事情之前,必须生成依赖关系,如果一个人无法构建,那么clean
就会变得更加混乱。
除了clean
之外,它还希望在构建任何目标之前建立所有依赖项。
此外,如果任何文件被更改为包含不存在的文件,则依赖项解析会中断,并且根本不会构建任何文件。
如果删除了标题,那么现有的依赖项文件仍然将其命名为目标,并且在删除有问题的依赖项文件之前不会构建任何内容......这不能用clean
完成。
用通配符替换include
的替换模式以包含所有预先存在的依赖项文件解决了一些问题,但它仍然无法清除损坏的依赖项,并且永远不会删除过时的依赖项文件。有更好的解决方案吗?该手册的示例是否真正用于实际用途?
答案 0 :(得分:18)
请勿提供生成.d
文件的规则。可以在Paul Smith的"Advanced Auto-Dependency Generation"中找到一个很好的解释为什么它不那么好(包括你的情况) - 这是GNU Make的维护者。
简而言之,以下模式适用于所有情况:
CPPFLAGS += -MMD -MP
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
-include $(OBJS:.o=.d)
另见我以前的相关答案:
答案 1 :(得分:6)
解决方案是使用https://www.gnu.org/software/make/manual/html_node/Goals.html:
ifneq ($(MAKECMDGOALS), clean)
-include $(notdir $(SOURCES:.cpp=.d))
endif
这使得clean目标不会调用*.d
目标,因为当您运行make clean
时,*.d
文件将不会包含在Makefile中。
参考:{{3}}
答案 2 :(得分:2)
我常用的模式看起来像
all: target
target: .depends
## [snip build rules]
.depends:
gcc -MM $(CPPFLAGS) .... > $@
-include .depends
注意-include
而不是include
。基本上,它有条件地包括:即iff文件存在
请参阅文档:http://www.gnu.org/software/make/manual/make.html#Include