2021SC@SUDSC
makefile相关知识
一、概述
很多windows程序员可能不知道makefile是什么,主要是因为windows的IDE帮你把一些任务做完了。首先,makefile关系到整个工程的编译规则。一个工程中的源文件不计其数,按功能、类型、模块分别放到若干个目录中,makefile定义了一系列规则来说明哪些文件需要先编译,哪些文件需要后编译,哪些文件需要后编译,甚至进行一些更复杂功能操作,因makefile也可以执行操作系统的命令,就像Shell脚本那样。
对于大多数使用过Linux的人来说,或多或少的都会用过make这个命令,这就是makefile的好处所在——自动化编译。一旦写好makefile,只需要一个命令,整个工程就可以自动编译,中间不需要人为干预,可以极大的提高开发效率。
二、程序的编译和链接
无论是C语言还是C++,大家在写完程序后都需要编译后才能运行,在Linux下,将源文件下编译成中间代码文件,也就是 “.o” 文件,也就是Object File,这个过程就是编译。然后将大量的中间文件合成执行文件,这个过程就叫做链接。
编译时,编译器需要知道头文件的位置,那些声明在C/C++文件中的。只要没有语法错误,编译器都可编译出中间目标文件。一般来说,每个源文件都会对应一个Object File。
链接时,就需要编译好的中间目标文件来链接我们的程序。链接器并不管函数所在的源文件,只关注中间目标文件。但是在大多数情况下,我们会写很多.c的文件,所以会编译出很多中间目标文件,而且链接时需要明确指出中间目标文件名,这显然给编译造成了很大的麻烦。因此,我们可以给中间文件打个包,即是“.a”的文件。就类似于windows的“库文件”。
三、编译规则
假设我们的工程有多个".c"和多个".h"的文件,那么我们就需要写一个makefile来告诉make命令该如何编译和链接这些文件。首先需要明确的编译顺序的规则:
- 如果这几个文件没有被编译过,那么这些“.c文件就要被编译然后链接”。
- 如果某些“.c”文件被修改了,那么可以只编译那些被修改的“.c”文件然后链接以提高效率。
- 如果某些头文件".h"被修改了,那么就需要重新编译那些引用该头文件的“.c”文件然后链接。
那么再来看一下makefile的简单格式:
target ... : prerequisites ...
command
...
...
其中target就是目标文件(Obiect File)也可以是可执行文件,甚至可以是一个标签。
prerequisites是生成对应target所需要的文件。
command是make需要执行的shell命令。
概括来说,makefile的核心内容就是,依照规则处理多个文件之间的依赖关系,target这些目标文件依赖于prerequisites中的文件,生成规则定义在command中。这就等价于如果prerequisites文件要比target文件新,那么command中定义的命令就会被执行。
test : file1.o file2