这一篇主要讲一下makefile 内置函数的使用,明天就回家了。能写多少就写多少!!
变量的替换引用
对于一个已经定义的变量,可以使用“替换引用”将其值中的后缀字符(串)使用
指定的字符(字符串)替换。格式为“(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”。
obj= main.c foo1.c foo2.c
all:main
main: main.o foo1.o foo2.o
gcc -o [email protected] $^
@echo var is === $(var)
var=${obj:.c=.o}
var:
gcc -c $<
clean:
rm -f *.o main1 main
上面就是把main.c foo1.c foo2.c 替换为 main.o foo1.o foo2.c
打印结果是
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
var is === main.o foo1.o foo2.o
“define”定义变量的语法格式:以指示符“define”开始,“endef”结束,之
间的所有内容就是所定义变量的值。所要定义的变量名字和指示符“define”在
同一行,使用空格分开;指示符所在行的下一行开始一直到“endef”所在行的
上一行之间的若干行,是变量值。
define two-lines
echo foo
echo $(bar)
endef
下面是测试代码,我们定义define com
gcc -o main main.o foo1.o foo2.o
mv main main1
endef
当使用这两行代码地方之间可以用com代替,省下很多代码
define com
gcc -o main main.o foo1.o foo2.o
mv main main1
endef
main : main.o foo1.o foo2.o
$(com)
main.o : main.c
gcc -c main.c
foo1.o : foo1.c
gcc -c foo1.c
foo2.o : foo2.c
gcc -c foo2.c
clean:
rm -f *.o main1 main
在使用指示符“define”定义一个多行的变量或者命令包时,其定义体
(“define”和“endef”之间的内容)会被完整的展开到Makefile中引用此变量的地方
(包含定义体中的注释行)
上面com所代表的的命令包会被展开到所在地方,上面com定义也叫做命令包
在makefile手册中这样被定义
“书写Makefile时,可能有多个规则会使用相同的一组命令。就像c语言程序中需要
经常使用到函数“printf”。这时我们就会想能不能将这样一组命令进行类似c语言函数
一样的封装,以后在我们需要用到的地方可以通过它的名字(c语言中的函数名)来对
这一组命令进行引用。这样就可减少重复工作,提高了效率。在GNU make中,可以使
用指示符“define”来完成这个功能(关于指示符“define”可参考 6.8 多行定义 一
节)。通过“define”来定义这样一组命令,同时用一个变量(作为一个变量,不能和
Makefile中其它常规的变量命名出现冲突)来代表这一组命令。通常我们把使用“define”
定义的一组命令称为一个命令包。定义一个命令包的语法以“define”开始,以“endef”
结束,”
关键字ifeq使用,
此关键字用来判断参数是否相等,格式如下:
ifeq (ARG1, ARG2)‘
ifeq ‘ARG1’ ‘ARG2”
ifeq "ARG1" "ARG2"‘
ifeq “ARG1” ‘ARG2”
`ifeq ‘ARG1’ “ARG2”’
替换展开“ARG1”和“ARG1”后,对它们的值进行比较。如果相同则(条件为
真)将“TEXT-IF-TRUE”作为make要执行的一部分,否则将“TEXT-IF-FALSE”作
为make要执行的一部分(上边的第二种格式)。
通常我们会使用它来判断一个变量的值是否为空(不是任何字符)。参数值可能是
通过引用变量或者函数得到的,因而在展开过程中可能造成参数值中包含空字符(空格
等)。一般在这种情况时我们使用make的“strip”函数(参考 8.2 文本处理函数 一节)
来对它变量的值进行处理,去掉其中的空字符。格式为:
ifeq ((strip(foo)),)
TEXT-IF-EMPTY
endif
这样,即就是在“$(foo)”中存在若干前导和结尾空格,“TEXT-IF-EMPTY”也会被作
为Makefile需要执行的一部分。
file=$(shell find foo2.c )
ifeq ($(strip $(file)),foo2.c)
main_name=main2
else
main_name=main3
endif
main : main.o foo1.o foo2.o
@echo ===== $(file)
gcc -o main main.o foo1.o foo2.o
mv main $(main_name)
main.o : main.c
gcc -c main.c
foo1.o : foo1.c
gcc -c foo1.c
foo2.o : foo2.c
gcc -c foo2.c
clean:
rm -f *.o main1 main
查找当前目录下是否存在foo2.c文件存在,就让可执行文件mv main main2,不存在就是 mv main main3
在 makefile中使用 shell命令 格式为 $(shell 命令),本例查找当前存在foo2.c,假如查找所有.c文件,file=(shell find *.c),
file=$(shell find *.c )
define find_name
ifeq ($(strip $(1)),foo2.c)
main_name=main2
endif
endef
$(foreach var,$(file),$(eval $(call find_name,$(var))))
main : main.o foo1.o foo2.o
@echo === $(main_name)
@echo ===== $(file)
gcc -o main main.o foo1.o foo2.o
mv main $(main_name)
main.o : main.c
gcc -c main.c
foo1.o : foo1.c
gcc -c foo1.c
foo2.o : foo2.c
gcc -c foo2.c
clean:
rm -f *.o main1 main
结果是:
gcc -c main.c
gcc -c foo1.c
gcc -c foo2.c
=== main2
===== foo1.c foo2.c main.c main1.c
gcc -o main main.o foo1.o foo2.o
mv main main2
“call”函数是唯一一个可以创建定制化参数函数的引用函数。使用这个函数可以
实现对用户自己定义函数引用。我们可以将一个变量定义为一个复杂的表达式,用“call”
函数根据不同的参数对它进行展开来获得不同的结果。
函数语法:
$(call VARIABLE,PARAM,PARAM,...)
函数功能:在执行时,将它的参数“PARAM”依次赋值给临时变量“(1)”、“(2)”
(这些临时变量定义在“VARIABLE”的值中,参考下边的例子)……call函
数对参数的数目没有限制,也可以没有参数值,没有参数值的“call”没有任何
实际存在的意义。执行时变量“VARIABLE”被展开为在函数上下文有效的临时
变量,变量定义中的“(1)”作为第一个参数,并将函数参数值中的第一个参数赋值给它;变量中的“(2)”一样被赋值为函数的第二个参数值;依此类推(变
量$(0)代表变量“VARIABLE”本身)。之后对变量“VARIABLE” 表达式的计
算值。
上面define用法已经说过define定义变量在使用时候会展开放在远离位置,对于复杂的表达式可以用define定义,
因为用define定义所以使用的时候要用eval函数展开define定义的find_name.
reverse = $(2) $(1)
foo = $(call reverse,a,b)
上面这个就不需要使用eval 函数!!因为没有用define定义,不需要展开
findstring 使用:
file=$(shell find *.c )
main_name=$(findstring foo2.c,$(file))
obj= main.o foo1.o foo2.o
main : $(obj)
gcc -o [email protected] $^
@echo === $(main_name)
@echo ===== $(file)
mv main $(main_name)
clean:
rm -f *.o main1 main
结果是:
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
=== foo2.c
===== foo1.c foo2.c main.c main1.c
mv main foo2.c
$(subst FROM,TO,TEXT)
函数名称:字符串替换函数—subst。
函数功能:把字串“TEXT”中的“FROM”字符替换为“TO”。
返回值:替换后的新字符串。
file=hello from DSP
main_name=$(subst DSP,PPTV,$(file))
obj= main.o foo1.o foo2.o
main : $(obj)
gcc -o [email protected] $^
@echo === $(main_name)
@echo ===== $(file)
# mv main $(main_name)
clean:
rm -f *.o main1 main
cc -c -o main.o main.c
cc -c -o foo1.o foo1.c
cc -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
=== hello from PPTV
===== hello from DSP
不想写了。就这些