转载自:
Makefile中的%标记和系统通配符*的区别在于,*是应用在系统中的,%是应用在这个Makefile文件中的。
通配符%的意思是:
当没有目标test1.o时,我要找test1.o的构造规则,看看Makefile中那个规则符合。
然后找到了%.o:%.c,
来套一下来套一下:
%.o 和我要找的 test1.o 匹配
套上了,得到%=test1。
所以在后面的%.c就表示test1.c了。
OK进行构造
而通配符*的意思是:
我不知道目标的名字,系统该目录下中所有后缀为.c的文件都是我要找的。
然后遍历目录的文件,看是否匹配。找出所有匹配的项目。
下面是几个特殊符号的意思:
$@:目标的名字
$^:构造所需文件列表所有所有文件的名字
$<:构造所需文件列表的第一个文件的名字
$?:构造所需文件列表中更新过的文件 ———— 编译时工程中有部分文件被修改过的情况
$(@D)
表示"$@"的目录部分(不以斜杠作为结尾) ,如果"$@"值是"dir/foo.o",那么"$(@D)"就
是"dir",而如果"$@"中没有包含斜杠的话,其值就是"."(当前目录) 。
$(@F)
表示"$@"的文件部分,如果"$@"值是"dir/foo.o",那么"$(@F)"就是"foo.o","$(@F)"相
当于函数"$(notdir $@)"
例如:
1 test1.o:test1.c
2 gcc -o $@ $<
$@:就是test1.o
$<:就是test1.c
1 test1.o:test1.c head.c
2 gcc -o $@ $^
$^:就是test1.c head.c
$(subst 要被替换的字符串,用来替换的字符串,被处理的字符串):
用“用来替换的字符串”替换“被处理的字符串”中的“要被替换的字符串”
所以:
$(subst .c,.o,test1.c test2.c)
就会得到test1.o test2.o
$(wildcard 寻找的文件):
在系统中寻找文件
例如:
$(wildcard *.c)
在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard”,它的用法是:$(wildcard PATTERN...) 。在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空。
一般我们可以使用“$(wildcard *.c)”来获取工作目录下的所有的.c文件列表。复杂一些用法;可以使用“$(patsubst %.c,%.o,$(wildcard *.c))”,首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表。
例如:test1.c test2.c test3.c 这样
$(basename 文件名):
取得文件的名字(去掉后缀的意思)
例如:
$(basename test1.c)
就会取得test1