xingzifei

make命令是linx中一个常用的编译命令,尤其是在开发C/C++程序时。make命令执行时,需要一个 Makefile 文件,通过Makefile文件中描述的源程序之间的依赖关系来自动进行编译。Makefile文件是按照规定的格式编写的,文件中需要说明如何编译各个源文件并如何链接生成可执行文件,并要求定义源文件之间的依赖关系。

在首次执行make时,会将所有相关的文件都进行编译,而在以后make时,通常是进行增量编译,即只对修改过的源代码进行编译。

即:

1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而编译所需要的文件和链接目标程序。

 

常用参数

格式:make

使用默认的makefile文件进行编译,按照GNUmakefile, makefile和Makefile的顺序进行查找。编译目标all,因此在一个makefile文件中必须要有all。【见下一个博客,最简单的makefile】

如果make后面不接任何参数,那么则是使用默认的makefile文件进行编译。同时,只对第一个目标进行编译。如果希望实现多个目标文件的话,可以使用一个特殊的目标all

all: a,b,c

 

格式:make -f makefile.debug

使用指定的makefile文件进行编译,此处就是makefile.debug。

 

格式:make install

编译目标install。install 是 该makefile 中的某个目标

 

格式:make clean

编译目标clean。clean 是该makefile 中的某个目标

 

格式:make veryclean

编译目标veryclean。veryclean是该makefile中的某个目标。一般,用于清除目标文件.o以及执行文件等,意思是干净的清除掉除makefile和源程序之外的文件。

 

格式:make rl

编译目标rl。rl是该makefile中的某个目标。一般,rl是relink的缩写,即重新链接,常用于某个依赖的库文件发生变化时强制重新链接生成执行文件。

 

make的工作方式

GNU的make工作时的执行步骤入下:(想来其它的make也是类似)
1、读入所有的Makefile。
2、读入被include的其它Makefile。
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。
1-5步为第一个阶段,6-7为第二个阶段。第一个阶段中,如果定义的变量被使用了,那么, make会把其展开在使用的位置。但make并不会完全马上展开,make使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要 使用了,变量才会在其内部展开。
当然,这个工作方式你不一定要清楚,但是知道这个方式你也会对make更为熟悉。有了这个基础,后续部分也就容易看懂了。
 
make是如何工作的
在默认的方式下,也就是我们只输入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的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一 个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成 功,make根本不理。make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
通过上述分析,我们知道,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
于是在我们编程中,如果这个工程已被编译过了,当我们修改了其中一个源文件,比如 file.c,那么根据我们的依赖性,我们的目标file.o会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o的文件也是最新的 啦,于是file.o的文件修改时间要比edit要新,所以edit也会被重新链接了(详见edit目标文件后定义的命令)。
而如果我们改变了“command.h”,那么,kdb.o、command.o和files.o都会被重编译,并且,edit会被重链接。
 
 
 

 

分类:

技术点:

相关文章: