Make不应重建深度依赖

时间:2018-12-19 16:19:36

标签: makefile

我有以下Makefile示例大致描述的构建过程:

a: b
    @echo "Build a, just using b.  Don't care about c."
    touch a

b: c
    @echo "Constructing b from c is cheap..."
    touch b
    @echo "Once accomplished, I no longer need c."

c:
    @echo "Constructing c is very expensive..."
    @echo "Work work work..."
    touch c

clean:
    $(RM) a b c

example: clean
    make a
    $(RM)   c
    make a

重点是:我需要c来构建b,但是一旦有了b,就再也不需要c。当我执行make example时,make使cba(如预期的那样)删除c,然后在在最后一次make a调用中,仅重制了c(尽管我认为它们现在已经过时,但不重制ba)。但是,由于我的目标是a并且b并没有改变,所以我不想重制c。忘掉它!谁在乎! a应该被认为是最新的。

另一件事是,当我

make a
rm c
make a

(而不是make example),在第二次调用make中将重建所有内容(而在make example中,第二次调用将仅重建c)。

当目标为make并且c的所有紧迫前提都存在且比其新鲜时,如何阻止a建立a({{ 1}}与a相比不是陈旧的,即使前提条件中的前提条件没有?

编辑:我认为我可能希望将每个文件都视为旧文件(例如,使用b除非该文件不存在

2 个答案:

答案 0 :(得分:1)

您似乎希望make将文件c视为中间文件,该文件除了生成另一个文件或其他文件时作为中间结果外,对您没有任何重要性。手册第10.4 Chains of Implicit Rules节对此概念进行了说明。由于您的示例未使用任何隐式规则,因此您可以将文件c手动标记为.INTERMEDIATE

此生成文件将c显示为中间文件。

a: b
        @echo "Build a, just using b.  Dont care about c."
        touch a

b: c
        @echo "Constructing b from c is cheap..."
        touch b
        @echo "Once accomplished, I no longer need c."

c: d
        @echo "Constructing c is very expensive..."
        @echo "Work work work..."
        touch c

.INTERMEDIATE: c
.PRECIOUS: c

我添加了一个基于your comment的文件d,尽管该示例不需要它。

在调用make之前,文件d必须存在,这是链的起点。调用make时,会发生以下情况:

$ touch d
$ make
Constructing c is very expensive...
Work work work...
touch c
Constructing b from c is cheap...
touch b
Once accomplished, I no longer need c.
Build a, just using b.  Dont care about c.
touch a

现在删除c对构建不会有任何影响:

$ rm c
$ make
make: `a' is up to date.

除此之外,基于依赖关系的更新行为“与通常相同”。

.PRECIOUS target是可选的。它是一个内置指令,指示make不要删除名为c的中间文件。您可以亲眼看到如果删除该行会发生什么情况。

答案 1 :(得分:0)

b可能是根据c构建的,但是您不想告诉Make b取决于c -如果b仅存在,那就足够了因此,您可以将b的食谱写为

b:
    $(MAKE) c
    @echo "Constructing b from c is cheap..."
    touch b
    @echo "Once accomplished, I no longer need c."

或者如果在制作c中仅使用b ,则可以将制作c的命令折叠到b的配方中并且完全不公开c的存在。

也许有更优雅的表达方式,而无需调用子品牌。而且,如果c有一些先决条件,如果它们在更新后会被重建,那么我想它们也需要列为b的先决条件。