Makefile在第二次运行时产生不同的结果

Makefile在第二次运行时产生不同的结果,makefile,gnu-make,Makefile,Gnu Make,我在makefile中有这样一个规则: target : dependencies rm -rd somedirectory runcodecoverage.exe # this generates somefile $(eval COVERAGE=$(shell grep "blah" somefile)) @echo $(COVERAGE) 当我第一次运行此文件时(在进行清理之后),echo不会打印任何内容。但是第二次和第二次之后,它会打印出正确的结果。如果我用gr

我在makefile中有这样一个规则:

target : dependencies
   rm -rd somedirectory
   runcodecoverage.exe # this generates somefile
   $(eval COVERAGE=$(shell grep "blah" somefile))
   @echo $(COVERAGE)
当我第一次运行此文件时(在进行清理之后),echo不会打印任何内容。但是第二次和第二次之后,它会打印出正确的结果。如果我用
grep“blah”somefile
替换$(eval..)行,我会得到我想要的结果,所以问题一定是$(eval)和$(shell)的使用。为什么会这样

编辑:我通过添加一个新的依赖项解决了这个问题,所以现在看起来像这样:

generatesomefile : 
   runcodecoverage.exe # this generates somefile

target : dependencies generatesomefile
   rm -rd somedirectory
   $(eval COVERAGE=$(shell grep "blah" somefile))
   @echo $(COVERAGE)
似乎只要输入“target”目标,就会用grep的结果替换$(eval),尽管我希望它在runcodecoverage.exe运行之后运行。从这个意义上说,我认为正确的答案并不完全正确——文档中关于变量扩展的描述如下:

规则定义

规则总是以相同的方式展开,无论其形式如何:

即时:即时;推迟 延迟的

不能像你想象的那样工作

第一次运行Make时,它会展开
eval
函数,并在执行任何规则之前执行变量赋值。由于没有
somefile
,因此
grep
不返回任何内容,而
COVERAGE
保持为空。当Make执行规则时,它将空变量传递给
echo
,echo将不报告任何内容

第二次运行Make时,它再次展开
eval
函数,在
somefile
上执行
grep
(第一次运行时构建),并将结果存储在
COVERAGE
中。然后,它执行规则并将覆盖范围传递给将其显示在屏幕上的echo。

解析生成文件时,而不是执行配方时,
$(eval…
运行

我不清楚你期望发生什么;从配方中设置Make变量似乎不是一种可持续的方法,但这在很大程度上取决于您需要在何处以及如何使用该变量。如果您只需要输出同一配方中的覆盖率,那么将最后几行替换为

grep "blah" somefile

啊。我需要停止把make当作一种编程语言。