关于Makefile中通配符的相关内容,以及‘%’和‘*’的区别

1. 通配符定义

通配符是指在操作系统中,用于代替其它字符或字符串的符号,可以匹配符合相应规则的文件或目录。即:可以使用通配符代表许多同种格式的文件。如:*.o  表示所有的.o文件

在命令行中,常用的通配符有以下几种:

1.* (星号):表示任意长度的任意字符(包括空字符),可以出现在文件名中的任意位置。

2. ? (问号):表示一个任意字符,且只能替代一个字符。

3. [] (中括号):可匹配其中某个指定字符,可以出现在文件名中的任意位置,如 [abc] 表示可以匹配 a、b、c 中任意一个字符。

4. {} (花括号):可使用逗号隔开的多个字符串中的一个。例如 {a,b,c} 表示可以匹配字符串 a、b、c 中的任意一个。

这些通配符的使用方法类似,都是在命令行中直接使用。使用通配符可以方便地批量操作文件,如删除、复制等。


2. ‘%’并不是通配符

首先说说‘%’,在Linux中,`%`不是通配符,而是一种特殊的替换符号,在一些命令或脚本中可以使用。

在`make`命令中,`%`可以匹配任意字符序列,用于表示规则中的通配符,如`%.o`可以匹配所有以`.o`为后缀的文件名。这样就可以很方便地使用单一规则来生成多个目标文件。

例如,在下面的规则中,`%.o`表示所有的`.o`文件:

```
%.o : %.c
    gcc -c $<
```

其中,`$<`代表依赖项中第一个文件的名称,也就是与这个`.o`文件对应的`.c`文件。这样,在执行这条规则时,`make`会自动将所有符合规则的`.o`文件依次生成。

需要注意的是,`.`表示当前目录,所以`%.o`也可以匹配当前目录下的所有`.o`文件。但是,如果有多个目录中都存在`.o`文件,那么`%.o`只能匹配在当前目录下的`.o`文件,不能匹配所有的`.o`文件。在这种情况下,需要使用相应的通配符来匹配不同目录下的`.o`文件。


3. ‘%’与‘*’的区别

%.o和*.o都可以匹配系统中的.o文件,但是匹配的方式有所不同。

%.o只能匹配当前目录下的.o文件,因为它是用于make命令中的通配符,用于表示规则中的通配符,如%.o可以匹配所有以.o为后缀的文件名,但是只能匹配当前目录下的文件。

*.o则可以匹配系统中所有.o文件,因为它是Shell中的通配符,可以匹配所有符合条件的文件,不限于当前目录。

例如,如果你希望查找系统中所有以.o为后缀的文件,可以使用以下命令:

find / -name "*.o"

这个命令可以在整个文件系统中查找所有符合条件的.o文件,并打印出它们的绝对路径。

需要注意的是,使用*等通配符,一定要小心使用,不要误删除或覆盖了重要文件。


4. 下面这个讨论是转载的,对原文做了一定的删改,可以用作参考,来源:Makefile中的%标记和系统通配符*的区别 - 大火人 - 博客园 (cnblogs.com)

Makefile中的%标记和系统通配符*的区别在于,*是应用在系统中的,%是应用在这个Makefile文件中的。

(本文的测试环境是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中第一个目标中没有通配符的目标进行构造,所以步骤是:

  1. 构造all,发现需要test1.o和test2.o
  2. 这个时候他就会在Makefile文件中找到目标能匹配test1.o和test2.o的规则。
  3. 找到test1.o的规则并且知道test1.c存在,运行下面的命令。
  4. 同步骤三构造出test2.o
  5. 现在构造all的源文件已经齐全,构建all

其中最重要的是第2步。

Makefile的通配符是在带着目的(如“寻找test1.o”)的时候才会把他要寻找的目标套用通配符%中。

所以通配符%的意思是:

  •  我要找test1.o的构造规则,看看Makefile中那个规则符合。
  •  然后找到了%.o:%.c,
  •  来套一下来套一下:
  •  %.o 和我要找的 test1.o 匹配
  • 套上了,得到%=test1。
  • 所以在后面的%.c就表示test1.c了。
  • OK进行构造

而通配符*的意思是:

  • 我不知道目标的名字,系统该目录下中所有后缀为.c的文件都是我要找的。
  • 然后遍历目录的文件,看是否匹配。找出所有匹配的项目。

所以虽然连个符号的意思有点沾边,但是他们的工作方式时完全不一样。

现在知道了为什么文件中只有

%.o:%.c
    gcc -o $@ $<

会找不到目标了吧。因为没有-f参数时Make会自动找到makefile中第一个目标中没有通配符的目标进行构造,所以就等于找不到目标了。它的意思并不会自动把文件中所有的文件都编译。

所以正确的代码应该是:

all:$(subst .c,.o,$(wildcard *.c))

%.o:%.c
    gcc -o $@ $<

这才是把目录下所有文件都编译的命令。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值