一 书写规则概述:
(1)规则包括两部分:一个是依赖关系;一个是生成目标的方法。
(2)目标(target):
*Makefile中只应该有一个最终目标,其他的目标都是这个目标所连带出来的。
*一般定义在Makefile中的目标很多,缺省情况下第一条规则中的目标被确定为最终目标。如果第一条规则中的目标有多个,那么第一个目标会成为最终的目标。
二 规则语法:
(1)makefile规则形式:
*target ... : prerequisites ...
command
...
...
或
*target ... : prerequisites;command
command
...
...
(2)详细介绍:
*target是文件(可执行文件或目标对象文件)名,以空格分开,可以使用通配符。一般来说,目标基本上是一个文件。
*command是命令行,如果与target:prerequisites在一行,用分号隔开;不在一行,必须以tab键开头。
*prerequisites:目标所依赖的文件(或依赖目标)。如果其中某个文件要比目标文件新,那么目标被认为是“过时的”,被认为需要重生成。
*如果命令行太长,可以使用反斜杠('\')作为换行符。
*规则告诉make两件事:文件的依赖关系(prerequisites)和如何生成目标文件(target)。
(3)在规则中使用通配符:
*make支持通配符:"*","?"和"[...]"。
三 文件搜寻:
*(VPATH(变量)和vpath(关键字)。非常注意:只是指定搜索文件依赖的目录,而不是command):
(1)概述:
*在一些大工程中有大量源文件,所以通常把它们分类,放在不同目录中。make需要查找文件的依赖关系时,可以在文件前面加上路径,但最好方法是告诉make一个路径,让make自动去找。
*方法:Makefile中的VPATH和vpath变量。
*注意:如果文件分布在不同目录下,makefile不使用VPATH,可能会通过编译,但是其中依赖文件改变时,不能被察觉到。
(2)VPATH:Search Path for All Prerequisites(注意是依赖文件的目录,还可以是目标文件,command不是)。
*如果没有指定VPATH,make只会在当前目录中寻找依赖文件和目标文件。
*格式:VPATH=src:../headers。
*上面定义指定两个目录,“src”和“../headers”,make会按照这个顺序进行搜索。目录由“冒号”或“空格”分隔。
(3)vpath关键字:比VPATH更灵活,可以指定不同的文件在不同的搜索目录中。
*三种使用方法:
1.vpath
2.vpath
3.vpath:清楚所有已被设置好了的文件搜索目录。
*
*
*例如:vpath %.h ../headers:要求 make 在“../headers”目录下搜索所有以“.h”结尾的文件(如果某文件
在当前目录没有找到的话) 。
*匹配多个pattern或在多个directories:
If several vpath patterns match the prerequisite file’s name, then make processes each matching vpath directive one by one, searching all the directories mentioned in each directive. make handles multiple vpath directives in the order in which they appear in the makefile; multiple directives with the same pattern are independent of each other.
四 伪目标(phony targets):
(1)概念(使用方法:make+targets):
A phony target is one that is not really the name of a file; rather it is just a name for a command to be executed when you make an explicit request.
(2).PHONY标记:为了避免为targets和文件重名。
*使用.PHONY显式指定一个目标是伪目标,向make声明。不管是否有这个文件,这个目标是“伪目标”。
*例如:
.PHONY clean
clean:
rm *.o
(3)伪目标一般没有依赖文件,但是也可以指定依赖文件。伪目标也可以作为“默认目标”,只要将其放在第一个。
(4)规范的伪目标命名(最好使用,显得专业):
*“all”
这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
*“clean”
这个伪目标功能是删除所有被 make 创建的文件。
*“install”
这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目
标中去。
*“print”
这个伪目标的功能是例出改变过的源文件。
*“tar”
这个伪目标功能是把源程序打包备份。也就是一个 tar文件。
*“dist”
这个伪目标功能是创建一个压缩文件,一般是把 tar 文件压成 Z 文件。或是 gz 文
件。
*“TAGS”
这个伪目标功能是更新所有的目标,以备完整地重编译使用。
*“check”和“test”
这两个伪目标一般用来测试 makefile的流程。
五 多目标(multiple targets)
六 静态模式
(1)语法:
*
...
~targets定义了一系列的目标文件,可以有通配符。是目标的一个集合。
~target-parrtern 是指明了 targets 的模式,也就是的目标集模式。
~prereq-parrterns是目标的依赖模式,它对 target-parrtern 形成的模式再进行一次依赖目标的定义。
(2)例如:
*objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
*指明了我们的目标从$object 中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量$object 集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo bar”,并为其加下“.c”的后缀,于是,我们的依赖目标就是“foo.c bar.c”。而命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“foo.c bar.c”),“$@”表示目标集(也就是“foo.o bar.o”) 。
七 自动生成依赖关系:
(1)gcc选项:
*-M:自动寻找源文件中包含的头文件,并生成一个依赖关系(make使用)。
*-MM:同-M,但是"-M"参数会把标准库的头文件也包含进来,-MM则不包含。