前言
如果我们想定义一系列比较类似的文件,我们很自然地就想起使用通配符。make 支持三种通配符:"*","?" 和 "[...]"。这和 Unix 的 B-Shell 是相同的。
本篇主要讲述 "*" 通配符在变量中使用失效时,使用 wildcard 函数使能 "*" 通配符的通配功能。
1 "*"通配符使用场景
(1) 在命令中使用"*";
clean: rm -f *.o
这是操作系统 Shell 所支持的通配符,删除当前目录下的所有以 .o 结尾的文件。
这是在命令中的有效通配符,通配所有 .o 文件的集合。
(2) 在规则中使用"*";
print: *.c lpr -p $? touch print
上面这个例子说明通配符 "*" 也可以在我们的规则中使用,目标 print 依赖于所有的 .c 文件。
(3) 在变量中使用"*";
objects = *.o
上面这个例子,表示了通配符 "*" 同样可以在变量中使用。
但是 *.o 在变量中不会展开,objects 的值就是 *.o。Makefile 中的变量其实就是 C/C++ 中的宏。如果希望通配符 "*" 在变量中展开,也就是让 objects 的值是所有 .o 的文件名的集合,那么需要 wildcard 函数的配合。
objects := $(wildcard *.o)
这样,objects 的值就是所有 .o 的文件名的集合。
2 "*"通配符实例
这里我创建了 source_dir 目录和三个子目录: gpio、irq、usart。三个子目录中都有对应的 .c 文件。
$(foreach source, $(SOURCE_DIR), $(wildcard $(source)/*.c))
上面的例子中,$(SOURCE_DIR) 中的单词会被挨个取出,并存到变量 source 中,(wildcard $(source)/*.c) 每次根据 $(source)/*.c 计算出一个值(因为使用了 wildcard,所以匹配单词目录下 .c 文件集合),这些值以空格分隔,最后作为 foreach 函数的返回值。
对于 foreach 函数不理解的同学,可以参考:
本例程的最终目的,是将各子目录下的 .c 文件(可编译文件)列举出来。
总结
通配符 "*" 只有在命令和规则中使用它才会展开,如果在定义变量和函数中使用时,通配符 "*" 不会自动展开,这个时候就需要函数 wildcard 的配合使用。