第三章:makefile总述
3.1makefile的内容
在一个完整的makefile中,包含显示规则、隐含规则、变量定义、指示符和注释。下面讨论一些基本概念:
显示规则:它描述了在何种情况下如何更新一个或者多个被称为目标的文件。书写makefile时需要明确地给出目标文件、目标的依赖文件列表以及更新目标文件所需要的命令。
隐含规则:它是make根据一类目标文件而自动退到出来的规则。make根据目标文件的名,自动产生目标的依赖文件并使用默认的命令来对目标进行更新。
变量定义:使用一个字符或字符串代表一段文本串,当定义一个变量以后,makefile在后续需要使用次文本的地方,通过引用这个变量来实现对文本串的使用。
makefile指示符:指示符指明在make程序读取makefile文件过程中所要执行的一个动作。其中包括:读取一个文件,读取给定文件名的文件,将其内容作为makefile文件的一部分;决定处理或者忽略makefile中的某一特定部分;定义一个多行变量。
注释:使用#来注释内容,当需要使用字符#时,可以使用反斜杠加#的方式来实现"#"。
makefile所以以tab字符开始的行,make程序都会将其交给系统shell程序去解释执行。因此,以tab字符开始的注释行也会被交给shell来处理,此命令是否需要被执行是由系统shell程序来判定。
3.3:包含其它makefile文件
makefile中包含其他文件所需要使用的关键字是“INCLUDE”,和c怨言对头文件的包含方式一致。
include指示符高速make暂停读取当前的makefile,而转去读取include指定的一个或者多个文件,完成以后再继续当前makefile的读取,makefile中的指示符include书写在独立的一行,其形式如下:
include FILENEMES...
FILENAMES是shell所支持的文件名。(可以使用通配符)
例如上一篇中的makefile文件可以写成两个不同的makefile文件:
makefile:
obj = main.o hello.o main:$(obj) cc -o main $(obj) include makefile1 .PHONY:clean clean: rm -rf *.o main
makefile1:
main.o hello.o : hello.h
再来看一个例子,存在三个.mk文件a.mk、b.mk、c.mk,“$(bar)”被扩展为“bish bash”。
则
include foo *.mk $(bar)
等价于:
include foo a.mk b.mk c.mk bish bash
之前已经提到make程序在处理指示符include时,将暂停对当前使用指示符include的makefile文件的读取,而转去依次读取由include指示符指定的文件列表。直到完成所有这些文件以后再回过头继续读取指示符include所在的makefile文件。
通常指示符用在以下场合:
1、有多个不同的程序,由不同目录下的几个独立的makefile来描述其重建规则。他们需要使用一组通用的变量定义或者模式规则。通用的做法是将这些共同使用的变量或者模式规则定义在一个文件中,在需要使用的makefile中使用指示符include来包含此文件。
2、当根据源文件自动产生依赖文件时;我们可以将自动产生的依赖关系保存在另外一个文件中,主makefile使用指示符include包含这些文件。这样的做法比直接在主makefile中追加依赖文件的方法要明智得多。
3.10 总结
make 的执行过程如下:
1. 依次读取变量“MAKEFILES”定义的makefile 文件列表
2. 读取工作目录下的makefile 文件(根据命名的查找顺序“GNUmakefile”,“makefile”,“Makefile”,首先找到那个就读取那个)
3. 依次读取工作目录makefile 文件中使用指示符“include”包含的文件
4. 查找重建所有已读取的makefile 文件的规则(如果存在一个目标是当前读取的某一个makefile 文件,则执行此规则重建此makefile 文件,完成以后从第一步开始重新执行)
5. 初始化变量值并展开那些需要立即展开的变量和函数并根据预设条件确定执行分支
6. 根据“终极目标”以及其他目标的依赖关系建立依赖关系链表
7. 执行除“终极目标”以外的所有的目标的规则(规则中如果依赖文件中任一个文件的时间戳比目标文件新,则使用规则所定义的命令重建目标文件)
8. 执行“终极目标”所在的规则