make更新target的时机(二)实验验证

根据make更新target的时机(一)中的总结,对流程图的中每个分支设置适当的实验场景,进行验证。

  1. 当目标t是伪目标的时候,无论是否存在名为t的文件,规则t都一定执行。
  2. t 依赖 p,且有匹配 p 的规则, 且 p 是伪目标时,
    无条件执行 p,接着执行 t
    无论文件p是否存在,无论文件 t 是否比文件 p 新。
  3. 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
上一篇:【Linux】-文件处理命令-touch+cat+more+less+head+tail


下一篇:如何解决 MacBook Pro Touch ID不起作用?