前言
前面我们对yum、vim、gcc/g++做了介绍,本期我们再来介绍一个好用的工具,就是make和makefile!
本期内容介绍
什么是make和makefile
makefile文件内容的解释
make执行makefile的原理
我们想要的makefile
一、什么是make 和 makefile ?
make是一条指令,makefile是一个文件!两个搭配使用完成项目的自动化构建。
make 会根据makefile的内容去完成编译和资源清理工作!
OK,先来举个例子看一下:
此时makefile已经被创建出来并被我进写了一下东西!
这个先暂时不解释,先看看他的效果,下面会逐一解释!
我们上面介绍说,make是一条指令是配合makefile 的内容进行对文件的编译和资源清理的!如何使用?
make 对文件的编译
make clean 对资源的清理
为什么要有make和makefile呢?
此时你会想,我们以前编译的时候没什么make和makefile也不是好好的吗?是的没错!以前编译的时候只有一个或三个文件!但如果在公司源文件可能不止几个,少则几十个多则几百个上千个,如果你都去gcc是不是等你编译完就可以下班了!效率极低,此时如果合理的用make和makefile文件的话,一个make 指令就可以完成 ,这就很大的提高编程的效率!
二、makefile文件内容的解释
这是我们当前的makefile 的内容!它都是什么意思呢?我们来详细介绍一下!
第一行: my.exe是目标文件(你要生成的),冒号(:)右边是这个目标文件所依赖的文件列表(可以有多个,多个用空格隔开)!目标文件 : 依赖文件 称为依赖关系
第二行: 必须是Tab开头(四个空格不行),然后目标文件的依赖方法(就是让依赖的文件做什么事)!
第三行: .PHNOY:xxx 意思是xxx对象的方法总要执行!
第四行: clean也是目标文件,它的依赖文件列表为空(依赖文件可以为空)
第五行: 是目标文件的依赖方法
如何理解依赖关系和依赖方法?
只有依赖关系没有依赖方法!
假设你今天月底了没有钱了,拿出了给他个人打了电话!假设你打通你只说了一句爹,我是你儿子,然后挂了!此时你就目标文件,你爹就是你的依赖文件!此时没有依赖方法也就是没指定让依赖方法做什么!你爹此时也很懵逼,这小子是要干啥?此时你告诉你爹我是你儿子是表明了依赖关系,但没说要干啥。所以只有依赖关系没有依赖方法啥也不做!
有依赖关系也有依赖方法!
你爹假设很忙,第一次你挂了也没有当回事!此时你饿了,要吃饭!你就又给你爹打过去了!爹我是你儿子,我没钱了!此时既表明了依赖关系有表明了依赖方法!你爹此时会给你打款过来!
资源清理
工程是要被清理的!像clean这种不是第一个目标表文件的不会自动执行,如果要执行就要make clean执行
如果你要把clean作为第一个目标文件也是可以的!
三、make执行makefile的原理
有了上面的解释,我们就能清楚,在我们执行make时,make实际上去makefile文件中找对应的目标文件,然后会让依赖的方法对依赖文件编译生成目标文件!在执行make clean是就执行删除目标文件!大概是这样,下面我们来在详细的解释一下它的执行原理!
make会在当前的目录下去寻找一个名字是"makefile"或"Makefile"的文件!如果没有找到makefile或Makefile文件会报错,入如果找到了就会在makefile或Makefile文件中找第一个目标文件,并将这个目标文件作为最终的目标文件。如果目标文件的依赖文件不存在就会去找目标文件依赖文件的依赖文件找到找到(参考下面的例子),如果没找到或出现错误,直接退出,什么也不做!!
make只关心文件的依赖性,即如果我找到了依赖关系后冒号后的文件在还是不在我就不管喽~!
还是前面的test.c我们现在再写一个Makefile文件:
make执行时会找makefike此时存在,所以就会在makefile中找第一个目标文件,这里就是mytest,并把mytest当作最终的目标文件!此时mytest目标文件依赖的是test.o的文件,是不存在的,就会去先找test.o第二个目标文件就是,但发现他有依赖test.s就去找test.s发现他依赖test.i,test.i依赖于test.c此时发现有,就先执行当前的依赖方法,这样就一层的照下来,然后返回上去!就和栈或递归一样!
总结:make会根据makefile的依赖关系进行自动的推到,帮助我们执行所有的依赖关系的依赖方法!
即使上面的依赖关系不是这样一步一步的而是乱序的也会一样的,会自动推到,但注意的是乱序时最终生成的目标文件必须是第一个!!!!
为什么makefile对最新的可执行程序,默认不想重新形成?
我们在执行make时发现:如果不修改test.c的内容是无法进行二次连续的make的:
如果可执行程序是最新的不给你形成其实很好理解!假设你的可执行 程序的源文件很大,2000个源文件编译一下就得2小时,假设你就想看一下源码但是不修改,结果你误操作了make了一下,那这样是不是很费时间呀!很不划算!所以他检查如果你的可执行程序是最新的就不给你生成了!!
如何做到的?
这里不生成新的可执行程序很好理解但是他是如何做到的呢???这里就得介绍一下一条指令了:
stat filename //查看文件的最近修改时间
OK,先解释一下这三个是啥?
Access :文件最近一次被访问的时间,查看文件内容、修改文件内容、都属于访问文件!
Modify:最近一次修改文件内容的时间
Change:最近一次修改文件属性的时间
这三个时间是关联的例如你修改文件的内容,三个都会变!
所以此时就有一个事实:一定是先有源文件再有可执行程序的!
所以makefile会比较可执行程序和源文件的最近修改的时间的前后来判断是否要重新生成的!!!
所以在清理时,加上.PHNOY是为了告诉makefile,当前的目标文件你千万不要这样比较~!!因为资源要清理多次~!
四、我们想要的makefile
makefile有他自己的一套类似于小语言的语法。所以这里要想配置成我们想要的makefile文件前我们需要介绍几个它的符号!
$@ 表示取目标文件
$^ 表示取所有的依赖文件
所以我们可以把上面makefile文件改成:
但是我们看到他每次都要给我提示gcc xxxxx的!我不想他给我提示了!我们可以在依赖方法的指令前加@
这样写还有一个缺点就是如果要修改makefile文件就会很麻烦尤其是源文件多了,他其实可以支持类似于宏的那种定义!
这就可以支持我们目前基本的开发了!
OK,好兄弟本期分享就到这里,我们下期再见!
结束语:如果结果并非所愿,那就在尘埃落定前奋力一搏!