makefile - 为什么 gnu make 忽略模式规则的缺失依赖项?
问题描述
一个最小的例子:
%.bar: missing_file.pckl
@echo executed
当我键入make foo.bar
时,make
说“无事可做”。为什么?missing_file.pckl
不存在,也没有规则。这不应该引发错误吗?(我知道您可以通过将规则设为静态来规避这一点 - 我只是想了解其中的原因。)
在旁注 - 我试图make
更好地理解背后的逻辑 - 模式规则和隐式规则之间有什么区别(这些术语似乎可以互换使用)?模式规则不能被伪造的原因是什么?我读到隐式规则旨在生成文件 - 但对我来说,对虚假目标使用模式规则同样有意义。
谢谢!
解决方案
模式规则是一种隐含规则。但后缀规则也是隐含规则。
makefile 中有两种基本类型的规则:显式规则和隐式规则。显式规则由显式目标的规则和静态模式规则组成(这绝对令人困惑,“静态模式规则”实际上是显式的,但它们是:它们只是编写大量显式规则的简写)。隐式规则由模式规则和后缀规则组成。
将隐式规则视为模板。它实际上根本没有定义任何目标。它仅提供如何创建目标(与模式/后缀匹配)的模板。如果您的 makefile 仅包含隐式规则,那么当您键入时make
它不会做任何事情,因为您的 makefile 实际上并没有定义任何目标......它只是创建了模板。
重要的是要了解可以构建相同目标的许多模板。甚至内置的 make 规则也提供了许多不同的方法来构建目标文件,例如:使用 C 编译器、C++ 编译器、FORTRAN 编译器等。用户可以添加自己的。
如果没有为目标找到显式规则,则 make 将开始搜索隐式规则。它可能会查看其中的许多内容,并且您肯定不希望看到每个不匹配的错误或消息!
这几乎可以回答您所有的问题,但总结一下:
您收到此消息的原因是 make 搜索了所有可用于构建该目标的隐式规则,但没有找到可以使用的规则(您提供的规则不起作用,因为先决条件不存在...但是 make 不认为这是一个错误,因为它只是构建目标的一种方式。人们实际上有时会使用这个非常方便的功能!!)所以它说,“我不知道如何构建那个目标” .
当然,make 可以在这里生成更多细节。它可以说“哦,我碰巧知道只有一个隐式规则可以匹配,所以我可以更具体地说明为什么那个规则不起作用并说缺少先决条件”。但是,如果您有两个可能匹配的隐式规则,那将是令人困惑的。或者,它可以列出它找不到的所有可能的先决条件。或者其他的东西。我不确定这些中的任何一个是否真的会总体上有所改进。它们在某些情况下会更好,而在其他情况下会超级烦人。
您不能应用于.PHONY
模式规则的原因是模式规则不是目标。当然,合理的增强是允许.PHONY
采用一种模式,然后将虚假应用到与该模式匹配的所有目标。但是,无论出于何种原因,该增强功能都没有实施。
推荐阅读
- sql - 如何从 IF ELSE 存储过程中的表中选择多个列
- kubernetes - 我想用用户名和密码在 Kubernetes 中创建一个用户。我尝试使用谷歌搜索,但只能找到使用证书密钥创建用户
- javascript - Vue 在与窗口宽度相关的条件下表现得很奇怪
- azure - 使用 Azure FrontDoor 按比例平衡 2 个 API 终结点
- docker - 使用 Github Actions 将 docker 镜像从 Github 注册表部署到 Digital Ocean droplet
- python - 如何将三个列表转换为字典,其中键取自前两个列表的笛卡尔积,值来自第三个列表
- javascript - 拒绝承诺时如何将状态码设置为 404
- javascript - 检查下一项是否长 1 个单位(Javascript)
- python - 获取脚本的名称以自动传递给模块函数
- kotlin - Ktor 与 Kmongo 和 kotlinx.serialization