Makefile目标依赖关系不成立

问题描述

#!make

.PRECIoUS: a/b/c/%_pqr
a/b/c/%_pqr:
        echo $@
        touch $@

.PRECIoUS: a/b/c/%_abc
a/b/c/%_abc: a/b/c/pqr_pqr
        echo $@
        touch $@

当我第一次运行时,它尊重它的依赖性:

make a/b/c/pqr_abc -f 1.mk
echo a/b/c/pqr_pqr
a/b/c/pqr_pqr
touch a/b/c/pqr_pqr
echo a/b/c/pqr_abc
a/b/c/pqr_abc
touch a/b/c/pqr_abc

但是,如果我删除“ a / b / c / pqr_pqr”文件,然后再次运行此目标,则它并不需要做

rm -f a/b/c/pqr_pqr; make a/b/c/pqr_abc -f 1.mk
make: `a/b/c/pqr_abc' is up to date.

根据我的理解,它应该再次运行两个目标。 请有人帮我。

解决方法

两个目标都是隐式的,因此是中间的。根据{{​​3}}:

第一个区别是如果中间文件不存在会发生什么。 [...]但是,如果b是中间文件,则make可以单独放置。除非更新b的某些先决条件或有其他原因更新该目标,否则不会麻烦更新b或最终目标。

因此,由于 pqr_abc 已经存在,并且 pqr_pqr 是中间文件,没有任何先决条件(因此,先决条件没有变化),因此将不会重新生成它。

根据制造商的理解,只需创建 pqr_pqr 即可从中生成 pqr_abc (这是中间文件的定义),并且由于 pqr_abc 已经存在,无需重新生成它。

如果您希望每次都重新生成该文件,则必须明确提及该文件,以便不再将其视为中间文件,即:

$ cat Makefile
a/b/c/%_pqr:
        touch $@

a/b/c/%_abc: a/b/c/pqr_pqr
        touch $@

a/b/c/pqr_pqr:

最后一行定义了显式目标,但没有定义配方,该配方仍将从隐式规则中调用。请注意,它将不再被认为是中间的,也不会被自动删除,因此也不需要.PRECIOUS指令。

输出:

$ make a/b/c/pqr_abc
touch a/b/c/pqr_pqr
touch a/b/c/pqr_abc

$ make a/b/c/pqr_abc
make: 'a/b/c/pqr_abc' is up to date.

$ rm a/b/c/pqr_pqr
$ make a/b/c/pqr_abc
touch a/b/c/pqr_pqr
touch a/b/c/pqr_abc