Makefile工具的使用( 三 )


如果makefile中的目标都是以隐含规则生成,可以将规则按照依赖关系分组:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.oedit : $(objects)
cc -o edit $(objects)$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
这里"defs.h"作为所有目标文件的依赖 。这种风格是好是坏取决于个人喜好,它非常紧凑,但是将每个目标的依赖信息放在一起看起来更清楚一些 。
1.8清理
编写规则不至于编译程序 。Makefile通常描述如何做其它事情:比如删除目录中的目标文件和可执行文件来清理目录 。例子中是这样写的:
clean:
rm edit $(objects)
实际情况是,我们需要处理一些意外事件:存在一个叫做"clean"的文件;如果rm出错,并不希望make过程停止下来,修改过的版本如下:
.PHONY : clean
clean :
-rm edit $(objects)
这样的规则当然不能放在makefile的开始,因为这并不是我们缺省要做的工作 。由于"clean"并不是"edit"的依赖,在运行make时没有参数时,这条规则不会执行;要执行这个规则,必须运行"make clean" 。
2Makefile
Makefile中包含五种内容:显式规则,隐式规则,变量定义,指令(directive)和注释 。
?;显式规则描述如何生成规则的目标,它列出了目标依赖的文件,指定了产生或更新目标的命令
?;隐式规则描述如何生成基于文件名的一类文件,说明目标可能依赖于和其文件名类似的文件,指定了相应的命令 。
?;指令类似与编译器的伪指令,包含:
?;指示make读入另一个makefile
?;决定是否忽略makefile中的一部分
?;定义一个变量
?;一行中‘#"开始是注释,直到行末,除非遇到续行符号 。在"define"和命令中不能有注释,其它情况下注释可出现在任何地方 。
2.1makefile名字
缺省情况下,make以下列名字查找makefile:"GNUmakefile","makefile"和"Makefile"(注意大小写) 。通常你的makefile应叫做"makefile"或"Makefile" 。"GNUmakefile"不推荐,除非你的makefile是为GNU的make定制的,其它的make不认为该名字是一个makefile的名字 。
如果你使用非标准命名的makefile,必须用命令开关"-f " 或 "—file" 。参数" –f NAME"或"—file NAME"告诉make读入NAME作为makefile 。如果使用多个该开关,所有的文件将按顺序连接起来 。如果使用该选项,标准的makefile名字不会自动检测 。
2.2包含
‘include"指令告诉make暂停处理余下的内容,读入其它makefile 。语法如下:
include FILENAMES …
这一行起始可以有空格,但TAB字符不允许 。如果文件名包含变量或函数,这些将被扩展 。
2.3‘MAKEFILE"变量
如果环境变量"MAKEFILE"已定义,make认为它的值是一系列空格隔开的文件名,这些文件在处理其它makefile前被make程序读入 。这类似于include指令;这些文件中的目标不会影响缺省目标,而且如果文件未找到的话,make并不认为是错误 。
这个变量的主要用途是递归引用make程序时通讯
2.4如何重新生成makefile
有时候makefile是从其它文件生成的,比如RCS或SCCS文件 。如果makefile是由其它文件生成的,需要make读入最新版本的makefile 。
在读入所有makefile之后,make认为每个makefile是一个目标,试图去更新它;如果makefile中有一条如何更新它的规则,或者有适用的隐式规则,需要的更新会进行 。所有的makefile检查完之后,如果有的改变了,make重新开始再读入(make会试图再做更新,但通常不会再改变了,因为已经是最新的了) 。
如果一个文件使用双冒号规则,提供了命令但没有依赖关系,文件始终会被更新 。在makefile的情况下,如果makefile双冒号规则,提供了命令但没有依赖关系,这样makefile始终会重新生成,这会导致循环:make只是在不断更新makefile,却不干活 。为避免这种情况,make不会重新生成那些只有命令没有依赖关系的双冒号规则的makefile 。

推荐阅读