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

可以看到能成功执行了

相关推荐
砍材农夫3 分钟前
物联网实战:Spring Boot MQTT | 模拟器Paho客户端拆解核心点
java·javascript·网络·spring boot·后端·物联网
掘金者阿豪11 分钟前
用 Codex 的不会还不知道这些开源项目提效吧?
后端
我登哥MVP14 分钟前
Spring Boot 从“会用”到“精通”:自动装配原理
java·spring boot·后端·spring·tomcat·maven·intellij-idea
雪隐42 分钟前
AI股票小助手05-用 Flask 把 MiniQMT 变成 REST API
人工智能·后端
道友可好1 小时前
Spec Kit:GitHub 官方出品,规范即代码
前端·人工智能·后端
货拉拉技术1 小时前
货拉拉标注平台-拉拉标注
后端·架构
fox_lht1 小时前
第十四章 一个输入和输出项目:构建一个命令行程序
开发语言·后端·rust
fox_lht1 小时前
14.2.读文件
开发语言·后端·rust
用户3058759549311 小时前
Docker 环境下 MySQL 读写分离实践:ProxySQL + 主从复制
后端
用户298698530141 小时前
Java 操作 Word 文档:常见编辑功能实现
java·后端