Makefile中的一些神奇用法

本文主要讲Makefile中的三个函数:
1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符

前言

今天在读工程代码的时候无意间看到这样几行代码,大概意思猜出来了,但是说实话确实没注意过这样的用法,于是google一番,豁然开朗。

写一个例子看一下

先创建一下目录

.
├── a
│   ├── aa.c
│   ├── ab.c
│   └── ac.c
├── a.c
├── b.c
└── c.c

vim Makefile 并写入一下内容

1
2
3
4
5
6
7
8
1 SRC=$(wildcard *.c ./a/*.c)                                                 
2 DIR=$(notdir $(SRC))
3 OBJ=$(patsubst %.c, %.o, $(SRC))
4
5 all:
6     @echo $(SRC)
7     @echo $(DIR)
8     @echo $(OBJ)

执行make查看运行结果

a.c b.c c.c ./a/aa.c ./a/ab.c ./a/ac.c
a.c b.c c.c aa.c ab.c ac.c
a.o b.o c.o ./a/aa.o ./a/ab.o ./a/ac.o

分析执行过程

通过第一行的输出可以看出,wildcard的作用是用后边的通配符去匹配文件名。

通过第二行的输出可以看出,notdir的作用是省略掉文件名中的路径信息,只保留最后的文件名称。

通过第三行的输出可以看出,patsubst的作用是把$SRC中所有的.c文件名修改为.o

‘%’(百分号)表示匹配任意长度的子串

扩展

此外还有几种方法效果和 OBJ=$(patsubst %.c, %.o, $(SRC))一样

Makefile中的变量替换引用

1
OBJ=$(SRC:.c=.o)

Makefile中的自动推导规则

1
2
%.o:%.c
  gcc -c -o $@ $^

最后给出全部代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
1 SRC=$(wildcard *.c ./a/*.c)                                                 
2 DIR=$(notdir $(SRC))
3 #OBJ=$(patsubst %.c, %.o, $(SRC))
4 OBJ=$(SRC:.c=.o)
5
6 %.o:%.c
7     @echo $@
8     @echo $^
9     @gcc -c -o $@ $^
10
11 all:$(OBJ)
12     @echo $(SRC)
13     @echo $(DIR)
14     @echo $(OBJ)
15
16 clean:
17     rm -rf $(OBJ)

运行输出

a.o
a.c
b.o
b.c
c.o
c.c
a/aa.o
a/aa.c
a/ab.o
a/ab.c
a/ac.o
a/ac.c
a.c b.c c.c ./a/aa.c ./a/ab.c ./a/ac.c
a.c b.c c.c aa.c ab.c ac.c
a.o b.o c.o ./a/aa.o ./a/ab.o ./a/ac.o