作者:我心永恒2602922374_902 | 来源:互联网 | 2023-09-13 19:06
四、浅析makefile的工作机制cc:gcctest:main.odemo.ohelloword.occ-otestmain.odemo.ohelloword.omain.o:
四、浅析makefile的工作机制
cc := gcctest : main.o demo.o helloword.occ -o test main.o demo.o helloword.omain.o : main.c common.hcc -o main.c
demo.o : demo.c demo.hcc -o demo.c
helloword.o : helloword.c helloword.hcc -o helloword.cclean:rm test main.o demo.o helloword.o
上述makefile是一个最为简单的例子,该工程中有3个c文件和3个.h头文件,执行文件test的生成依赖于编译链接的中间目标文件(xxx.o),则上一个例子中的target文件就包括执行文件test和中间目标文件main.o demo.o helloword.o。在命令行中执行命令make,make工具就可以根据makefile中的依赖关系生成执行文件test,执行make clean命令则可以删除执行文件以及中间目标文件。
所谓依赖关系就是生成该target文件所需要的文件,如上述例子中冒号后面的文件,依赖关系也可以认为是target文件是通过哪些文件来进行更新的。在定义好依赖关系之后,便进行关于如何生成目标文件的操作系统的命令。(PS:进行该命令的编写一定要以 Tab 开头,一般Tab表示的是四个 spaces)
Make工具不管命令是怎么工作的,这只是一个脚本处理工具,ta只管执行所定义的命令。Make会比较target文件和Prerequisites文件的修改日期,如果Prerequisites文件的日期要比target文件,或者target文件不存在,make就会执行后续定义的命令。
其次make clean不是一个文件,它可以理解为一个动作,clean的冒号后面没有其他文件,也表明其不存在所谓的依赖关系,所以在执行make时就不会自动去找它的依赖关系,也不会去执行其后的所定义的命令。要执行改命令,就必须在make命令后明显的指出这个label的名字,如make clean。这种方法在make工具中十分有用,我们可以在makefile中定义一些与编译工程无关的命令,比如说程序的打包和备份等。如:
Tar:tar -czf demo.tar.gz *.cbackup:cp demo.c demo.c_backup
上面我们讲了make的工作机制,那么make是怎么工作的呢?
在默认的情况下,我们在command line中输入make命令,则:
1)make工具会在当前的文件路径下寻找名为“makefile”or“Mskefile”的文件。
2)如果找到,它就会在该makefile文件中找到第一个target文件,并将该target文件作为最终生成的目标文件。假如没有找到,该工具就会提示“make: *** 没有指明目标并且找不到 makefile。 停止。”。
3)如果target文件不存在,或者是target文件所依赖的.o文件的修改时间比target文件新,那么该工具就会执行后面所定义的命令来生成target文件。
4)如果target文件所依赖的.o文件也不存在的话,make工具就会在当前文件中找target为.o文件的依赖性,如果找到则根据该规则生成.o文件。然后再用生成的.o文件,换言之就是生成最终target文件所依赖的文件执行make命令。
综上,如果在某个工程中我们修改了其中一个源文件(demo.c),那么根据文件的依赖关系(demo.c的修改时间就比demo.o的要新)其对应的target文件(demo.o)就会被重新编译,如此一来依赖关系(demo.o的修改时间就比test的要新)其对应的target文件(test)就会被重新编译,从而完成project的更新。
Make的工作方式可以简化为:
1)读入所有的Makefile。2)读入被include的其它Makefile。3)初始化文件中的变量。4)推导隐含规则,并分析所有规则。5)为所有的目标文件创建依赖关系链。6)根据依赖关系,决定哪些目标要重新生成。7)执行生成命令。