makefile 目录搜索
对于大的系统,通常将源文件和目标文件放在不同的目录中。目录搜索功能可以让make自动在多个目录中搜寻依赖文件,当你将文件重新分布是,不需要改变规则,更改搜索路径即可。
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’目录中可以找到。
选择性搜索
与’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 %.c blish
vpath %.c bar
将按照’foo’,‘blish’,’bar’的次序查找’.c’文件。而
vpath %.c foo:bar
vpath % blish
按照’foo’,’bar’,’blish’的顺序搜索。
使用自动变量
目录搜索的结果并不改变规则中的命令:命令按原样被执行。因此,必须写出与目录搜索功相适应的命令。这可以通过使用$^
这样的自动变量来完成。$^
表示规则中的所有依赖文件,包含它们所在的目录名(参见目录搜索);$@
表示目标。
例如:
foo.o : foo.c
cc -c $(CFLAGS) $^ -o $@
通常情况下,依赖文件也包含头文件,但命令中并不提及这些文件:变量$<
表示第一个依赖文件:
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc –c $(CFLAGS) $< -o $@
目录搜索和隐含规则
使用’VPATH’和’vpath’指定目录搜索也会影响隐含规则。例如:文件’foo.o’没有显式规则,make会考虑隐式规则:如果’foo.c’存在则编译它;如果这个文件不存在,则在相应的目录中查找;如果’foo.c’在任一的目录中存在,则C编译的隐式规则被应用。
隐式规则的命令使用自动变量通常是必要的,这样无需其它努力即可以使用目录搜索得到的文件名。