·ChinaUnix首页 ·论坛 ·博客 
Linux首页 | Linux新闻 | Linux文档 | Linux论坛 | Linux下载 | Linux博客 | Linux搜索
新手入门 | 安装启动 | 管理员指南 | 开发手册 | 桌面应用 | 程序开发 | 数据库 | 网络技术| CentOS | Fedora | MySQL | Apache | Ubuntu | Gentoo| OSCON08
  Linux时代 >> 技术文档 >> 系统管理
 
第五章:规则的命令(三)
来源: ChinaUnix博客  日期: 2008.03.17 15:22 (共有条评论) 我要评论
 

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

define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef

这里,“run-yacc”是这个命令包的名字。在“define”和“endef”之间的命令就是命令包的主体。需要说明的是:使用“define”定义的命令包中,命令体中变量和函数的引用不会展开。命令体中所有的内容包括“$”、“(”、“)”等都是变量“run-yacc”的定义。它和c语言中宏的使用方式一样。关于变量可参考第六章 Makefile中的变量
例子中,命令包中第一个命令是对引用它所在规则中的第一个依赖文件运行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 $
    frob-step-2 $@-step-1 -o $@
endef

此命令包的第一行命令执行前不会被回显,其它的命令在执行前都被回显。
另一方面,如果一个规则在引用此命令包之前使用了控制命令的前缀字符。那么这个前缀字符将会被添加到命令包定义的每一个命令行之中例如:
frob.out: frob.in
@$(frobnicate)

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

target: ;

这就是一个空命令的规则,为目标“target”定义了一个空命令。也可以使用独立的命令行格式来定义,需要注意的是独立的命令行必须以[Tab]字符开始。一般在定义空命令时,建议不使用命令行的方式,因为看起来空命令行和空行在感觉上没有区别。
大家会奇怪为什么要定义一个没有命令的规则。其唯一的原因是,空命令行可以防止make在执行时试图为重建这个目标去查找隐含命令(包括了使用隐含规则中的命令和“.DEFAULT”指定的命令。关于隐含规则可参考 第十章 使用隐含规则)。这一点它和伪目标有相同之处。使用空命令的目标时,需要注意:如果需要实现一个不是实际文件的目标,我们只是需要通过使用这个目标来完成对它所依赖的文件的重建动作。首先应该想到伪目标而不是空命令目标。因为一个实际不存在的目标文件的依赖文件,可能不会被正确重建。
因此,对于空命令规则,最好不要给它指定依赖文件。避免特殊情况下产生错误的情况。定义一个空命令规则,建议使用上例的格式。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/61627/showart_498200.html
  发表评论 查看评论(共有条评论) 我要提问
 
 


最新资讯更多>> 
· Debian 下一个稳定版的代号被确..
· 发行版发布:Mandriva Linux 2..
· Sun VirtualBox v2.0 发布
· Ubuntu Linux用户突破800万
· Mandriva Linux 2009 RC 1 发布
· 构建Linux版本的谷歌Chrome浏览器
· 发行版发布:Scientific Linux..
· BSD发行版:DragonFly BSD 2.1..
· 要做“龙芯技术源头”龙芯中科..
· 2008年中国开源软件应用调查报告
论坛热点更多>> 
· 奔腾老机器16M内存,还能用什..
· 【经典】我是一条内存
· 刚接到通知
· 建议!
· 中秋都有什么打算啊
· 下班我们部门KTV有美女陪 o(..
· 誰懂裝修啊,來幫幫忙
· 《深入理解Linux网络内幕》原..
· UNIX环境高级编程这本书怎么样?
· 真实的战争~~~~来晚的已经没..
文档更新更多>> 
· 用YUM升级CentOS系统中PHP和MySQL
· [转]Red Hat Linux 安全设置指南
· 使用Emacs作为文件管理器
· linux内核的移植与遭遇问题的解决
· KStar 校园网锐捷认证GUI版
· 给eclipse安装CDT插件开发C/C++工程
· ubuntu 8.10 安装 Lotus Symphony
· fsck命令
· RHEL5的kickstart中的%packages部..
· linux 线程实现机制分析
 
关于我们 | 联系方式 | 广告合作 | 诚聘英才 | 网站地图 | 友情链接 | 免费注册

Copyright © 2001-2008 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们