Makefile之foreach 、wildcard 、patsubst 解析
BUILDPATH ?= build
SRCDIR += ./
CSRCS += $(foreach d, $(SRCDIR), $(wildcard $d/*.c))
COBJS += $(patsubst %.c, $(BUILDPATH)/%.o, $(CSRCS))
===============================================
一、foreach
$(foreach VAR,LIST,TEXT),返回值:空格分割的多次表达式“ TEXT”的计算的结果。
如果需要(存在变量或者函数的引用),首先展开变量“ VAR”和“ LIST”的引用;而表达式“ TEXT”中的变量引用不展开。
执行时把“ LIST”中使用空格分割的单词依次取出赋值给变量“ VAR”,然后执行“ TEXT”表达式。重复直到“ LIST”的最后一个单词(为空时结束)。
二、wildcard,扩展通配符
一般我们可以使用“$(wildcard *.c)”来获取工作目录下的所有的.c文件列表。
三、patsubst ,替换通配符
“$(patsubst %.c,%.o,$(wildcard *.c))”,首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o文件列表。
四、对变量的赋值也用到了一个特殊的符号:(:=)
五、notdir : 去除路径
例子如下:
建立一个测试目录,在测试目录下建立一个名为sub的子目录
$ mkdir test;cd test;mkdir sub
在test下,建立1.c和2.c,2个文件,在sub目录下,建立3.c和4.c,2 个文件
建立一个简单的Makefile
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )
all:
@echo $(src)
@echo $(dir)
@echo $(obj)
@echo "end"
执行结果分析:
第一行输出:
1.c 2.c ./sub/3.c ./sub/4.c
wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。
第二行输出:
1.c 2.c 3.c 4.c
notdir把展开的文件去除掉路径信息
第三行输出:
1.o 2.o 3.o 4.o
在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
任何输出。
或者可以使用
obj=$(dir:%.c=%.o)
效果也是一样的。
这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
它的标准格式是
$(var:a=b) 或 ${var:a=b}
它的含义是把变量var中的每一个值结尾用b替换掉a