根据make更新target的时机(一)中的总结,对流程图的中每个分支设置适当的实验场景,进行验证。
- 当目标t是伪目标的时候,无论是否存在名为t的文件,规则t都一定执行。
- t 依赖 p,且有匹配 p 的规则, 且 p 是伪目标时,
无条件执行 p,接着执行 t
无论文件p是否存在,无论文件 t 是否比文件 p 新。 - t 依赖 p,且有匹配 p 的规则, 且 p 不是伪目标
有文件 p | 没有文件 p | |
---|---|---|
p 执行 | 比较p和t | t 需要执行 |
p 不执行 | 比较p和t | -(没有文件p,p一定会执行) |
01. 更新 target 的时机
01.1 target 是伪目标或文件 target 不存在,无条件执行 target
[chenx@lcs2 01]$ ls -a
. .. makefile
[chenx@lcs2 01]$ cat makefile
# target 是伪目标或文件 target 不存在,无条件执行 target
t1:
touch t1
t2:
touch t2
.PHONY: t2 clean
clean:
rm -vf t1 t2
[chenx@lcs2 01]$ make t1
touch t1
[chenx@lcs2 01]$ make t1
make: 't1' is up to date.
[chenx@lcs2 01]$ make t2
touch t2
[chenx@lcs2 01]$ make t2
touch t2
[chenx@lcs2 01]$ ls
makefile t1 t2
01.2 t 依赖文件 p,且没有匹配 p 的规则
若不存在文件p,则报错;
若存在p,则当p比t新的时候执行t,否则不执行t。
[chenx@lcs2 02]$ ls -a
. .. makefile
[chenx@lcs2 02]$ cat makefile
#依赖文件 p,且没有匹配 p 的规则
# 若不存在文件p,则报错;
# 若存在p,则当p比t新的时候执行t,否则不执行t。
t: p
touch t
[chenx@lcs2 02]$ make t
make: *** No rule to make target `p', needed by `t'. Stop.
[chenx@lcs2 02]$ touch p
[chenx@lcs2 02]$ make t
touch t
[chenx@lcs2 02]$ make t
make: `t' is up to date.
01.3 t 依赖 p,且有匹配 p 的规则, 且 p 是伪目标
无条件执行 p,接着执行 t
无论文件p是否存在,无论文件 t 是否比文件 p 新。
[chenx@lcs2 03]$ ls -a
. .. makefile
[chenx@lcs2 03]$ cat makefile
# t 依赖 p,且有匹配 p 的规则, 且 p 是伪目标
# 无条件执行 p,接着执行 t
t: p
touch t
p:
@echo execute recipe of p
.PHONY: p clean
clean:
rm -vf t p
[chenx@lcs2 03]$ make t
execute recipe of p
touch t
[chenx@lcs2 03]$ make t
execute recipe of p
touch t
[chenx@lcs2 03]$ ls
makefile t
[chenx@lcs2 03]$ touch p
[chenx@lcs2 03]$ make t
execute recipe of p
touch t
01.4 t 依赖 p,且有匹配 p 的规则, 且 p 不是伪目标
有文件 p 没有文件 p
p 执行 比较p和t t 需要执行
p 不执行 比较p和t -(没有文件p,p一定会执行)
[chenx@lcs2 04]$ ls
makefile
[chenx@lcs2 04]$ ls
makefile
[chenx@lcs2 04]$ cat makefile
# t 依赖 p,且有匹配 p 的规则, 且 p 不是伪目标
#
# 有文件 p 没有文件 p
# p 执行 比较p和t t 需要执行
# p 不执行 比较p和t -(没有文件p,p一定会执行)
t: p
touch t
p:
@echo execute recipe of p
clean:
rm -vf t p
.PHONY: clean
# 1. 没有文件 p -> p 需要执行,t 需要执行
[chenx@lcs2 04]$ make t
execute recipe of p
touch t
[chenx@lcs2 04]$ make t
execute recipe of p
touch t
# 2. 有文件 p -> p 不执行,t是否需要执行,根据 p 和 t 的新旧关系判断
[chenx@lcs2 04]$ touch p
[chenx@lcs2 04]$ touch t # t 比 p 新
[chenx@lcs2 04]$ make t
make: `t' is up to date.
[chenx@lcs2 04]$ touch t; touch p # p 比 t 新
[chenx@lcs2 04]$ make t
touch t
[chenx@lcs2 04]$ make t
make: `t' is up to date.
# 用 t,p,d 构造最后一种场景:
# 3. 有文件 p,p 需要执行 -> t是否需要执行,看 p 和 t 的新旧关系。
t: p
touch t
p: d
@echo execute recipe in p
clean:
rm -vf p t
.PHONY: clean
[chenx@lcs2 05]$ touch d
[chenx@lcs2 05]$ touch t
[chenx@lcs2 05]$ touch p
[chenx@lcs2 05]$ touch p # 有文件p,p需要执行,p 比t新
[chenx@lcs2 05]$ touch d
[chenx@lcs2 05]$ make t
execute recipe in p
touch t
[chenx@lcs2 05]$ # 有文件 p,p需要执行,p 不比 t 新
[chenx@lcs2 05]$ make t
execute recipe in p
[chenx@lcs2 05]$ make t