Makefile 显式规则和隐式规则

最近在使用Makefile的过程中发现了一个很有意思的现象,现在抽象一个简单的例子来展示这个现象

Makefile内容如下

makefile 复制代码
% : %.in
	echo $<
	echo $@

文件列表如下:

makefile 复制代码
total 4.0K
-rw-rw-r-- 1 raid raid  0 Oct 28 18:23 aa.stage.in
-rw-rw-r-- 1 raid raid  0 Oct 28 18:09 cc.sh.in
-rw-rw-r-- 1 raid raid  0 Oct 28 18:23 d.c.in
-rw-rw-r-- 1 raid raid 29 Oct 28 18:09 Makefile

执行:

shell 复制代码
➜  22 make aa.stage
echo aa.stage.in
aa.stage.in
echo aa.stage
aa.stage
➜  22 make cc.sh
make: *** No rule to make target 'cc.sh'.  Stop.
➜  22

可以看到一个执行成功,一个执行失败,出现问题的原因是Makefile的匹配规则

make 的模式匹配算法在处理带有后缀的目标时,会优先寻找更具体的规则

shell 复制代码
➜ make -p 
...
# Not a target:
.w:
#  Builtin rule
#  Implicit rule search has not been done.
#  Modification time never checked.
#  File has not been updated.

# Not a target:
.SUFFIXES: .out .a .ln .o .c .cc .C .cpp .p .f .F .m .r .y .l .ym .yl .s .S .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo .w .ch .web .sh .elc .el

...

可以看到Makefile内置了这些后缀,也就是说Makefile认识这些后缀,当 make 看到一个目标文件以这些它认识的后缀结尾时,优先使用显式规则,所以可以看到make cc.sh的时候提示找不到cc.sh,因为确实没有cc.sh这个target,而make aa.stage的时候没问题,因为.stage 后缀Makefile不认识,走的还是模式匹配

通过-R可以取消Makefile使用的这些内置变量规则

go 复制代码
➜  22 make -R cc.sh
echo cc.sh.in
cc.sh.in
echo cc.sh
cc.sh

可以看到能成功执行了

相关推荐
北斗落凡尘7 分钟前
LangGraph 入门实战(7)
后端·langchain
uzong22 分钟前
业务新老系统数据迁移-负责人经验总结和复盘
后端
dogstarhuang1 小时前
大模型 API 停服怎么办:用 API 网关实现多模型统一接入与可切换架构
人工智能·后端·架构·大模型·api·数字化转型·ai应用
程序猿DD1 小时前
OctaFuse Gateway 2.5.0:接入 Responses 端点、更易理解的路由配置
后端·agent
nnerddboy3 小时前
Rust教程04:引用、借用与切片
开发语言·后端·rust
Rain的Java大神之路3 小时前
线上接口负载满了如何解决
java·数据库·redis·后端·缓存·面试·架构
weixin_431600444 小时前
NestJS 入门(7):生命周期钩子——构造函数和 `OnModuleInit` 差在哪?
前端·后端·学习·node.js·nest.js
小强库计算机毕业设计5 小时前
基于 Spring Boot + Vue3 的校园管理系统
java·spring boot·后端·项目实战·管理系统·技术分享·校园管理系统实战
canonical_entropy5 小时前
关于《Mission Driver:Loop Engineering 的一种通用参考实现》的补充说明
后端·agent·ai编程
__zRainy__5 小时前
Node系列 · Node基础:Node.js 概述
后端·node.js