分类: LINUX
2010-11-11 00:07:11
一、makefile的概述
1、 makefile的内容
在一个完整的makefile中,包含5个东西:显式规则、隐含规则、变量的定义、指示符和注释。
A、显式规则:描述在不同情况下是怎样去更新一个或多个目标文件的。在文件中要明确给出目标文件、目标文件的依赖、以及更新目标文件所需要的命令。
B、隐含规则:根据目标文件的文件名而自动推导出来更新目标文件的方法。根据目标文件的文件名自动产生目标文件的依赖文件,以及使用默认的命令对目标文件进行更新。
C、变量的定义:通过一个字符串来代替一个文本串,在需要引用文本串的地方就可以直接引用字符串来代替文本串的内容。
D、指示符:指明了make程序在读取makefile文件过程中所执行的一系列动作。作用:
读取一个指定的文件;
Makefile的条件执行;
定义一个多行变量;
E、注释:#号之后的内容就当做注释的内容。注释最好是采用独立的一行。
2、 makefile的文件名
a、 在默认情况下,make会在当前目录下依次寻找: GNUmakefile、makefile、Makefile。
b、 通过”make -f”的方法来指定自己命名的makefile文件。
c、 如果目录下存在目标文件的依赖文件,可以通过命令行指定目标文件的方法,运用makefile的隐含规则来更新或生成目标文件。如果目录下不存在目标文件的依赖文件,则会提示出错。
例如:
当前目录下不存在以“GNUmakefile”、“makefile”、“Makefile”命名的任何文件,
A、当前目录下存在一个源文件foo.c的,我们可以使用“make foo.o”来使用make的隐含规则自动生成foo.o。
当执行“make foo.o”时。我们可以看到其执行的命令为:
cc –c –o foo.o foo.c
之后,foo.o将会被创建或者更新。
B、如果当前目录下没有foo.c文件时,就是make对.o文件目标的隐含规则中依赖文件不存在。如果使用命令
“make foo.o”时,将回到到如下提示:
make: *** No rule to make target ‘foo.o’. Stop.
C、如果直接使用命令“make”时,得到的提示信息如下:
make: *** No targets specified and no makefile found. Stop.
3、 包含其他makefile文件
可以通过include来包含其他的文件。
“include”指示符告诉make停止读取当前的makefile,而转去读取include指定的文件,读取完成之后再读取当前的makefile文件。
include作用的场合:
a、 有多个不同的程序,在不同的目录下的几个独立的makefile来更新或创建目标文件。对于通用的变量和模式规则,我们可以放在同一个文件,通过include指示符来包含。
b、 通过目标文件,采用隐含规则来产生依赖文件时,将这些依赖关系保存在一个文件,然后再主akefile中包含此文件。这种方法比直接在主makefile中采用追加依赖文件的方法更明智。
如果include指定的文件不是采用绝对路径,则makefile搜索文件的顺序:
当前目录;
通过命令行参数“-I“;
搜索“/usr/gnu/include“、”/usr/local/include“、”/usr/include”等目录。
如果在当前目录下没有找到include指定的文件时,make会提示一个包含文件未找到的告警提示,但不会立即退出。而是继续处理makefile的内容。当完成读取所有makefile的内容后,make将试图使用规则创建通过include指示符指定但未找到的文件,如果不能创建时,则提示致命错误并且退出。
Include FILENAMEs: make程序处理时,如果FILENAME列表中的任何一个文件不能正常读取而且不存在一个创建此文件的规则时,make程序将会提示错误并退出。
-Include FILENAMES: 当包含的文件不存在或者不存在一个规则去创建它,make程序会继续执行。只有在makefile的目标规则不存在时,才会提示致命错误并退出。为了和其他makefile兼容,使用“sinclude“代替”-include”。
4、 变量“MAKEEFILES”
如果当前的系统环境变量定义了一个“MAKEFILES”变量,则执行make时,首先将MAKEFILES的值当做读入的makefile文件,和include类似,如果文件名非绝对路径并且在当前目录找不到,就会按默认的路径去查找。但和include有点区别:
A、 环境变量MAKEFILES指定的makefile文件中的目标不能当做最终目标, 如果在当前目录下没有GNUmakefile、makefile、Makefile或没通过make –f指定文件,则会提示错误。
B、 环境变量MAKEFILES定义的文件是否存在不会导致make的错误。
C、 Make执行时,先读取MAKEFILES变量的值,然后读取GNUmakefile、makefile、Makefile,然后读取include包含的文件。
5、 变量“MAKEFILE_LIST”
Make在读取makefile文件时,会把读取到文件的文件名追加到变量MAKEFILE_LIST中。例如:
name1:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
include inc.mk
name2:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
all:
@echo name1=$(name1)
@echo name2=$(name2)
最终的执行结果为name1=Makefile name2=inc.mk
6、 makefile执行的过程:
A、 读取变量MAKEFILES指定的文件
B、 在当前目录下一次读取GNUmakefile、makefile、Makefile或没通过make –f 指定文件
C、 读取makefile文件中include包含的文件
D、查找重建所有已读取的makefile文件的规则(如果存在一个目标是当前读取的某一个makefile文件,则执行此规则重建makefile文件,完成以后从第一步开始重新执行)。
E、 初始化变量值并且展开那些需要立即展开的变量和函数并且根据预设条件确定执行分支。
F、 根据最终目标以及其他目标的依赖关系建立依赖关系链表。
G、执行除最终目标以外所有目标的规则。
H、 执行最终目标所在的规则。