Linux项目自动化构建工具-make/Makefile
Linux项目自动化构建工具-make/Makefile
所属专栏:Linux学习??
🚀 >博主首页:初阳785??
🚀 >代码托管:chuyang785??
🚀 >感谢大家的支持,您的点赞和关注是对我最大的支持!!!??
🚀 >博主也会更加的努力,创作出更优质的博文!!??
1. 认识make和makefile
1.1概念
- 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的
规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂
的功能操作。 - makefile带来的好处就是——
“自动化编译”
,一旦写好,只需要一个make命令,整个工程完全自动编
译,极大的提高了软件开发的效率。 make是一个命令工具
,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命
令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一
种在工程方面的编译方法。make是一条命令,makefile是一个文件
,两个搭配使用,完成项目自动化构建。
1.2 简单是使用
- 首先我们要创建一个名字为makefile/Makefile的文件,记住一定要是这个名字。
- 写好依赖关系和依赖方法,写完后保存退出。
= - 执行make
2. 依赖关系和依赖方法
- 依赖关系:确定为什么要帮你。
- 依赖方法:确定怎么帮你。
3. make clear
3.1 clear
- 我们在使用vs或者其他编译器的时候,都是可以直接按快捷键执行代码的,并且你可以对没有修改的代码进行多次的编译,但是使用make不能。如果你对一个写好了的代码执行过一次make了,在你没有对原先代码进行任何的修改前提下,再次使用make指令执行代码此时make就会提示该文件已存在,则不会在进行编译。
只有当你对原先代码进行了修改之后才能再次使用make
。原因是在对一个没有进行修改的代码,在执行make指令的时候make会进行判断,判断你的代码是否修改过,如果修改过了则可以使用make指令进行编译,但是如果没有的话,make就会认为既然没有修改过执行后的结果也是跟上一次一样,也就没有必要在进行编译,于是make就会中断,直接跳出提示信息。
- 解决这个问题的方法也是很简单,那就是把上一次生成的可执行文件删除,然后再次使用make指令生成可执行文件。于是就可以再次在makefile文件加上一个clear依赖关系。
3.2 make和makefile的默认方式
- 在这里我们将刚才写到两个依赖关系换个顺序。
- 此时再次执行make会是什么结果呢?
- 结论就是:
makefile和make形成可执行文件后,默认是从上到下扫描makefile文件,默认是形成第一个文件。
4.make/makefile确定一个文件是否是新的
4.1 文件的时间
-
先说结论,后验证。
make/makefile是通过文件的修改时间来判断的
。说到时间,在我们之前学习文件的时候,我们说过了每一个文件都对应着有三个时间,修改时间(modify),改动时间(change),访问时间(access)
。
首先我们先搞明白先后顺序,是先有文件呢?还是先有可执行文件呢?
肯定是现有文件,然后通过编译才有的可执行文件。所以一般可执行文件的修改时间是比文件的时间要最新的
,所以make是通过判断谁的时间更新来进行判断要不要在进行编译的。
如果可执行文件的时间最新,那么就说明原先的文件没有别修改过,所以make就不会进行编译。如果是文件的时间最新就说明文件被修改过,那么make指令就会被执行。 -
修改时间(modify)
说到时间上面的时间有两个看似是一样的,修改时间(modify)和改动时间(change),但是其实不是。
我们讲文件的时候提到,文件=内容+属性
,当文件内容改动的时候则修改时间(modify)就会更新,如果时属性发生改变了则改动时间(change)会进行更新。
那么这里为什么只是修改了文件的内容而修改时间(modify),和改动时间(change)都改变了呢?
我们要知道属性不仅包括了文件的创建时间,文件名等,还包括了文件大小,在修改文件内容的时候文件大小也随着改变,进而属性也发生了改变。
-
改动时间(change)
我们可以改变一下文件的权限,权限也属于文件的属性内容。
从这里就可以验证,当属性被修改后,改动时间(change)则会进行更新。 -
访问时间(access)
当对文件进行访问的时候,访问时间会进行更新。
细心的小伙伴可能会发现,当多次访问同一个文件的时候,不是每次访问(access)时间都会实时更新,而是过了一段时间后再次访问后才会进行更新。这是因为,时间也是文件的属性,我们要对文件属性进行修改就要到文件所在的磁盘底下对数据进行修改,而访问文件时修改文件,改动属性这三者当中占比最多的一个。如果我们每次访问文件都对文件的访问时间(access)进行实时更新的话,那也就是说在系统当中相当一大部分时间都只在对文件的属性进行更新,而且还是实时更新的,那个假设有多个文件同时访问呢?这务必会对系统的一些效率会产生一定的影响,所以设计者就规定,只有在访问后的一段时间,或者访问到一定的次数之后我们的访问时间才会进行更新。
4.2 对文件的修改时间进行更新
- 既然make/makefile是
通过文件的修改时间进行判断是否要进行编译
,那么也就说我们是不是每次我们要执行make的时候都要去对我问文件进行修改后才能能运行呢?
按道理说是这样的,但是我们也可直接从修改时间下手,直接通过命令直接修改——修改时间(modify)就要用到我们之前学到的一个命令——touch,touch除了可以创建一个文件外,还可以对一个已成创建的文件进行刷新修改时间(modify)
4.3 .PHONY修饰目标文件
- 被"
.PHONY
"修饰后的目标文件成为一个伪目标
,修饰后的结果——总是可以被执行。
这个时候无论执行多少次make都可以了,因为这个时候目标文件被.PHONY修饰后成为伪目标,总是可以被执行。
但是我们一般并不希望把目标文件设置为伪目标,一把比较希望把clear设置为总是被执行的。
这里为什么没有被.PHONY修饰还是可以被执行呢,是因为由-f选项,强制删除。
至于为什么不希望把目标文件设置为伪目标呢?是因为当我们在一个项目里面,有很多个.c文件,当这些文件都生成.o文件之后,需要进行链接,而链接也是有效率的,而对于项目多多少少都可能会出现一些问题在给别的.c文件里面,这个时候需要对部分的.c文件进行debug,也就是对部分.c我文件进行修改,那么一旦我们的目标文件被.PHONY修饰为伪目标之后,在debug之后,所有的.o文件都将重新进行链接,个别两个效率可能还看不出来,如果时成百上千个呢?这个时候效率显现出来的,而如果没有被修饰成伪目标,make之后对修改了的我进行再次编译,链接的时候只需要把修改后的文件重新进行链接就行了,这样链接的整体效率就得到了提高。
5. 补充内容
在我们的makefile文件中,我们的依赖方法中,其实可以不要直接出现目标文件和原文件,因为我们的make/makefile本来就可自动的识别我们的目标文件和原文件。
- 用
“$@”来表示目标文件,
- 用
“$^表示原文件
- 也就是说之前的方式可以写成以下方式:
- 也可以直接在makefile中定义变量
这里就有点类似于定义宏替换。
6. make/makefile的语法推导理解
- 在上面的依赖关系和依赖方法我们都是一步到位的,但是其实中间是有四个过程的,
预处理,编译,汇编,和链接构成的
,所有它们的依赖关系和依赖方法应该也是由四个的
。
上面的文件 mytext,它依赖 text.o
text.o , 它依赖 text.s
text.s , 它依赖 text.i
text.i , 它依赖 text.c
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!