Makefile 中,规则描述了何种情况下使用什么命令来重建一个特定的文件,此文件被称为规则 “目标”(通常规则中的目标只有一个)。规则所罗列的其他文件称为“目标”的依赖,而规则中的 命令是用来更新或者创建此规则的目标。
①,依赖的类型
1.常规依赖:这些依赖文件的更新需要对应更新目标文件
2.read_only依赖:这些依赖的更新不会导致目标被重建
格式:
TARGETS : NORMAL-PREREQUISITES | ORDER-ONLY-PREREQUISITES
②,文件名使用通配符
“*.c”代 表了当前工作目录下所有的以“.c”结尾的文件等。这里在make的时候在会自动展开。
注意这里的objects仅代表*.o。
若是需要在objects 赋值时,直接表示的是用空格分开的所有.o 文件列表。则需要是用 函数“wildcard”来实现(objects = $(wildcar *.o))。
在规则中,通配符会被自动展开。但在变量的定义和使用函数是,通配符不会被 自动的展开。这种情况下需要通配符有效,要用到函数“wildcard”,其用法:$(wildcard PATTERN...) ;在 Makefile 中,它被展开未已经存在的、空格分割的、匹配此模式的所有文件列 表。
“$(patsubst %.c,%.o,$(wildcard *.c))”,首先使用“wildcard”函数获取工作目录下的.c 文件列表;之后将列表中所有文件名的后缀.c替换为.o。这样我们就可以得到在当前目录可生成的.o 文件列表。
③,目录搜索
<1>一般搜索VPATH
通过变量“VPATH”可以指定依赖文件的搜索路径,其实也可以是目标文件。
在当前目录不存在时,make 会在此变量所指定的目录下去寻找这些依赖文件
使用空格或者冒号(:)将多个目录分开
VPATH = src:../headers
指定了两个搜索目录,“src”和“../headers”
<2>选择性搜索
1、vpath PATTERN DIRECTORIES
“PATTERN”表示了具有相同特征的一类文件,而“DIRECTORIES”则指定了搜索此类文 件目录。当规则的依赖文件列表中出现的文件不能在当前目录下找到时,make 程序将依次在 “DIRECTORIES”所描述的目录下寻找此文
vpath %.h ../headers
其含义是:Makefile 中出现的.h 文件;如果不能在当前目录下找到,则到目录“../headers” 下寻找
<3>搜索机制
1. 首先,如果规则的目标文件在 Makefile 文件所在的目录(工作目录)下不存在,那么就执 行目录搜寻。
2. 如果目录搜寻成功,在指定的目录下存在此规则的目标。那么搜索到的完整的路径名就被 作为临时的目标文件被保存。
3. 对于规则中的所有依赖文件使用相同的方法处理
a) 当规则的目标不需要被重 建时,规则中的所有的文件完整的路径名有效。已经存在的目标文件所在的目录不会 被改变。
b) 当规则的目标需要重建时,规则 的目标文件会在工作目录下被重建,而不是在目录搜寻时所得到的目录。这里,必须 明确:此种情况只有目标文件的完整路径名失效,依赖文件的完整路径名是不会失效 的。否则将无法重建目标
若在dir1 文件夹下存有目标文件targit.a ,并在子目录dir2下存有依赖文件sum.c和memcp.c.
1.如果在两个目录(“prom”和“src”)都不存在目标“libtest.a”,执行 make 时将会 在当前目录下创建目标文件“libtest.a”。
2.当我们修改了文件“sum.c”或者“memcp.c”以后执行 make。“libtest.a”和“sum.o” 或者“memcp.o”文件将会被在当前目录下创建(目标完整路径名被废弃),而不是在“src” 目录下更新这些已经存在的文件。此时在两个目录下(“prom”和“src”)同时存在文件 “libtest.a”。但只有“prom/libtest.a”是最新的库文件
3.
目标“libtest.a”将会被在“src”目录下被更新(目标完整路径名不会被废弃)。
④makefile伪目标
伪目标:它不代表一个真正的文件名
在执行 make 时可以指定这个目标来执 行其所在规则定义的命令,有时我们也可以将一个伪目标称为标签
我们输入“make clean”后,“rm *.o temp”总会 被执行
但当前工作目录下存在文件“clean”时情况就不一样了,在我们输入“make clean”时。规 则没有依赖文件,所以目标被认为是最新的而不去执行规则作定义的命令,命令“rm”将不会被执 行
我们可以将目标“clean”明确的声明为伪目标。 将一个目标声明为伪目标需要将它作为特殊目标.PHONY”的依赖。如下:
我们可以输入“make cleanall”和“make cleanobj”和“make cleandiff”命令来达到清除不同种类文件的目的。