通配符是指在操作系统中,用于代替其它字符或字符串的符号,可以匹配符合相应规则的文件或目录。即:可以使用通配符代表许多同种格式的文件。如:*.o 表示所有的.o文件
在命令行中,常用的通配符有以下几种:
1.* (星号):表示任意长度的任意字符(包括空字符),可以出现在文件名中的任意位置。
2. ? (问号):表示一个任意字符,且只能替代一个字符。
3. [] (中括号):可匹配其中某个指定字符,可以出现在文件名中的任意位置,如 [abc] 表示可以匹配 a、b、c 中任意一个字符。
4. {} (花括号):可使用逗号隔开的多个字符串中的一个。例如 {a,b,c} 表示可以匹配字符串 a、b、c 中的任意一个。
这些通配符的使用方法类似,都是在命令行中直接使用。使用通配符可以方便地批量操作文件,如删除、复制等。
首先说说‘%’,在Linux中,`%`不是通配符,而是一种特殊的替换符号,在一些命令或脚本中可以使用。
在`make`命令中,`%`可以匹配任意字符序列,用于表示规则中的通配符,如`%.o`可以匹配所有以`.o`为后缀的文件名。这样就可以很方便地使用单一规则来生成多个目标文件。
例如,在下面的规则中,`%.o`表示所有的`.o`文件:
```
%.o : %.c
gcc -c $<
```
其中,`$<`代表依赖项中第一个文件的名称,也就是与这个`.o`文件对应的`.c`文件。这样,在执行这条规则时,`make`会自动将所有符合规则的`.o`文件依次生成。
需要注意的是,`.`表示当前目录,所以`%.o`也可以匹配当前目录下的所有`.o`文件。但是,如果有多个目录中都存在`.o`文件,那么`%.o`只能匹配在当前目录下的`.o`文件,不能匹配所有的`.o`文件。在这种情况下,需要使用相应的通配符来匹配不同目录下的`.o`文件。
%.o
和*.o
都可以匹配系统中的.o
文件,但是匹配的方式有所不同。
%.o
只能匹配当前目录下的.o
文件,因为它是用于make
命令中的通配符,用于表示规则中的通配符,如%.o
可以匹配所有以.o
为后缀的文件名,但是只能匹配当前目录下的文件。
而*.o
则可以匹配系统中所有.o
文件,因为它是Shell中的通配符,可以匹配所有符合条件的文件,不限于当前目录。
例如,如果你希望查找系统中所有以.o
为后缀的文件,可以使用以下命令:
find / -name "*.o"
这个命令可以在整个文件系统中查找所有符合条件的.o
文件,并打印出它们的绝对路径。
需要注意的是,使用*
等通配符,一定要小心使用,不要误删除或覆盖了重要文件。
(本文的测试环境是Windows7下使用MinGW提供的make.exe)
例如,如果你想编译一个文件夹下的所有.c文件,你可能会这样写:
%.o:%.c
gcc -o $@ $<
但是如果整个文件只有这两行的话,就会出现这样的错误:
Make: *** target not found. stop.
要知道原因,我们先来看看另一个makefile的运行过程,例如有Makefile如下:
test1.o:test1.c
gcc -o test1.o test1.c
test2.o:test2.c
gcc -o test2.o test2.c
all:test1.o test2.o
如果没有指定输出项目的时候Make会自动找到makefile中第一个目标中没有通配符的目标进行构造,所以步骤是:
其中最重要的是第2步。
Makefile的通配符是在带着目的(如“寻找test1.o”)的时候才会把他要寻找的目标套用通配符%中。
所以通配符%的意思是:
而通配符*的意思是:
所以虽然连个符号的意思有点沾边,但是他们的工作方式时完全不一样。
现在知道了为什么文件中只有
%.o:%.c
gcc -o $@ $<
会找不到目标了吧。因为没有-f参数时Make会自动找到makefile中第一个目标中没有通配符的目标进行构造,所以就等于找不到目标了。它的意思并不会自动把文件中所有的文件都编译。
所以正确的代码应该是:
all:$(subst .c,.o,$(wildcard *.c))
%.o:%.c
gcc -o $@ $<
这才是把目录下所有文件都编译的命令。