make -B 始终打印 shell 任务的"is up to date"



考虑这个制作文件

test.txt: foo.bar
$(shell grep ^hello $< >$@)

要测试它,需要创建一个包含的文件foo.bar,例如,

hello
hello 2

make始终打印

make: 'test.txt' is up to date.

即使文件test.txt不存在,也会发生这种情况。在这种情况下,make 可以正确运行并创建test.txt,但仍会打印上述消息。即使使用make -B也会给出相同的信息。

我正在使用GNU Make 4.2.1。

为什么会有这种行为?

发生这种情况是因为它实际上是一个空配方,所以没有什么可运行的。

$(shell)函数在 Makefile 配方解析时进行评估,其输出被视为配方内容。碰巧此语句生成一个输出文件作为副产品,但语句的输出为空,因此make无关,并得出结论,目标是最新的。事实上,如果食谱结果是空的,它总是会这么说:

$ ls
Makefile  foo.bar
$ cat Makefile
test.txt: foo.bar
$(info Making $@ from $<)
$ make
Making test.txt from foo.bar
make: 'test.txt' is up to date.
$ ls
Makefile  foo.bar

请注意,上面的例子没有创建test.txtmake只是得出结论,它运行了(空(配方来更新它,所以现在它是最新的。

为了正确运行它,您应该完全删除$(shell)函数。make的配方已经在外壳中调用:

$ cat Makefile
test.txt: foo.bar
grep ^hello $< >$@
$ make
grep ^hello foo.bar >test.txt
$ make
make: 'test.txt' is up to date.
$ make -B
grep ^hello foo.bar >test.txt
$ ls
Makefile  foo.bar  test.txt

相关内容

最新更新