GNU make:仅当文件尚不存在时才添加文件作为依赖项

时间:2016-02-22 11:07:13

标签: makefile gnu-make

GNU make对avoid recompilation有以下选项:

   -o file, --old-file=file, --assume-old=file
        Do not remake the file file even if it is older than  its  dependen‐
        cies,  and  do  not  remake  anything on account of changes in file.
        Essentially the file is treated  as  very  old  and  its  rules  are
        ignored.

所以给出以下Makefile

A : B
    touch A
B : C
    touch B
C :
    touch C

假设某些文件存在,我可以运行以下命令:

$ touch C
$ make A -o B
make: `A' is up to date.     # Good. C is out-of-date, but A does not get updated.

问题

如何更改我的Makefile,以便B 始终假设为旧,而仅重建

A : <WHAT_GOES_HERE> B
    touch A
B : C
    touch B
C :
    touch C

我特意寻找以下结果:

结果1 :当还没有文件存在时,make A应该像以前一样创建所有文件。

$ make A
touch C
touch B
touch A

结果2 :当C已过期时,make B应像之前一样更新B.这意味着我们在B和C之间不能有order-only dependency(即B : | C)。假设所有文件都存在:

$ touch C
$ make B
touch B    # Good. Don't loose this property.

结果3 :当C过期时,make A应为无操作,无需额外标记。

$ touch C
$ make A
make: `A' is up to date.

2 个答案:

答案 0 :(得分:4)

换句话说, 在决定是否重建A时, make 应该忽略B的时间戳。 换一种说法, B不是A的先决条件。 只需在B的相关系列中关闭A即可。

虽然阅读了你的答案,但如果它已经存在,你似乎想要建立B

A: $(if $(wildcard B),,B)
    ⋮

答案 1 :(得分:1)

这是一个解决方案。检查B是否明确存在,如果不是,则以递归方式调用make

A :
    @if [ ! -f B ]; \
        then $(MAKE) --no-print-directory B && echo touch A && touch A; \
    fi
B : C
    touch B
C :
    touch C

它有效,但我希望只使用Makefile指令的解决方案,而不是shell脚本。

$ make A
touch C
touch B
touch A
$ touch C
$ make B
touch B
$ touch C
$ make A
make: `A' is up to date.