1

考虑以下生成文件:

foo :
    mkdir foo

foo/a.out : foo a.in
    cp a.in foo/a.out

foo/b.out : foo b.in
    cp b.in foo/b.out

以及与它的以下交互,从包含文件的目录开始,a.in仅此b.in而已:

$ make foo/a.out
mkdir foo
cp a.in foo/a.out

到目前为止,一切都很好。

$ make foo/b.out
cp b.in foo/b.out

仍然很好,但现在:

$ make foo/a.out   # a.out should be up to date now!
cp a.in foo/a.out

它重建a.out目标,即使它的先决条件都没有改变。

似乎正在发生的事情是,当foo/b.out创建时,目录的最后修改时间foo被更新,所以它认为它已经“改变”了。

有没有办法避免这种情况?例如,有没有一种方法可以声明仅foo/a.out依赖于必须存在的内容,并且在其中创建文件不会导致被认为是过时的?foofoofoofoo

4

3 回答 3

4

作为 Make 最近的权威人士指出

“你永远不能做的一件事是使用目录作为一个简单的先决条件。文件系统用于更新目录修改时间的规则不适用于 make。”

但我认为这会做你想要的:

foo :
    mkdir foo

foo/a.out : a.in | foo
    cp a.in foo/a.out

foo/b.out : b.in | foo
    cp b.in foo/b.out
于 2013-05-03T01:30:16.733 回答
2

我喜欢@Beta 的答案,但它不可移植。对于一个简单的可移植解决方法,请在创建目录时创建一个哨兵文件,并改为依赖哨兵文件。

foo/.dir:
        mkdir -p foo
        touch $@
foo/a.out: a.in foo/.dir
        cp $< $@
foo/b.out: b.in foo/.dir
        cp $< $@

这可以通过模式规则进一步简化:

foo/%.out: %.in foo/.dir
        cp $< $@
于 2013-05-03T05:51:48.663 回答
1

您可以简单地在其构建规则中无条件地创建目录,而不是使目标依赖于目录:

foo/a.out: a.in
        mkdir -p foo
        cp a.in foo/a.out

foo/b.out: b.in
        mkdir -p foo
        cp b.in foo/b.out

这避免了使用目录作为先决条件的问题。

于 2013-05-03T01:30:48.543 回答