我在一个类Unix系统上使用GNU Make(3.81),而且遇到一个问题,$(通配符,模式)函数无法找到由(大概/明显的)先前执行的配方生成的文件,而其他程序(例如ls)能够验证其存在.我想知道为什么通配符函数不会返回任何东西,当它被扩展(到空字符串)时,以及我如何找到生成的文件.
测试用例:
以下测试用例说明了该问题.
Makefile内容:
.PHONY: build clean test: @echo "Creating test file 'test'." @echo "this is a test file" > test build: test @echo "Directory contents:" @ls @echo "Test file contents:" @cat test @echo "Wildcard output:" @echo $(wildcard test) clean: @rm -f test
运行makefile两次(然后清理)显示只有在第二次运行时它会检测到创建的文件.
输出:
Creating test file 'test'. Directory contents: makefile test Test file contents: this is a test file Wildcard output: Directory contents: makefile test Test file contents: this is a test file Wildcard output: test
复制:
将makefile保存在一个空目录中,然后运行“make build; make build; make clean”.
研究:
处理目标的先决条件的顺序为independent of the order in which they appear in the list after the colon,因此如果要定义处理它们的顺序,则必须引入明确的先决条件依赖关系.
但是,我不认为我可以再剥离依赖;构建取决于测试,测试对应于不存在且由其配方生成的文件.我认为在制作的配方被处理的时候会出现.
从我对如何解析makefile的了解,配方中的通配符功能不应该被扩展,直到它被处理.
然而,我清楚地看到了内置的make功能的输出和通过shell访问的通用实用程序的输出之间的差异,所以这个推测可能是错误的,但是我没有遇到任何关于什么应该是在这里发生,甚至不在GNU手册中.
注:这个问题的目的只是为了了解与这个问题有关的通配符功能的运作情况;有一个实际的用例,我把这个浇水版本翻译出来,但我对这个案子更感兴趣.
解决方法
关于您的陈述,即先决条件的处理顺序:技术上,GNU对订单不作任何保证,但实际上,这些prereq是从左到右处理的,尽管纯粹主义者试图改变(仅为了拧紧目的)与没有完全指定依赖关系的人),GNU所做的实际改变实现细节的可能性是非常小的.但是,您只能在串行版本中真正依赖该顺序.如果您并行运行构建,那么事情会变得更棘手:GNU make仍然按照从左到右的顺序处理prereq,但是在开始下一步之前不再等待完成,所以实际上可能会出现以随机或“任何”的顺序进行处理,受到prereq依赖之间的限制,这就是为什么指定这些依赖关系的良好做法.