Remake 仅在需要时才包含 makefile

Remake 仅在需要时才包含 makefile

假设我有一个 Makefile,它有两个“主要”目标:foo.oclean。前一个有创建文件的方法foo.o。后一种删除所有临时文件。

为了消除手动指定依赖项的需要foo.o,我的目标foo.d是有效的 makefile,以 format 指定依赖项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就会被包含在内,甚至被制定。

如何阻止 make 包括制定目标的foo.d时间? clean(或者,如何仅在foo.o制作时包含它?)

该解决方案可以使用 GNU Make 的功能。

答案1

解决方案非常简单,但会导致 Makefile 代码有些不可读。

首先,我们必须知道该include指令尝试包含该文件,如果它不存在,则会失败。还有-include(或sinclude),如果文件不存在,则根本不包含该文件。但这不是我们想要的,因为如果可能的话,它仍然会尝试重新创建包含的 makefile。

我们可以通过两种方式避免这种情况:要么通过更改 include 指令参数,使 Makefile 认为它无法生成该包含文件(例如相对路径与绝对路径等),要么在文件不包含该文件时省略该参数。存在。这可以通过多种方式完成:

-include $(wildcard foo.d*)

但这有一个问题:它也匹配其他文件。所以我们可以这样写:

-include $(filter foo.d,$(wildcard foo.d*))

甚至这个:

-include $(filter foo.d,$(wildcard *))

我们又提出了另一个问题:foo.d没有得到实现。通过将其添加为另一个目标可以解决此问题foo.o

foo.o: foo.c foo.d

或将其添加为命令:

foo.o: foo.c
    $(MAKE) foo.d
    cc …

或直接,不调用make

foo.o: foo.c
    sh script.sh …
    cc …

相关内容