Linux项目自动化构建工具-make/Makefile

一、前言

会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
 
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
 
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
 
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
 
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

二、理解

1.使用

makefile就是创建一个文件叫做 makefile

Linux项目自动化构建工具-make/Makefile_第1张图片

我们vim打开makefile。Linux项目自动化构建工具-make/Makefile_第2张图片

我们敲出上图代码。正常情况下,我们要编译 test.c 文件,我们直接 gcc test.c ,加上 -o [文件名]可以指定编译出来的可执行程序名字。

其中 test:test.c 冒号左边是生成的程序名,冒号右边的是程序生成依赖的文件,这一行是依赖关系。而下面一行则是依赖方法记住,下面一行开头必须是 tab

clean没有依赖的文件,所以后面不接文件名,下面同样是依赖方法。而 .PHONY:  则是将clean修饰成伪目标

做好上述的的准备之后,我们输入 make

Linux项目自动化构建工具-make/Makefile_第3张图片

就会发现,系统会自动帮我们输入依赖关系。当操作的文件非常多的时候,这是极其方便的。

我们再次 make 就会发现系统提示我们 test 文件已经是最新的了,不能再编译。

Linux项目自动化构建工具-make/Makefile_第4张图片

我们想要删除输入:make clean ,可是我们却发现 make clean 是可以一直清理的。这就是因为我们用 .PHONY 将它设置成了伪目标,伪目标的特性是:总是被执行

那么 make 是如何识别文件是不是最新的呢?

  

2.文件三个时间

Linux项目自动化构建工具-make/Makefile_第5张图片

当我们用 stat 命令查看文件属性的时候,我们可以看到有:access、modify、change 三个时间。

access:是进入文件的时间,但是当一个系统运行起来的时候,同时会进入非常多的文件,如果每进入一次,就修改大量文件的时间,那么也太浪费性能了,所以就规定了一段时间进入了一定次数后才修改时间。

modifiy:是修改文件内容的时间,当修改一个文件的内容的时候,access的时间一定改变

change:是修改文件属性的时间。

当可执行文件生成的时候会得到这三个时间,如果我们源文件修改了,时间也会刷新,当源文件的内容修改时间要比可执行文件的时间晚的时候,那么这时候我们输入 make 才会重新编译


三、原理

make 是如何工作的 , 在默认的方式下,也就是我们只输入 make 命令。
  1. make会在当前目录下找名字叫“Makefifile”“makefifile”的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test”这个文件,并把这个文件作为最终的目标文件。
  3. 如果hello文件不存在,或是hello所依赖的后面的hello.o文件的文件修改时间要比test这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成test这个文件。
  4. 如果test所依赖的test.o文件不存在,那么make会在当前文件中找目标为test.o文件的依赖性,如果找到则再根据那一个规则生成test.o文件。(这有点像一个堆栈的过程)
  5. 当然,你的C文件和H文件是存在的啦,于是make会生成test.o 文件,然后再用test.o 文件声明make的终极任务,也就是执行文件test了。
  6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
  7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
  8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

例如:

Linux项目自动化构建工具-make/Makefile_第6张图片

mycode 是依赖 mycode.o的,而 mycode.o 是依赖 mycode.s 的,mycode.s 是依赖 mycode.i的,mycode.i 是依赖 mycode.c 的,没有依赖文件就会向下去找,逐层递归,最终倒着生成。mycode.i依赖 mycode.c 生成,然后mycode.s 依赖 mycode.i 生成……,最终生成了mycode,但是我们实际上写的时候是没必要这样写的, 我们直接mycode依赖mycode.c就行了,其他的编译器会自动处理的。

你可能感兴趣的:(Linux操作系统,自动化,运维,linux,服务器)