【问题标题】:Makefile directory rule dependency rebuildMakefile目录规则依赖重建
【发布时间】:2018-05-25 12:49:32
【问题描述】:

我得到了这样的 Makefile

all: sub-dir my-rule

sub-dir:
    $(MAKE) -C $@

my-rule: sub-dir
    g++ main.cpp

.PHONY sub-dir

所以基本上我想在构建 my-rule 之前等待 sub-dir 完成,但 my-rule 每次都会重新构建 - 即使 sub-dir 没有变化。

如何让它等待子目录并仅在子目录发生更改时重建我的规则?

【问题讨论】:

    标签: makefile compilation gnu-make


    【解决方案1】:

    当您编写如下规则时:

    my-rule: sub-dir
    

    如果先决条件 (sub-dir) 较新,则将重建目标 (my-rule)。 Make 不关心目标或先决条件是文件还是目录,只关心它们的最后修改时间是什么。

    你的 makefile 有很多问题。最简单的一个是您永远不会创建目标 my-rule,因此就 make 而言,目标 总是 过时(不存在 == 过时)。

    您必须像这样编写规则,以便配方更新目标:

    my-rule: sub-dir
            g++ main.cpp -o $@
    

    如果这不是您想要创建的程序,当然更改my-rule。

    第二,目录修改时间会随着目录的变化而更新。当该目录中的某些内容被重命名、添加或删除时,该目录会发生变化。因此,如果您调用 sub-make 并且 sub-make 重命名、添加或删除该目录中的某些内容,则 my-rule 目标将过期。如果没有任何内容被重命名、添加或删除,那么my-rule 将不会过时。

    一般来说,您几乎从不想将目录列为先决条件。相反,您应该将子make创建的目标列为先决条件,如下所示(假设子make创建libfoo.):

    sub-dir/libfoo.a: FORCE
            $(MAKE) -C $(@D)
    FORCE:
    
    my-rule: sub-dir/libfoo.a
            ...
    

    FORCE 规则用于强制调用子生成,即使 sub-dir/libfoo.a 已经存在。

    【讨论】:

    • 好吧,当您将构建结果放到他们自己的目录中时,您几乎总是希望一个目录成为仅订单依赖项。例如。目标文件取决于它们的目录。如果 GNU Make 可以自动为目标创建目录,那就太好了。
    • 在这种情况下,我们知道该目录已经存在,因为它包含一个 makefile(并且可能是源代码)。仅当您将目标文件写入可能不存在的单独目录时才需要仅订购先决条件技巧。
    • 如果我要在子目录中构建多个文件怎么办?
    • 您可以像我上面展示的那样制作多个目标。不幸的是,它会为每个目标重新调用一次 make,但除非您的 makefile 非常大且复杂,否则您不会真正注意到它。或者,您必须变得更高级,并拥有一个所有子目标都依赖的目标来进行子制作。
    • 这是我一直在寻找的答案。
    猜你喜欢
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2021-02-07
    • 2012-10-04
    相关资源
    最近更新 更多