简体   繁体   English

Makefile 目标依赖不兑现

[英]Makefile target dependency not honored

#!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 $@

When I run first time, it honors its dependency:当我第一次运行时,它尊重它的依赖性:

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

But if I delete "a/b/c/pqr_pqr" file and then run this target again, it doesn't do the needful:但是如果我删除“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.

As per my understanding, it should run both targets again.据我了解,它应该再次运行两个目标。 Please somebody help me.请有人帮助我。

Both your targets are implicit and therefore intermediate.您的两个目标都是隐含的,因此是中间的。 As per documentation :根据文档

The first difference is what happens if the intermediate file does not exist.第一个区别是如果中间文件不存在会发生什么。 [...] But if b is an intermediate file, then make can leave well enough alone. [...] 但是如果 b 是一个中间文件,那么 make 可以单独留下。 It won't bother updating b, or the ultimate target, unless some prerequisite of b is newer than that target or there is some other reason to update that target.它不会更新 b 或最终目标,除非 b 的某些先决条件比该目标更新,或者有其他原因需要更新该目标。

Therefore since pqr_abc already exists and pqr_pqr is an intermediate file and has no prerequisites (so no prerequisites have changed), it will not be regenerated.因此,由于pqr_abc已经存在并且pqr_pqr是一个中间文件并且没有先决条件(因此没有先决条件发生变化),因此不会重新生成。

As per make's understanding pqr_pqr would need to be created only to generate pqr_abc from it (this is the definition of intermediate file), and since pqr_abc already exists, there is no need to regenerate it.根据 make 的理解,只需要创建pqr_pqr以从中生成pqr_abc (这是中间文件的定义),并且由于pqr_abc已经存在,因此无需重新生成它。

If you want the file to be regenerated every time, it has to be mentioned explicitly, so that it is no longer considered an intermediate file, ie:如果你希望每次都重新生成文件,则必须明确提及,以便不再将其视为中间文件,即:

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

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

a/b/c/pqr_pqr:

The last line defines explicit target, but it does not define recipe, which will still be invoked from implicit rule.最后一行定义了明确的目标,但没有定义食谱,它仍然会从隐式规则中调用。 Note that it will no longer be considered intermediate and will not be automatically removed, so .PRECIOUS directives are also not needed.请注意,它将不再被视为中间值,也不会自动删除,因此也不需要.PRECIOUS指令。

Output: Output:

$ 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM