makefile 使用实例(三)

这一篇主要讲一下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 $@ $^
    @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 $@ $^
    @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 $@ $^
    @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

不想写了。就这些

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九霄的爸爸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值