5. 模式规则
模式规则是在规则中使用百分号(%)通配符 来代替显示规则的一种方式,他可以制作显式规则的模版。让多个规则总结为一个规则的方法。
我们之前定义多个显式规则,使用显式规则可以自定义每一个规则执行的命令,当然文件比较多时,规则也就相应的增多,代码量会变大。
如下:
main.o : main.c $(HEADERS)
gcc -o $@ -c $<
file1.o : file1.c $(HEADERS)
gcc -o $@ -c $<
file2.o : file2.c $(HEADERS)
gcc -o $@ -c $<
如果文件比较多的时候,我们可以使用隐含规则,但隐含规则只能匹配默认的几种规则,且不能够自定义命令的格式。此时使用模式规则可以解决上述问题。
模式规则的语法:
目标文件模式 : 依赖文件模式
<制表符> 命令1
<制表符> 命令2
...
说明:
- 目标文件模式 和 依赖文件模式 需要使用百分号通配符来表示文件的模式和匹配样式。
例如,上述模式可以改写成
%.o : %.c $(HEADERS)
gcc -o $@ -c $<
echo "compiling $@, % is $* ..."
此模式规则中 %.o 表示以任何 .o 结尾的目标文件。%.c 是和目标同名且以 .c 结尾的文件。此时的 % 匹配非空的文件名,且文件名一定相同。即 %.o 匹配 file1.o 时,%.c 一定匹配 file1.c。
在模式匹配中,使用自动变量 $* 可以获取通配符 % 匹配的字符串。
改写后的 Makefile 如下:
.PHONY: all clean
SOURCES := file1.c file2.c main.c
HEADERS := file1.h file2.h
OBJECTS := file1.o file2.o main.o
TARGET := myapp
# 修改隐含规则的变量,更改编译命令
CC = gcc
CFLAGS = -g -Wall
all: $(TARGET) # 编译最终目标
$(TARGET) : $(OBJECTS)
gcc -o $@ $^
# 自定义模式规则
%.o : %.c $(HEADERS)
gcc -o $@ -c $<
echo "compiling $@, % is $* ..."
clean: # 清除目标文件
rm $(OBJECTS)
make 的执行结果如下:
weimz@anonymous myapp % make
gcc -o file1.o -c file1.c
echo "compiling file1.o, % is file1 ..."
compiling file1.o, % is file1 ...
gcc -o file2.o -c file2.c
echo "compiling file2.o, % is file2 ..."
compiling file2.o, % is file2 ...
gcc -o main.o -c main.c
echo "compiling main.o, % is main ..."
compiling main.o, % is main ...
gcc -o myapp file1.o file2.o main.o
从上述执行结果可以看出,使用模式规则可以代替隐含规则并能够自定义任何通用规则,使用 $* 可以获取每次匹配的字符串。
实验:
尝试在自己的 Makefile 中使用模式规则。