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

可以看到能成功执行了

相关推荐
想打游戏的程序猿20 小时前
核心概念层——深入理解 Agent 是什么
后端·ai编程
woniu_maggie21 小时前
SAP Web Service日志监控:如何用SRT_UTIL快速定位接口问题
后端
一线大码21 小时前
Java 使用国密算法实现数据加密传输
java·spring boot·后端
Rust语言中文社区21 小时前
【Rust日报】用 Rust 重写的 Turso 是一个更好的 SQLite 吗?
开发语言·数据库·后端·rust·sqlite
在屏幕前出油1 天前
06. FastAPI——中间件
后端·python·中间件·pycharm·fastapi
wuqingshun3141591 天前
说一下spring的bean的作用域
java·后端·spring
钟智强1 天前
从2.7GB到481MB:我的Docker Compose优化实战,以及为什么不能全信AI
后端·docker
华科易迅1 天前
Spring JDBC
java·后端·spring
小村儿1 天前
一起吃透 Claude Code,告别 AI 编程迷茫
前端·后端·ai编程
程序员大飞哥1 天前
云控SLA的数学:250ms端到端延迟预算怎么分配给传输层
后端