全部学习汇总: https://github.com/GreyZhang/g_makefile
关于这部分本来是想先看例子,查阅了部分资料之后觉得这部分的分析从文档本身开始比较合适一些。

首先看一下这一段文档,针对这段文档可以梳理出来几条比较有用的知识小结。1,首先注意一下这个用法的基本语法格式以及每一部分的具体功能,由此对这个表述形式的功能做出一个小结:每一个与目标模式相匹配的目标都会被提取出来名称中的一部分,这部分称为stem,将stem替换到每一个依赖匹配中用以推导出依赖文件。2,每一个匹配模式一般只包含一个%,如果是用来处理target,%可以用来匹配名字中的任意部分,但是非%得部分应该百分百匹配。3,除了第1条中总结出来的替换规则,还有另一个可能性:依赖规则中没有%,这样所有的target的依赖文件都是相同的。这种表达依然合法。4,如果想在匹配模式中匹配%字符,可以加上一个\实现。如果不想\%被解析成%符号本身而是可以匹配那么使用\\%。但是,这里并不是说\\是\的转义用法,如果想用两个\直接输入\\即可。
接下来看几个例子。
CC := gcc
objects = foo.o bar.o all.o
all: $(objects)
# These files compile via implicit rules
foo.o: foo.c
bar.o: bar.c
all.o: all.c
all.c:
echo "int main() { return 0; }" > all.c
%.c:
touch $@
clean:
rm -f *.c *.o all
首先,这个是一个之前大概看过的表达模式。唯一不同的是在于通配符使用上,使用%.c来处理默认的C代码的target。这里之所以说是默认,暂时没有找到文档一句,跟我测试的结论有一定的关系。在下一个对比例子中能够做一个更好的对比阐明。
CC := gcc
objects = foo.o bar.o all.o
all: $(objects)
# These files compile via implicit rules
# Syntax - targets ...: target-pattern: prereq-patterns ...
# In the case of the first target, foo.o, the target-pattern matches foo.o and sets the "stem" to be "foo".
# It then replaces the '%' in prereq-patterns with that stem
$(objects): %.o: %.c
all.c:
echo "int main() { return 0; }" > all.c
%.c:
touch $@
clean:
rm -f *.c *.o all
这是上面的Makefile的另外一种表达方式,使用了静态匹配模式规则。我之前写过一个非常简单粗暴地Makefile的生成工具中,这方面就是一个很好的改进点。如果能够用这种规则处理,Makefile的简洁度会增加很多。然而,既然都已经自动生成了,是否简洁也就不算是一个特别需要关注的地方了。这个例子的运行效果跟前面一样,效果如下:

通过这个例子,其实是能够看出我前面所测试得出来的一个结论的。那就是,通过模糊匹配的这种方式跟之前我进行target重名测试的时候出现的方式不同。按理说,%.c可以匹配全部的C文件,all.c也会被加入进来进行第二次处理。这样应该会出现一个target的重名,如果检测到重名,应该跟之前的测试一样出现一个警告。这里并没有出现警告,加上一个echo输出提示进行对比也可以发现其实有了all.c这部分就会忽略对all.c的处理。看上去像是all.c的处理有着更高的优先级而且会取消掉后续的模糊匹配的表达。
本文详细解读Makefile中的模糊匹配机制,重点介绍%.c规则的应用,以及如何通过stem替换依赖。通过实例分析,探讨了如何避免target重名问题和提升特定文件处理优先级。
1100

被折叠的 条评论
为什么被折叠?



