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.
答案 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.