1.makefile文件的命名
默认情况下,make会在工作目录下按照文件顺序寻找makefile文件并执行:
GUNmakefile,makefile,Makefile
如果make程序在工作目录下无法找到三个文件中的任何一个,它将不读取任何其他文件作为解析对象。
此时,需要通过-f NAME / --file=NAME 选项来指定make读取的makefile文件。
注:
当目录下不存在以GUNmakefile,makefile,Makefile命令的任何文件时,
当目录下存在一个源文件getaddinfo.c时,我们可以使用 make getaddrinfo.o 来使用make的隐含规则自动生成getaddrinfo.o:
2. 包含其他makefile文件
如果在一个makefile文件中需要包含另一个makefile文件,需要使用关键字 include.
include指示符告诉make暂停读取当前的makefile,而转去读取include指定的一个或多个文件,完成以后再继续当前的makefile读取。
格式:
include FILENAME...
include与文件名之间、多个文件之间使用空格或者[tab]键隔开。
如果include指示的文件不是绝对地址,并且当前目录下不存在此文件,make将根据文件名试图在以下目录中查找:
- 首先,使用命令行选项 -I 或者 --include-dir 指定的目录,如果找到指定的文件,则使用这个文件;否则继续依次搜索以下几个目录(如果存在): /user/gun/include 、 /user/local/include 、 /use/include
- 其次,当这些目录下都没有找到include指定的文件时候,make将会提示一个包含文件未找到的警告信息,但是不会立即退出,而是继续处理makefile后续的内容。
- 最后,当完成读取整个makefile之后,make试图使用规则来创建通过指示符include指定的但未找到的文件,当不能创建它时,make将提示致命错误并退出。(可以使用-include 代替 include来忽略由于文件不存在或无法创建的错误提示。)
3. makefile执行规则
第一阶段:
- 依次读取变量MAKEFILES定义的makefile文件列表。
- 读取工作目录下的makefile文件,依次查询GUNmakefile, makefile, Makefile.
- 依次读取工作目录makefile文件中使用指示符include包含的文件。
- 查找重建所有已读取的makefile文件的规则。
- 初始化变量值并展开哪些需要立即展开的变量和函数,并根据预设条件确定执行分支。
- 根据 终极目标 以及其他目标的依赖关系建立 依赖关系链表。
第二阶段:
- 执行除 终极目标 以外的所有的目标的规则。
- 执行 终极目标所在的规则。
4. 立即展开和延后展开
- 在make执行的第一阶段中如果变量和函数展开,则称此展开为立即展开。非立即展开,直到后续规则需要使用时或者make处理的第二阶段它们才展开,成为延后展开。
- 当变量使用追加符号 += 时,如果此前这个变量是一个简单变量,使用 := 定义,则认为它是立即展开的,其他情况被称为 延后展开。
- 所有用到条件语句的地方,ifdef, ifeq, ifdef, ifneq,make程序会根据预设条件将正确的分支展开,此展开为立即展开。
- 目标和依赖如果引用其他的变量,则被立即展开。规则命令中的变量引用会被延后展开。