Makefile 中使用的函数

最近要搞Windows产品进行Linux移植,搞视频监控相信你们都知道海康这个龙头老大,最近看海康linux64 consoleDemo,无界面编程须要留了解他的Makefile文件了,在网上查了查这些函数的使用及方法做用,记录一下备忘。linux

Foreach:编程

foreach 函数和别的函数很是的不同。由于这个函数是用来作循环用的,Makefile中的foreach函数几乎是仿照于Unix标准Shell (/bin/sh)中的for语句,或是C-Shell(/bin/csh)中的foreach语句而构建的。它的语法是:函数


    $(foreach <var>,<list>,<text>)测试


这个函数的意思是,把参数<list>;中的单词逐一取出放到参数<var>;所指定的变量中,而后再执行< text>;所包含的表达式。每一次<text>;会返回一个字符串,循环过程当中,<text>;的所返回的每一个字符串会以空格分隔,最后当整个循环结束时,<text>;所返回的每一个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。

因此,<var>;最好是一个变量名,<list>;能够是一个表达式,而<text>;中通常会使用<var>;这个参数来依次枚举<list>;中的单词。举个例子:

    names := a b c d

    files := $(foreach n,$(names),$(n).o)

上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后做为foreach函数的返回,因此,$(files)的值是“a.o b.o c.o d.o”。

注意,foreach中的<var>;参数是一个临时的局部变量,foreach函数执行完后,参数<var>;的变量将不在做用,其做用域只在foreach函数当中。spa


Makefile里的subst
用法是$(subst FROM,TO,TEXT),即将TEXT中的东西从FROM变为TO
Makefile中的字符串处理函数
格式:
    $(subst ;,;,;)
名称:字符串替换函数——subst。
功能:把字串;中的;字符串替换成;。
返回:函数返回被替换事后的字符串。
示例:
$(subst a,the,There is a big tree),
把“There is a big tree”中的“a”替换成“the”,返回结果是“There is the big tree”orm


一、wildcard : 扩展通配符
二、notdir : 去除路径
三、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后,一切正常了,若是你知道为何,请留言告诉我吧