makefile学习要点汇总
一般来说,make 会以 UNIX 的标准 Shell,包括通配符的使用,也就是/bin/sh 来执行命令,遵循于 IEEE 1003.2-1992标准的(POSIX.2),那什么是Makefile(百度百科介绍)呢,一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,也可以执行操作系统的命令。这就是Makefile。
在默认的方式下,也就是我们只输入 make 命令。那么,
1、make 会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
3、如果 edit 文件不存在,或是 edit 所依赖的后面的[.o]文件的文件修改时间要比edit 这个文件新,那么,他就会执行后面所定义的命令来生成 edit 这个文件。
4、如果 edit 所依赖的.o 文件也存在,那么 make 会在当前文件中找目标为.o 文件的依赖性,如果找到则再根据那一个规则生成.o 文件。(这有点像一个堆栈的过程)
5、当然,你的 C 文件和 H 文件是存在的啦,于是 make 会生成 .o 文件,然后再用 .o文件生命 make 的终极任务,也就是执行文件 edit 了。
make工作步骤
1、读入所有的 Makefile。
2、读入被 include 的其它 Makefile。
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个 Tab 键作为开头。记住,make 并不管命令是怎么工作的,他只管执行所定义的命令。make
会比较 targets 文件和 prerequisites 文件的修改日期(时间戳),如果 prerequisites 文件的日期要比 targets 文件的日期要新,或者 target 不存在的话,那么,make 就会执行后续定义的命令。值得一提的是makefile中定义的变量在执行之初并不会具体展开,但是采用了一种拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。
Makefile 里主要包含了五个东西:显示规则、隐晦规则、变量定义、文件指示和注释。
1、显示规则。显示规则说明了,如何生成一个或多的的目标文件。这是由 Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
2、隐晦规则。由于我们的 make 有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 Makefile,这是由 make 所支持的。
3、变量的定义。在 Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点像 C 语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。
4、文件指示。其包括了三个部分,一个是在一个 Makefile 中引用另一个 Makefile,就像 C 语言中的 include 一样;另一个是指根据某些情况指定 Makefile 中的有效部分,就
像 C 语言中的预编译#if 一样;还有就是定义一个多行的命令。。
5、注释。Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“#”字符,这个就像 C/C++中的“//”一样。如果你要在你的 Makefile 中使用“#”字符,可以用反斜框进行转义, 如:“\#”。
6、最后,还值得一提的是,在 Makefile 中的命令,必须要以[Tab]键开始。
相信这会儿对makefile有了大概的了解。在文中提到多次寻找依赖项,这个寻找过程是怎么样的,它是通过Makefile的环境变量VPATH,Makefile会展昭这个变量中所制定的目录去寻找具体的依赖项以及目标文件,当然当前目录在这个时候仍然具有最高优先级。另一种文件搜索方式是vpath,它有三种方式,具体如下
1、vpath <pattern> <directories> 为符合模式<pattern>的文件指定搜索目录<directories>。
2、vpath <pattern> 清除符合模式<pattern>的文件的搜索目录。
3、vpath 清除所有已被设置好了的文件搜索目录。