一. 前言
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作 makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命 令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。 make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
二. 创建makefile工具:
对比不使用makefile工具时和使用makefile工具的差别:
不使用makefile工具时:
步骤1: 创建一个.c文件:
步骤2:对.c文件进行代码编写:
步骤3:将.c文件编译为可执行文件
步骤4: 输出可执行文件的结果:
指令:./可执行文件名
步骤5: 发现.c文件中有bug,修改文件代码
步骤6:重新编译.c文件生成可执行文件 myset.exe :
一般来说,常规情况下编译.c文件然后形成可执行文件的步骤就是来来回回这么6步。
若是有了makefile工具后,使得这些繁琐的步骤指令更加简单化:
步骤1:
makefile是一个文件名,若想构建自动化工具,只能touch这个文件名,起其他的名字,操作系统不会认为这是自动化构建工具。
步骤2:编写自动化工具指令,采用vim编辑器进行:
makefile中需要注意两个关键: 1.依赖关系,2.依赖方法
这两点是makefile存在的意义
举个例子,某个大学生到了月底,生活费就花的差不多了,这时他就得问父母要生活费了,于是给老爸打电话说:“爸,我没钱花了。
依赖关系就是: 我是你儿子 (亲子关系) ;依赖方法: 电话告父亲没钱花了 !
若是向舍友父亲借钱: 这个依赖关系不成立,毕竟人家和你没有任何关系!
步骤3:
根据上图,儿子就相当于是可执行目标程序,根据逻辑可执行得依赖.c文件才能生成。其次依赖的方法就是.c文件形成可执行的具体指令。
保存退出后,使用makefile写好的指令:
如何使用在makefile中写好的指令?
在输入每条设置好的指令之前,都需要先输入make,再输入指令。这是makefile工具的特性。
注:原本设置好的指令是:myset.exe,应该输入make myset.exe才对,但是只输入make,它会默认执行makefile工具的第一条指令,所以就后面的myset.exe就可以直接省略。
根据该指令是否处于makefile的首行指令就可以判断,是否使用make 还是使用make+指令A去执行。
测试可执行文件是否能够显示成功的结果:
那么根据该试验可得:提前设置好指令便可以简单化,提高效率,使得简单的make指令就能代替复杂的gcc myset.c -o myset.exe指令。此外makefile还可以设置多个指令。
这里介绍一下makefile工具的语法:.PHONY
该语法被称作是伪目标,含义:被设置好的指令A若是加上了.PHONY语法,那么该指令A总是会被执行 (不论什么阻碍,总是要执行的)。
这句话有些不好理解,我们通过试验来理解,如下图:.PHONY:clean ,设置clean,它是用来删除可执行文件的指令
结果测试:
注:设置好的指令,使用时前面都需要加make 。
如上图本来myset.exe已经被删除了(ll指令查看当前目录下并没有myset.exe文件),再一次执行make clean指令后,系统仍会再次执行rm -f删除该文件,这就是无论什么阻碍,makefile工具总会执行一一即使没有该.exe文件,系统仍是无条件的执行!
.PHONY用在clean指令上还是不太能真正理解,我们试试用在myset.exe指令上试试:
现在已经有了myset.exe了,再执行make指令,系统就会提示myset.exe已经编译完成,无需再次编译。(上图的情况是myset.exe指令还未加.PHONY语法时的情况)
将myset.exe指令加上PHONY语法:
结果测试:
多层依赖关系:
例1:
指令解析:
make后,默认执行makefile第一条指令,想要生成.exe文件就得依赖.o文件,但现在.o文件不存在,继续往下依赖,.o文件的生成依赖于.s文件,但.s文件也不存在,往下依赖,想要生成.s文件,它依赖于.i文件,但.i文件也不存在,继续往下依赖,想要生成.i文件,依赖于.c文件,现在有.C文件,那么就可以生成.i文件,便可以倒推回去,一步一步的生成.i,.s,.o文件,之后.exe文件便可以生成了! 这就好比是栈,先进的后出,先执行的没办法生成,最后进来的可以先生成。
试验结果: