GNU Make 简介( 六 )



注意:"PATTERN"是大小写敏感的 。

3.4 目录搜索

对于大的系统,通常将源文件和目标文件放在不同的目录中 。目录搜索功能可以让make 自动在多个目录中搜寻依赖文件,当你将文件重新分布是,不需要改变规则,更改搜索路径即可 。

3.4.1‘VPATH"

make 变量"VPATH"列出make 应当搜索的目录列表 。很多情况下,当前目录不包含依赖文件,"VPATH"描述一个对所有文件的搜索列表,包含那些是规则的目标的文件 。如果一个目标或者依赖文件在当前目录没找到的话,"make"在"VPATH"中列出的目录中查找同名的文件 。如果找到的话,那个文件成为依赖文件;规则可以象这些文件在当前目录中一样来使用他们 。

"VPATH"变量中,目录名以冒号或空格隔开;目录列出的顺序决定make查找的顺序 。(注:在pSOSystem 2.5 移植到Win32 的GNU make 目录名必须使用分号隔开,以下均简称Win32 GNU make) 。举例说明:

VPATH = src:../headers 则规则
foo.o : foo.c
被解释为
foo.o : src/foo.c
假设"foo.c"在当前目录不存在,在"src"目录中可以找到 。

3.4.2 选择性搜索

与"VPATH"变量相似但更具选择性的是"vpath"指令(注意是小写),可以指定对于符合特定模式文件的查找路径 。这样可以为不同类型的文件指定不同的搜索路径 。

"vpath"指令共有三中形式:

"vpath PATTERN DirectorIES" 为匹配PATTERN 的文件名指定搜索路径DIRECTORIES,目录的分隔和"VPATH"的相同

"vpath PATTERN" 清除为匹配PATTERN 的文件名指定的搜索路径
"vpath" 清除所有以前用"vpath"指定的搜索路径
"vpath"的模式是包含"%"的字符串:这个字符串必须匹配需要搜索的依赖文件名,"%"字符匹配0 个或多个任意字符 。例如:"%.h"匹配任何以".h"结尾的文件(如果没有%,则PATTERN 必须和依赖文件完全一致,这种用法不太多) 。

当前目录中不存在依赖文件时,如果"vpath"中的PATTERN 匹配依赖文件名,则指令中DIRECTORIES 列出的目录和"VPATH"中同样处理 。举例:

vpath %.h ../headers

告诉make 在当前目录中未找到的".h"文件在../headers 目录中查找 。如果多个"vapth"的模式匹配依赖文件名,make 将逐一处理,在所有指定的目录中搜索 。Make 按照"vapth"在makefile 中的次序;来处理它们,多个相同模式的"vapth"是相互独立的 。

vpath %.c foo
vpath % blish
vpath %.c bar
将按照"foo",‘blish","bar"的次序查找".c"文件 。而
vpath %.c foo:bar
vpath % blish
按照"foo","bar","blish"的顺序搜索 。

3.4.3 使用自动变量

目录搜索的结果并不改变规则中的命令:命令按原样被执行 。因此,必须写出与目录搜索功相适应的命令 。这可以通过使用"$^"这样的自动变量来完成 。

"$^"表示规则中的所有依赖文件,包含它们所在的目录名(参见目录搜索);"$@"表示目标 。例如:

foo.o : foo.c
cc -c $(CFLAGS) $^ -o $@
通常情况下,依赖文件也包含头文件,但命令中并不提及这些文件:
变量"$<"表示第一个依赖文件:
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc -c $(CFLAGS) $< -o $@

3.4.4 目录搜索和隐含规则

使用"VPATH"和"vpath"指定目录搜索也会影响隐含规则 。例如:文件"foo.o"没有显式规则,make 会考虑隐式规则:如果"foo.c"存在则编译它;如果这个文件不存在,则在相应的目录中查找;如果"foo.c"在任一的目录中存在,则C编译的隐式规则被应用 。

隐式规则的命令使用自动变量通常是必要的,这样无需其它努力即可以使用目录搜索得到的文件名 。

3.5 PHONY 目标

PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字 。有两种理由需要使用PHONY 目标:避免和同名文件冲突,改善性能 。

推荐阅读