加入收藏
设为首页
联系站长
您现在的位置: 21chip中国电子联盟 >> 设计与应用 >> 嵌入式系统 >> 设计与应用正文
 
专 题 栏 目
最 新 热 门
最 新 推 荐
相 关 文 章
开放源码:嵌入式系统开…
新手必读:关于Linux,你…
嵌入式linux 中 英 论坛
一种嵌入式Linux平台的软…
为多功能片上系统处理器…
新手必读:关于Linux,你…
Linux网络代码导读v0.2
Linux内核2.4.x的网络接…
GNU make中文手册-(附录…
GNU make中文手册-(15)m…
 
  GNU make中文手册-(5)规则的命令3
GNU make中文手册-(5)规则的命令3
作者:佚名 文章来源:网络转载 点击数: 更新时间:2006-10-20 16:29:10
 
 

5.7      定义命令包

在书写Makefile时,可能有多个规则会使用相同的一组命令。就像c语言程序中需要经常使用到函数“printf”。这时我们就会想能不能将这样一组命令进行类似c语言函数一样的封装,以后在我们需要用到的地方可以通过它的名字(c语言中的函数名)来对这一组命令进行引用。这样就可减少重复工作,提高了效率。在GNU make中,可以使用指示符“define”来完成这个功能。通过“define”来定义这样一组命令,同时用一个变量(作为一个变量,不能和Makefile中其它常规的变量命名出现冲突)来代表这一组命令。通常我们把使用“define”定义的一组命令称为一个命令包。定义一个命令包的语法以“define”开始,以“endef”结束,例如:

 

define run-yacc

yacc $(firstword $^)

mv y.tab.c $@

endef

 

这里,“run-yacc”是这个命令包的名字。在“define”和“endef”之间的命令就是命令包的主体。需要说明的是:使用“define”定义的命令包中,命令体中变量和函数的引用不会展开。命令体中所有的内容包括“$”、“(”、“)”等都是变量“run-yacc”的定义。它和c语言中宏的使用方式一样。

例子中,命令包中第一个命令是对引用它所在规则中的第一个依赖文件(函数“firstword”,可参考 8.2 文本处理函数 一节)运行yacc程序。yacc程序总是生成一个命名为“y.tab.c”的文件。第二行的命令就是把这个文件名改为规则目标的名字。

定义了这样一个命令包后,后续应该如何使用它?前面已经提到,命令包是使用一个变量来表示的。因此我们就可以按使用变量的方式来使用它。当在规则的命令行中使用这个变量时,命令包所定义的命令体就会对它进行替代。由于使用“define”定义的变量属于递归展开式变量,因此,命令包中所有命令中对其它变量的引用,在规则被执行时会被完全展开。例如这样一个规则:

 

foo.c : foo.y

      $(run-yacc)

 

此规则在执行时,我们来看一下命令包中的变量的替换过程:1. 命令包重中的“$^”会被“foo.y”替换;2. $@”被“foo.c”替换。大家应该对“$<”和“$@”不陌生吧,如果陌生可以 参考  自动化变量 一小节。

当在一个规则中引用一个已定义的命令包时,命令包中的命令体会被原封不动的展开在引用它的地方(和 c语言中的宏一样)。这些命令就成为规则的命令。因此我们也可在定义命令包时使用前缀来控制单独的一个命令行(例如“@”,“-”和“+”)。例如:

 

define frobnicate

     @echo "frobnicating target $@"

     frob-step-1 $< -o $@-step-1

     frob-step-2 $@-step-1 -o $@

endef

 

此命令包的第一行命令执行前不会被回显,其它的命令在执行前都被回显。

另一方面,如果一个规则在引用此命令包之前使用了命令的前缀字符。那么这个前缀字符将会被添加到命令包定义的所有命令行之中。例如:

 

frob.out: frob.in

      @$(frobnicate)

 

这个规则执行时不会回显任何将要执行的命令。

5.8      空命令

有时可能存在这样的一个需求,需要定义一个什么也不做的规则(没有命令行)。前面我们已经看到过这样的用法。这样的规则,只有目标文件(可以存在依赖文件)而没有命令行。可以像这样定义:

 

target: ;

 

这就是一个空命令的规则,为目标“target”定义了一个空命令。也可以命令行的格式来定义空命令,需要注意的是命令行必须以[Tab]字符开始。一般在定义空命令时,建议不使用命令行的方式,因为看起来空命令行和空行在感觉上没有区别。

大家会奇怪为什么要定义一个没有命令的规则。其唯一的原因是,使用空命令行可以防止make在执行时图重建这个目标而查找隐含命令(包括了使用隐含规则中的命令和“.DEFAULT”指定的命令。关于隐含规则可参考 10 使用隐含规则)。这一点和伪目标有相同之处。在使用空命令的目标时,需要说明的是:实现一个没有实际文件的目标,这个目标只是作为一个标签,来完成它的依赖文件的重建动作。实现这个目的,首先应该想到伪目标而不是空命令目标。因为一个实际不存在的目标文件的依赖文件,可能不会被正确的重建。

所以,对于空命令规则,最好不要给它指定依赖文件。避免特殊情况下产生错误的情况。定义一个空命令规则,建议使用上例的格式。

设计与应用录入:yh    责任编辑:yh 
  • 上一篇设计与应用:

  • 下一篇设计与应用:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
     
    21chip中国电子联盟 皖ICP备06011561号 安徽鹏达科技 QQ:332122631 站长:21chip