14

我正在使用 gmake 并按照手册gcc -MM跟踪标头依赖项。该机制依赖于 makefile指令来导入计算的依赖项。include

因为.d文件包含在 makefile 中,所以它们必须存在才能生成任何目标,包括clean. 因此,在clean做正确的事情之前,必须生成依赖关系,如果构建失败,那么clean只会变得更加混乱。

此外clean,它希望在构建任何目标之前生成所有依赖项。

此外,如果任何文件被更改为包含一个不存在的文件,那么依赖解析就会中断,并且什么都不会构建。

如果删除了标头,则现有的依赖文件仍然包含将其命名为目标,并且在删除有问题的依赖文件之前不会构建任何内容……这不能用clean.

用通配符替换替换模式include以包含所有预先存在的依赖文件可以解决一些问题,但它仍然无法清除损坏的依赖项,并且永远不会删除陈旧的依赖项文件。有更好的解决方案吗?手册中的示例真的是为了实际使用吗?

4

3 回答 3

19

只是不提供生成.d文件的规则。Paul Smith 的“高级自动依赖生成” (GNU Make 的维护者)很好地解释了为什么它不那么好(包括你的情况) 。

简而言之,以下模式适用于所有情况:

CPPFLAGS += -MMD -MP

%.o: %.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<

-include $(OBJS:.o=.d)

另请参阅我之前的相关答案:

于 2012-10-12T10:56:25.660 回答
9

解决方案是使用条件语法

ifneq ($(MAKECMDGOALS), clean)
-include $(notdir $(SOURCES:.cpp=.d))
endif

这使得干净的目标不会调用*.d目标,因为当您运行时make clean*.d文件不会包含在 Makefile 中。

参考:https ://www.gnu.org/software/make/manual/html_node/Goals.html

于 2015-11-03T03:43:38.987 回答
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

于 2012-10-12T10:52:35.687 回答