假设我有一个 Makefile,它有两个“主要”目标:foo.o
和clean
. 前者有一个创建foo.o
文件的方法。后者删除所有临时文件。
为了消除foo.o
手动指定依赖项的需要,我的目标foo.d
是有效的 makefile,指定格式的依赖项foo.o foo.d : dep1 dep2 depn
。此依赖文件包含在 makefile 中。
生成文件如下所示:
;; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with C-x C-f and enter text in its buffer.
foo.o: foo.c
cc -c -o $@ $<
foo.d: foo.c
sh deps.sh $< > $@
include foo.d
.PHONY: clean
clean:
rm …
当我想制作foo.o
时,一切正常:foo.d
得到(重新)制作,它被包含foo.o
并被制作。问题是当我想制作clean
目标时,foo.d
被包含,甚至被制作。
如何防止制作包括制作目标的foo.d
时间clean
?(或者,如何仅在foo.o
制作时包含它?)
该解决方案可以使用 GNU Make 的功能。
解决方案非常简单,但会导致 Makefile 代码有些不可读。
首先,我们必须知道
include
指令试图包含该文件,如果它不存在,则失败。如果文件不存在,也有-include
(或sinclude
)不包含该文件。但这不是我们想要的,因为它仍然会尝试重新制作包含的 makefile,如果可能的话。我们可以通过两种方式避免这种情况:要么以 Makefile 认为它无法生成包含文件的方式更改 include 指令参数(例如相对路径与绝对路径等),要么在文件不包含时省略参数存在。这可以通过多种方式完成:
但这有一个问题:它也匹配其他文件。所以我们可以这样写:
甚至这个:
而我们又犯了一个问题:
foo.d
没有得到。这可以通过将其添加为的另一个目标来解决foo.o
:或将其添加为命令:
或直接,不调用
make
: