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

可以看到能成功执行了

相关推荐
东风破_10 小时前
从跨域到 WebSocket:前端跨域方案、SSE 与双向实时通信详解
前端·后端
行百里er11 小时前
Gateway 上别硬塞 MVC:DeferredImportSelector 看菜下锅
spring boot·后端·开源
名字还没想好☜11 小时前
Java 遍历时删元素抛 ConcurrentModificationException:fail-fast 原理与三种正确删法
后端
IT_陈寒12 小时前
React Hooks闭包陷阱差点让我加班到凌晨
前端·人工智能·后端
码事漫谈13 小时前
本体论,彻底懂
后端
创新技术阁13 小时前
FastapiAdmin 系统日志体系与核心配置参数详解
前端·后端·fastapi
掘金者阿豪13 小时前
SQL Server 迁到金仓,真正麻烦的不是数据,而是这些 T-SQL
后端
Kyrie_kk13 小时前
Java--IO--Path文件访问
java·后端
wxwx_bscxy32214 小时前
基于springboot宠物领养系统的设计与实现
数据库·spring boot·后端·spring·宠物
分支预测失败14 小时前
RISC-V AIA 中断架构实战:从 PLIC 到 APLIC 与 IMSIC 的迁移
linux·后端