加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

GNU make通配符功能没有找到运行时生成的文件

发布时间:2020-12-16 07:52:25 所属栏目:百科 来源:网络整理
导读:概要: 我在一个类Unix系统上使用GNU Make(3.81),而且遇到一个问题,$(通配符,模式)函数无法找到由(大概/明显的)先前执行的配方生成的文件,而其他程序(例如ls)能够验证其存在.我想知道为什么通配符函数不会返回任何东西,当它被扩展(到空字符串)时,以及我如何
概要:
我在一个类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 make在执行任何命令之前扩展目标的所有命令.在这种情况下,“扩展”意味着“用它们的值替换所有变量引用(递归),并评估任何函数引用.”当然,$(通配符)是一个函数引用.由于在执行任何命令之前发生扩展,所以当然不能找到文件测试 – 它尚未创建.第二次运行构建时,测试已经存在,所以$(通配符)可以找到它.

关于您的陈述,即先决条件的处理顺序:技术上,GNU对订单不作任何保证,但实际上,这些prereq是从左到右处理的,尽管纯粹主义者试图改变(仅为了拧紧目的)与没有完全指定依赖关系的人),GNU所做的实际改变实现细节的可能性是非常小的.但是,您只能在串行版本中真正依赖该顺序.如果您并行运行构建,那么事情会变得更棘手:GNU make仍然按照从左到右的顺序处理prereq,但是在开始下一步之前不再等待完成,所以实际上可能会出现以随机或“任何”的顺序进行处理,受到prereq依赖之间的限制,这就是为什么指定这些依赖关系的良好做法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读