Make and last modification times of directories on Linux

走远了吗. 提交于 2019-12-02 14:01:19

问题


Consider the following makefile:

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

and the following interaction with it, starting from a directory that contains files a.in and b.in and nothing else:

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

So far, so good.

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

Still good, but now:

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

It rebuilds the a.out target, even though none of its prerequisites have changed.

It seems like what's happening is that when foo/b.out is created, the last modification time of the directory foo is updated, so it picks that up as having "changed".

Is there a way to avoid this? For example, is there a way to declare that foo/a.out depends on foo only in that foo has to exist, and the creating of files inside foo doesn't cause foo to be considered out of date?


回答1:


As an authority on Make recently pointed out:

"The one thing you must NEVER do is use a directory as a simple prerequisite. The rules the filesystem uses to update the modified time on directories do not work well with make."

But I think this will do what you want:

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



回答2:


I like @Beta's answer, but it is not portable. For a simple portable workaround, create a sentinel file when you create the directory, and depend on the sentinel file instead.

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

This can be further simplified with a pattern rule:

foo/%.out: %.in foo/.dir
        cp $< $@



回答3:


Instead of making the targets dependent on the directory, you can simply create the directory unconditionally in their build rules:

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

This avoids problems with using a directory as a prerequisite.



来源:https://stackoverflow.com/questions/16350158/make-and-last-modification-times-of-directories-on-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!