×××××××××××××××××××××××××××××××××××××
××× 呕心整理,转载请注明出处 GuoSenZQ ×××
×××××××××××××××××××××××××××××××××××××
规则
-
语法
TARGETS:PREREQUISITES (; COMMAND) COMMAND ...
TARGETS : 目标,可以是空格分开的多个文件,也可使用通配符;
PREREQUITITES : 依赖,根据依赖更新后是否需要重建目标,将依赖分为两种,用“|”进行分割,“需要|不需要”,把更新后不需要重建目标的依赖称为“order-only”依赖;
COMMAND : 有两种风格,可以与目标和依赖在同一行,用分号分割,或者在下一行,并必须以【Tab】字符开始; -
目录搜索
VPATH:是个变量,指定了make执行时当前Makefile中所有文件的搜索路径,包括规则的依赖文件和目标文件,定义时通过冒号“:”将多个目录分开,如LIBS_DIRS = /lib:/usr/lib:/usr/local/lob;
vpath:是个关键字,可以为不同类型的文件指定不同的搜索路径,使用时通过模式字符“%”进行匹配,但是模式匹配所指定的文件仅仅指在Makefile中出现的相应类型的文件,(如:%.h 并不包含源文件中包含的头文件所在的路径,其需要在编译时通过 gcc 的 -I 选项进行指定),使用格式如下,为所有符合模式“PATTERN”的文件指定搜索目录“DIRECTORY”,多个目录使用空格或冒号分开 :vapth PATTERN DIRECTORIES;
GPATH:变量,如果目标是通过目录搜索得到的完整路径名,且该目标所在的目录出现在GPATH所定义的目录列表中,那么重建目标时将在该目录下进行,而不是在Makefile所在的目录下进行;
-Iname : 若在依赖文件列表中存在这种格式的依赖文件,make将根据name在当前系统中依次搜索可提供的共享库、静态库。
搜索时的搜寻顺序是: Makefile文件所在的目录 => VPATH、vpath指定搜索目录 => 对于用-I方式引入的库文件依赖,还会搜索库文件的默认目录/lib、/usr/lib、PREFIX/lib;
通过搜索得到的文件名可能是包含路径信息的完整文件名,可能并不是规则中列出的文件名,为了保证规则中能正确的使用依赖文件,规则的命令行中必须使用自动化变量来代表依赖文件; -
特殊目标
(0). 特殊的普通目标clean: rm *.o temp
特点:
i). 规则的目标不是一个存在的文件;
ii). 没有依赖或命令;
可能产生的问题:
i). 目标名字可能与当前工作目录下的实际文件名字冲突。
(a). 若目标名字与当前工作目录下的实际名字不冲突时,即此时当前工作目录下不存在同名的文件,且该目标没有依赖,此时make便会通过执行命令去“完成目标的创建”(创建和更新目标是规则的命令部分被赋予的理论上应有的功能),所以此时该规则的命令会被成功执行;
(b). 若冲突时,由于规则没有任何依赖,且目标的同名文件已存在,所以目标会被认为是最新的,因此该规则的命令将不会被执行,此时的结果便与我们定义该规则的初衷相悖;
ii). 当目标名字与当前工作目录下的实际文件名不冲突时,及目标的同名文件不存在时,make在执行时会试去查找可用的隐含规则来创建它,虽然最终并不会找到合适的隐含规则去创建,但是试图查找可用的隐含规则的过程是不可避免的,这会影响make的执行效率;
(1). 强制目标:
特点:
i). “FORCE” 是一个强制目标,但是在GNU make中应避免使用,尽量通过 .PHONY 的方式来代替;
ii). 强制目标本身不是一个真正的文件,并且规则没有命令或依赖,该规则中的目标总被认为是最新的(无论强制目标的同名文件是否存在,没有依赖的规则的目标文件总被认为是最新的,但规则的命令是否会被执行取决与同名文件则是否存在)
iii). 当强制目标作为某个规则的依赖时,由于依赖总被认为是最新的,则以强制目标作为依赖的规则中所定义的命令总会被执行,因此可使用强制目标作为上述(0)中的特殊的普通目标的依赖,来达到与定义成伪目标同样的效果,如下:clean:FORCE rm *.o temp
(2). 伪目标
伪目标不是一个真正的文件名,可以没有命令或依赖,也可以都有,通过指定规则的目标来完成某一功能的一系列命令,通过 .PHONY 进行定义,如下:.PHONY:clean clean: rm *.o temp
特点:
i). 避免Makefile中的目标和工作目录下的实际文件名冲突;
ii). 提高make执行效率,对于声明为伪目标的规则,make执行时不会试图去为它查找隐含规则来创建它;
iii). 无论目标文件是否存在,其规