GNU make手册翻译系列(4)

4.5 伪目标

      有这么一种目标,它不代表一个真正的文件名,执行make时可以指定这个目标来执行其所在规则定义的一系列配方,这种目标就叫伪目标.使用伪目标有两个原因:一个是避免跟同名文件出现冲突,另一个是提高执行make 时的效率.

      如果你要书写这么一条规则:它的配方不会创建目标文件,并且反复指定make该目标时,它的配方都会被执行.下面就是一个例子:

clean:

        rm*.o temp
由于 rm命令并不会创建一个名为 "clean"的文件 ,当前目录下通常也不会存在这个同名文件 ,所以每次你输入 "makeclean",规则中的 rm命令总会被执行 .

      在这个例子中,如果当前目录下已经存在一个名为"clean"的文件时,则目标"clean"所在的规则就不会被执行.因为没有依赖,目标"clean",也就是文件"clean",总被认为是最新的,所以它的配方将不会被执行.为了避免这个问题,你需要将目标"clean"声明为伪目标,方法是将它作为特殊目标".PHONY"的依赖,如下:

.PHONY: clean

clean:

        rm*.o temp
目标 "clean"声明为伪目标之后 ,无论在当前目录下是否存在 "clean"这个文件 ,输入 "makeclean"后都会执行目标 "clean"对应的配方 .

      伪目标在make程序执行递归的过程中同样有用.在这种情况中,Makefile通常包含了这么一个变量,该变量定义为所有需要make的子目录.处理这类场景的一种简单的方法是定义一条规则,在规则的配方中使用shell循环遍历每个子目录进行make,就像下面这样:

SUBDIRS= foo bar baz

subdirs:

        fordir in $(SUBDIRS); do \

            $(MAKE)-C $$dir;\

        done
但这种方法存在几个问题 .第一 ,子目录中执行 make时出现的任何错误都会被忽略掉 ,就是说 ,在对某一个目录执行 make失败以后 ,会继续对其他的目录进行 make.尽管可以在配方中添加出错检测并退出的 shell命令 ,不幸的是 ,如果在执行 make 时使用了 "-k"选项 ,此方法将失效 .第二 ,更重要的一点是 ,这种方法使你无法利用 make并行处理规则目标的功能 ,因为只有一条规则 .

      将子目录声明为伪目标(必须这样做,因为子目录显然总是存在的),就可以解决这些问题:

SUBDIRS= foo bar baz

.PHONY: subdirs $(SUBDIRS)

subidrs: $(SUBDIRS)

        $(MAKE)-C $@

foo: baz
这里我们还声明了一条规则 "foo: baz",这条规则用来确保只有在子目录 "baz"make完毕后才会对子目录 "foo"执行 make.make并行处理规则目标时 ,这种顺序关系声明特别重要 .

        make程序不会对伪目标尝试搜索隐含规则,也不关心是否存在和伪目标同名的文件,这也就是为什么将目标声明为伪目标可以提高make执行效率的原因.

      伪目标通常不会作为一个真正的目标文件的依赖,这是因为如果伪目标成为一个目标文件的依赖时,每次make程序尝试刷新该目标文件时,作为依赖的伪目标,其配方必然会被执行.只要伪目标不作为一个真正目标的依赖,那么该伪目标的配方只会在make程序显式指定执行该目标时被执行.

      伪目标可以有自己的依赖.当一个目录下需要创建多个可执行程序时,一种最方便的方法就是将所有程序的重建规则在一个Makefile中进行描述.因为Makefile中第一个目标就是默认目标,约定的做法是使用一个称为"all"的伪目标来作为默认目标,它的依赖文件就是那些需要构建的独立程序.下边就是一个例子:

all: prog1 prog2 prog3

.PHONY: all

prog1: prog1.o utils.o

        cc-o prog1 prog1.o utils.o

prog2: prog2.o

        cc-o prog2 prog2.o

prog3: prog3.o sort.o utils.o

        cc-o prog3 prog3.o sort.o utils.o
现在我们只需要简单的输入 "make"就可以构建所有的程序 ,或者在 make的命令行参数中指定要构建的程序 (比如 "makeprog1 prog3").伪目标的特性是不会被继承的 :除非特定声明某个目标为伪目标 ,否则伪目标的依赖不会也变成伪目标 .

      当一个伪目标作为另外一个伪目标的依赖时,make程序会将该伪目标作为另外一个伪目标的子程序来处理.在下面这个例子中,输入"makeclean"就会删除所有".o"文件,".diff"文件,以及"program"文件:

.PHONY: cleanall cleanobj cleandiff

cleanall: cleanobj cleandiff

        rm program

cleanobj:

        rm *.o

cleanobj:

        rm *.diff
