目录
make / Makefile 是大型工程中非常重要的一环。会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,而Makefile是文件。一般来说,大多数的IDE都有这个命 令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。
总之,make是一条命令,makefile是一个文件,两个搭配使用,可完成项目自动化构建。
Makefile文件是为了构建项目而存在的,它的内部需要写依赖关系和依赖方法。
什么是依赖关系和依赖方法呢?————举个简单例子:我和我爸有依赖关系(父子),我没钱了问他要钱,先要表明依赖关系,而后提出依赖方法(打钱)。
如何实现?————
1、在Linux下我的目录中,我先创建两个文件,mytest.c和Makefile。
2、vim mytest.c进入文件写一个C程序,如打印hello;vim Makefile 进入文件,写和mytest.c的 依赖关系和依赖方法:

第一行:mytest : mytest.c,这是个依赖关系。左边是欲要生成的可执行文件,右边是mytest所依赖的源文件,:两侧构成了依赖关系。
第二行:gcc mytest.c -o mytest 是依赖方法,也可以写成 gcc -o mytest mytest.c(总之 -o后面跟的是要生成的可执行文件) 注意:第二行开头用Tab键空开四个字符位,不能用空格打,必须用Tab键!
第三行:.PHONYL:clean 这里的clean是一个伪目标(被.PHONY关键字修饰的对象都是伪目标),并且该目标总是被执行的!
第四行:也是依赖关系,依赖关系的右侧可以为空,也就是clean不依赖其他文件,它的下一行就是依赖方法。
第五行:依赖方法,删除mytest可执行文件(相当于清理)
写完保存退出,执行指令make,可直接编译。

make后默认生成第一条依赖关系及方法(后面的不生成),也就是刚刚写的gcc编译指令。
编译好后生成mytest可执行文件,./mytest 运行打印出" hello "
想删除可执行文件,执行make clean即可(make 后加依赖关系,执行的就是对应依赖方法)

上述编译过程还可被分解,我们已经知道gcc编译过程了(见下博客)linux gcc翻译过程_SAKURAjinx的博客-CSDN博客
下面我们就分解一下该过程,更好地理解依赖关系及方法。

mytest可执行文件依赖于.o文件生成,依赖方法是链接,生成可执行文件。
mytest.o依赖于.s文件生成,依赖方法是汇编,生成可重定向目标二进制文件。
mytes.s依赖于.i 文件生成,依赖方法是编译,生成汇编语言文件。
mytes.i 依赖于.c 文件生成,依赖方法是预处理,生成预处理后的c语言文件。
删除的时候将文件全部删除。

有人会问,不是make默认只执行第一条依赖方法吗?为什么这里都执行了?
————因为这里是一个依赖的递进关系,上面一层依赖关系需要先执行下面的依赖方法才能实现依赖关系。从上面的执行过程也可以看出,写的时候的先后顺序与执行时候相反,也说明了它们之间的实现关系。
make的执行规则是:只生成所有目标对象中的第一个,当然make会根据语法规则,递归生成第一个目标对象的所有依赖对象后再回头生成第一个目标对象,生成后退出。
在make完以后,我们再次输入make指令,发现无法再执行。

显示:mytest文件已经是最新的了。
我们查看mytest以及mytest.c的文件时间:

Access:文件访问时间;
Modify:文件内容被修改的时间;
Change:文件属性被修改的时间。
注意:1、当文件内容被修改了,Modify改变,Change属性也会改变。
2、理论而言当文件内容发生改变,Access 访问时间也会改变(不访问如何改变文件内容)
但是因此Access改变次数过于频繁,会对系统造成负担,因此老版本的操作系统内核是上述所言只要访问或改文件内容就立即修改Access,但是现在的操作系统会减少修改Access的次数,具体看操作系统设计了。
回到上文,那么gcc如何知道文件是最新的呢?————mytest 是依赖于mytest.c实现的,那么mytest.c修改时间必定早于mytest,只要看两个文件的时间,如果mytest时间比mytest.c晚,那么说明是最新的。
有一种情况不管文件是否是最新的都可以执行make指令,就是之前说的 .PHONY修饰的目标总是被执行的。
如果改一下makefile文件里的内容:


目标mytest是伪指令,总是被执行,就不受时间约束了。
make / makefile 是项目中常用的,一个项目不可能只有一个源文件,这里只是简化版的,方便理解基础使用方法,关于它的其它应用在下一节《Linux 小程序》中进一步说明。