Makefile工具的使用( 六 )


‘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.5PHONY目标
Phony目标并非实际的文件名:只是在显式请求时执行命令的名字 。有两种理由需要使用phony目标:避免和同名文件冲突,改善性能 。
如果编写一个规则,并不产生目标文件,则其命令在每次make该目标时都执行 。例如:
clean:
rm *.o temp
因为"rm"命令并不产生"clean"文件,则每次执行"make clean"的时候,该命令都会执行 。如果目录中出现了"clean"文件,则规则失效了:没有依赖文件,文件"clean"始终是最新的,命令永远不会执行;为避免这个问题,可使用".PHONY"指明该目标 。如:
.PHONY : clean
这样执行"make clean"会无视"clean"文件存在与否 。
已知phony目标并非是由其它文件生成的实际文件,make会跳过隐含规则搜索 。这就是声明phony目标会改善性能的原因,即使你并不担心实际文件存在与否 。完整的例子如下:
.PHONY : clean
clean :
rm *.o temp
phony目标不应是真正目标文件的依赖 。如果这样,每次make在更新此文件时,命令都会执行 。只要phony目标不是真正目标的依赖,规则的命令只有在指定此目标时才执行 。
Phony目标可以有依赖关系 。当一个目录中有多个程序是,将其放在一个makefile中会更方便 。因为缺省目标是makefile中的第一个目标,通常将这个phony目标叫做"all",其依赖文件为各个程序:
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o

推荐阅读