makefile中的patsubst

1、wildcard : 扩展通配符

2、notdir : 去除路径

3、patsubst :替换通配符


例子:
建立一个测试目录,在测试目录下建立一个名为sub的子目录
$ mkdir test
$ cd test
$ mkdir sub

在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件

建立一个简单的Makefile
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )

all:
@echo $(src)
@echo $(dir)
@echo $(obj)
@echo "end"

执行结果分析:
第一行输出:
a.c b.c ./sub/sa.c ./sub/sb.c

wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。

第二行输出:
a.c b.c sa.c sb.c
notdir把展开的文件去除掉路径信息

第三行输出:
a.o b.o sa.o sb.o

在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
任何输出。
或者可以使用
obj=$(dir:%.c=%.o)
效果也是一样的。

这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
它的标准格式是
$(var:a=b) 或 ${var:a=b}
它的含义是把变量var中的每一个值结尾用b替换掉a

今天在研究makefile时在网上看到一篇文章,介绍了使用函数wildcard得到指定目录下所有的C语言源程序文件名的方法,这下好了,不用手工一个一个指定需要编译的.c文件了,方法如下:

SRC = $(wildcard *.c)

等于指定编译当前目录下所有.c文件,如果还有子目录,比如子目录为inc,则再增加一个wildcard函数,象这样:

SRC = $(wildcard *.c) $(wildcard inc/*.c)

也可以指定汇编源程序:
ASRC = $(wildcard *.S)

这样一来,makefile模板可修改的基本就是AVR名称和时钟频率了,其它的一般不用动了。

 

 

PS:针对patsubst我们来好好聊一聊

这是个模式替换函数

格式:$(patsubst <pattern>,<replacement>,<text> ) 
名称:模式字符串替换函数——patsubst。
功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)
返回:函数返回被替换过后的字符串。

示例:

$(patsubst %.c,%.o,x.c.c bar.c)

把字串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”

 

make中有个变量替换引用

 

对于一个已经定义的变量,可以使用“替换引用”将其值中的后缀字符(串)使用指定的字符(字符串)替换。格式为“$(VAR:A=B)”(或者“${VAR:A=B}”),意思是,替换变量“VAR”中所有“A”字符结尾的字为“B”结尾的字。“结尾”的含义是空格之前(变量值多个字之间使用空格分开)。而对于变量其它部分的“A”字符不进行替换。例如:

 

foo := a.o b.o c.o

bar := $(foo:.o=.c)

 

在这个定义中,变量“bar”的值就为“a.c b.c c.c”。使用变量的替换引用将变量“foo”以空格分开的值中的所有的字的尾字符“o”替换为“c”,其他部分不变。如果在变量“foo”中如果存在“o.o”时,那么变量“bar”的值为“a.c b.c c.c o.c”而不是“a.c b.c c.c c.c”。

它是patsubst的一个简化,那么到底是简化成了什么样子呢

 

CROSS=

CC=$(CROSS)gcc

CFLAGS= -Wall 

LDFLAGS= 

 

PKG = src

 

SRCS = $(wildcard $(PKG)/inc/*.c) $(wildcard $(PKG)/*.c)

BOJS = $(patsubst %.c,%.o,$(SRCS))

#BOJS = $(SRCS: .c = .o)

 

#%.o:%.c

# $(CC) -c $< $(CFLAGS) -o $@

 

.PHONY:main

main:$(BOJS)

-$(CC) -o $@ $(CFLAGS) $^ $(LDFLAGS)

-mv main ./myfile

起初使用的是变量替换引用的方式,但是却始终不生成中间的.o文件,但是使用patsubst后,一切正常了,如果你知道为什么,请留言告诉我吧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: makefile patsubst 函数是用来批量替换字符串的一个工具。它的语法如下: ``` $(patsubst pattern,replacement,text) ``` - pattern:需要被替换的字符串的模式。 - replacement:替换的字符串。 - text:需要被处理的字符串。 例如: ``` objects = file1.o file2.o file3.o all: $(objects) %.o: %.c gcc -c $< -o $@ clean: rm -f $(objects) ``` 在这个例子,我们使用 patsubst 函数来删除 .o 文件: ``` clean: rm -f $(patsubst %.o,%,$(objects)) ``` 这样,makefile 就会调用 rm 命令删除 file1 file2 和 file3 这三个文件,而不是删除 .o 文件。 ### 回答2: 在 Makefile patsubst 是一个内置的字符串替换函数,可以用于对模式匹配的字符串进行替换。 具体用法如下: ```makefile # 定义一个变量 SOURCE_FILES = src/main.c src/utils.c src/foo.c # 使用patsubst进行替换 OBJECT_FILES = $(patsubst src/%.c,obj/%.o,$(SOURCE_FILES)) # 输出替换结果 all: @echo $(OBJECT_FILES) ``` 在上面的例子,我们使用了 patsubst 函数来将源文件路径转换为目标文件路径。 `src/%.c` 表示源文件的模式,其 `%` 是通配符,表示任意字符串,并且使用 `.c` 进行匹配。 `obj/%.o` 表示目标文件的模式,我们可以看到,这里也使用了 `%` 通配符,并使用 `.o` 进行匹配。 通过在 patsubst 函数使用这两个模式,我们可以将 `SOURCE_FILES` 变量的源文件路径替换为目标文件路径。 以上面的例子为例,假设 `SOURCE_FILES = src/main.c src/utils.c src/foo.c`,则经过 patsubst 函数处理后,`OBJECT_FILES` 的值将变为 `obj/main.o obj/utils.o obj/foo.o`。 通过这样的替换,我们可以方便地将源文件的路径转换为目标文件的路径,从而方便地进行编译和链接操作。 ### 回答3: makefile 是一种用于构建程序的工具,它可以帮助我们管理项目的文件依赖关系和编译过程。patsubstmakefile 的一个函数,用于进行模式替换。 patsubst 函数的作用是根据给定的模式,对字符串进行替换。它的语法如下: $(patsubst pattern,replacement,text) 其pattern 是要匹配的模式,replacement 是要替换的内容,text 是要进行替换的字符串。 举个例子来说明,假设我们有一个变量: files := file1.c file2.c file3.c 我们想要替换这些文件的扩展名为 .o,可以使用 patsubst 函数来完成: objects := $(patsubst %.c,%.o,$(files)) 在上面的例子,%.c 表示任意以 .c 结尾的字符串,%.o 表示将匹配到的字符串替换为以 .o 结尾。通过对 files 变量的每一个字符串应用 patsubst 函数,我们得到了一个新的变量 objects,其的字符串经过替换后,变成了 file1.o file2.o file3.o。 这个函数在 makefile 的应用非常广泛。比如,我们可以使用 patsubst 函数来生成源码文件对应的目标文件名,或者从文件列表过滤出满足特定条件的文件名等等。 需要注意的是,patsubst 函数只负责替换文件名的部分,而不会改变路径部分。如果想要同时替换路径和文件名,可以使用另外一个函数 called $(subst pattern,replacement,text)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值