(这里似乎缺少关于上面这个例子的讲解内容)    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GNU MAKE的详细中文手册,目录如下: 目 录 第一章:概述 1.1 概述 1.2 准备知识 第二章:GNU make 介绍 2.1 Makefile简介 2.2 Makefile规则介绍 2.3 简单的示例 2.4 make如何工作 2.5 指定变量 2.6 自动推导规则 2.7 另类风格的makefile 2.8 清除工作目录过程文件 第三章:Makefile 总述 3.1 Makefile的内容 3.2 makefile文件的命名 3.3 包含其它makefile文件 3.4 变量 MAKEFILES 3.5 变量 MAKEFILE_LIST 3.6 其他特殊变量 3.7 makefile文件的重建 3.8 重载另外一个makefile 3.9 make如何解析makefile文件 3.9.1 变量取值 3.9.2 条件语句 3.9.3 规则的定义 3.10 总结 第四章:Makefile的规则 4.1 一个例子 4.2 规则语法 4.3 依赖的类型 4.4 文件名使用通配符 4.4.1 统配符使用举例 4.4.2 通配符存在的缺陷 4.4.3 函数wildcard 4.5 目录搜寻 4.5.1 一般搜索(变量VPATH) 4.5.2 选择性搜索(关键字vpath) 4.5.3 目录搜索的机制 4.5.4 命令行和搜索目录 4.5.5 隐含规则和搜索目录 4.5.6 库文件和搜索目录 4.6 Makefile伪目标 4.7 强制目标(没有命令或依赖的规则) 4.8 空目标文件 4.9 Makefile的特殊目标 4.10 多目标 4.11 多规则目标 4.12 静态模式 4.12.1 静态模式规则的语法 4.12.2 静态模式和隐含规则 4.13 双冒号规则 4.14 自动产生依赖 第五章:规则的命令 5.1 命令回显 5.2 命令的执行 5.3 并发执行命令 5.4 命令执行的错误 5.5 中断make的执行 5.6 make的递归执行 5.6.1 变量MAKE 5.6.2 变量和递归 5.6.3 命令行选项和递归 5.6.4 -w选项 5.7 定义命令包 5.8 空命令 第六章:Makefile中的变量 6.1 变量的引用 6.2 两种变量定义(赋值 ) 6.2.1 递归展开式变量 6.2.2 直接展开式变量 6.2.3 如何定义一个空格 6.2.4 “?=”操作符 6.3 变量的高级用法 6.3.1 变量的替换引用 6.3.2 变量的套嵌引用 6.4 变量取值 6.5 如何设置变量 6.6 追加变量值 6.7 override 指示符 6.8 多行定义 6.9 系统环境变量 6.10 目标指定变量 6.11 模式指定变量 第七章:Makefile的条件执行 7.1 一个例子 7.2 条件判断的基本语法 7.2.1 关键字“ifeq” 7.2.2 关键字“ifneq” 7.2.3 关键字“ifdef” 7.2.4 关键字“ifndef” 7.3 标记测试的条件语句 第八章:make的内嵌函数 8.1 函数的调用语法 8.2 文本处理函数 8.2.1 $(subst FROM,TO,TEXT) 8.2.2 $(patsubst PATTERN,REPLACEMENT,TEXT) 8.2.3 $(strip STRINT) 8.2.4 $(findstring FIND,IN) 8.2.5 $(filter PATTERN…,TEXT) 8.2.6 $(filter-out PATTERN...,TEXT) 8.2.7 $(sort LIST) 8.2.8 $(word N,TEXT) 8.2.9 $(wordlist S,E,TEXT) 8.2.10 $(words TEXT) 8.2.11 $(firstword NAMES…) 8.3 文件名处理函数 8.3.1 $(dir NAMES…) 8.3.2 $(notdir NAMES…) 8.3.3 $(suffix NAMES…) 8.3.4 $(basename NAMES…) 8.3.5 $(addsuffix SUFFIX,NAMES…) 8.3.6 $(addprefix PREFIX,NAMES…) 8.3.7 $(join LIST1,LIST2) 8.3.8 $(wildcard PATTERN) 8.4 foreach 函数 8.5 if 函数 8.6 call函数 8.7 value函数 8.8 eval函数 8.9 origin函数 8.10 shell函数 8.11 make的控制函数 8.11.1 $(error TEXT…) 8.11.2 $(warning TEXT…) 第九章:执行make 9.1 指定makefile文件 9.2 指定终极目标 9.3 替代命令的执行 9.4 防止特定文件重建 9.5 替换变量定义 9.6 使用make进行编译测试 9.7 make的命令行选项 第十章:make的隐含规则 10.1 隐含规则的使用 10.2 make的隐含规则一览 10.3 隐含变量 10.3.1 代表命令的变量 10.3.2 命令参数的变量 10.4 make隐含规则链 10.5 模式规则 10.5.1 模式规则介绍 10.5.2 模式规则示例 10.5.3 自动化变量 10.5.4 模式的匹配 10.5.5 万用规则 10.5.6 重建内嵌隐含规则 10.6 缺省规则 10.7 后缀规则 10.8 隐含规则搜索算法 第十一章:使用make更新静态库文件 11.1 库成员作为目标 11.2 静态库的更新 11.2.1 更新静态库的符号索引表 11.3 make静态库的注意事项 11.4 静态库的后缀规则 第十二章 : GNU make的特点 12.1 源自System v的特点 12.2 源自其他版本的特点 12.3 GNU make自身的特点 第十三章 和其它版本的兼容 第十四章 Makefile的约定 14.1 基本的约定 14.2 规则命令行的约定 14.3 代表命令变量 14.4 安装目录变量 14.5 Makefile的标准目标名 14.6 安装命令分类 第十五章 make的常见错误信息   附录:关键字索引 1. GNU make可识别的指示 符 2. GNU make函数 3. GNU make的自动化变量 4. GNU make环境变量 后序

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值