我在makefile中有这样的规则:
target : dependencies
rm -rd somedirectory
runcodecoverage.exe # this generates somefile
$(eval COVERAGE=$(shell grep "blah" somefile))
@echo $(COVERAGE)
当我第一次运行此文件时(清洁后),回声不会打印任何内容。但是在第二次和之后,它会打印出正确的结果。如果我用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)
似乎$(eval)一旦被" target"替换为grep的结果。目标已输入,即使我希望它在runcodecoverage.exe运行后运行。从这个意义上说,我认为正确的答案是不对的 - 文档在变量扩展中说这个:
规则定义
规则总是以相同的方式扩展,无论形式如何:
立即:立即;延期的 推迟答案 0 :(得分:1)
The eval
function并不像您认为的那样工作。
第一次运行Make时,它会扩展eval
函数并在执行任何规则之前执行变量赋值。由于没有somefile
,{ {1}}不返回任何内容,grep
保持为空。当Make执行规则时,它会将空变量传递给COVERAGE
,它会及时报告任何内容。
第二次运行Make时,它再次展开echo
函数,执行eval
grep
(在第一次运行中构建),并将结果存储在somefile
。然后它执行规则并将COVERAGE
传递给COVERAGE
,然后将其放在屏幕上。
答案 1 :(得分:1)
解析Makefile时$(eval ...)
运行,而不是在执行配方时运行。
我不清楚你期望发生什么;在配方中设置Make变量似乎不是一种可持续的方法,但它在很大程度上取决于您需要使用此变量的位置和方式。如果您只需要输出同一配方的覆盖范围,请用
替换最后几行grep "blah" somefile