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编译的隐式规则被应用。

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