Unix爱好者家园最引人注目的广告位!
  欢迎 xxtcfpl 加入本站!
 免费注册  用户登陆  汇款方式  汇款确认  产品报价  联系我们  帮助中心

加入收藏
设为首页
会员体系
申请VIP
网站首页 光盘超市 软件下载 技术文章 专题 用户中心 VIP会员 网站留言 论坛 站内搜索 卓越资源 源代码

今天是:2010年03月13日 星期六  您现在位于: 首页 → 技术文章 → GNU make中文手...
   GNU make中文手册-(5)规则的命令3
作者:  出处:Unix爱好者家园unix-cd.com  更新时间: 2006年03月16日 

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 使用隐含规则)。这一点和伪目标有相同之处。在使用空命令的目标时,需要说明的是:实现一个没有实际文件的目标,这个目标只是作为一个标签,来完成它的依赖文件的重建动作。实现这个目的,首先应该想到伪目标而不是空命令目标。因为一个实际不存在的目标文件的依赖文件,可能不会被正确的重建。

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

 (本文已被浏览 24189 次)
 发布人:sdccf
 → 推荐给我的好友
上篇文章:GNU make中文手册-(5)规则的命令2
下篇文章:GNU make中文手册-(6)Makefile...
 相关文章:
Linux系统下软件包管理(7) Linux系统下软件包管理(6)
Linux系统下软件包管理(5) Linux系统下软件包管理(4)
Linux系统下软件包管理(3) 让Linux象Windows一样安装卸载
GNU make中文手册 将Unix应用程序移植到Linux系统详解
GDB调试精粹及使用实例 GNU线性编程中的中间问题
Linux下用Gnuplot科学绘图入门 shell编程例子 -- 一个makefile例子
Linux操作系统中GCC的应用介绍(上) Linux基础认识 理解GNU/Linux
常用命令之 make常见规则解析 Linux/Unix环境下的make和makefile详解
FreeBSD中的GNU C编译器--编译器GCC Debian 3.1 桌面安装方法
GNU make中文手册-(附录)关键字索引 GNU make中文手册-(15)make的常见错误信息

相关搜索
查看百度中关于GNU make中文手册-(5)规则的命令3的更多内容
查看google中关于GNU make中文手册-(5)规则的命令3的更多内容
   文章分类
操作系统 |
SCO_UNIX  Sun_Solaris  IBM_AIX  HP_UX  Linux  BSD  Tru64_UNIX 
通用UNIX知识  Windows  Minix 
程序设计 |
Shell编程  C/C++  汇编  PHP  JAVA  Perl  Python 
ASP/HTML  XML  中间件 
数据库 |
Oracle  Informix  Sybase  Fox  DB2  SQL  MySQL 
PostgreSQL 
网络应用 |
网络应用 
计算机硬件 |
计算机主机  打印机  路由器  交换机  终端  磁带机  MO 
刻录机  终端服务器  调制解调器 
   文章评论
  → 评论内容 (点击查看)   共0条评论,每页显示5条评论   浏览所有评论
(没有相关评论)
  → 发表我的评论
您的姓名: 您的Email:
评论内容:
250字内
发表评论:      发表评论须知 →
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  • 关于我们 ┋  网站留言 ┋  网站地图 ┋  友情链接 ┋  与我在线 ┋  汇款确认 ┋  管理 ┋  TOP
    Unix爱好者家园  http://www.unix-cd.com/
    联系我们:sdccf@163.com
    腾讯QQ: 7644599
    备案序号:鲁ICP备09036304号
    Copyright (c) 2001-2010 Unix-cd.com. All Rights Reserved.