前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux项目自动化构建工具-make/Make?le

Linux项目自动化构建工具-make/Make?le

作者头像
青衫哥
发布2023-03-31 09:15:14
7330
发布2023-03-31 09:15:14
举报
文章被收录于专栏:C++打怪之路C++打怪之路

一、前言

会不会写make?le,从一个侧面说明了一个人是否具备完成大型工程的能力。

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,make?le定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

make?le带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

make是一个命令工具,是一个解释make?le中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,make?le都成为了一种在工程方面的编译方法。

make是一条命令,make?le是一个文件,两个搭配使用,完成项目自动化构建。


二、理解

1.使用

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

我们vim打开makefile。

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

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

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

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

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

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

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

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

2.文件三个时间

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

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

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

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只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

例如:

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就行了,其他的编译器会自动处理的。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、理解
    • 1.使用
      • 2.文件三个时间
      • 三、原理
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
      http://www.vxiaotou.com