Linux项目自动化构建工具make/makefile

1.背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计其数,其按类型,功能,模块分别放在若干目录中,makefile定义了一系列的规则来制定,那些文件需要先编译,那些文件需要后编译,那些文件需要重新编译,甚至于进行更复杂的功能操作
  • makefile带来的好处就是—“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释Makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建

2.实例代码

  1. 首先在Linux下创建两个文件,一个用来完成代码的编写,另一个是makefile(也可以是大写的Makefile)。
    Linux项目自动化构建工具make/makefile_第1张图片

  2. 在mycode.c中简单的编写一个hello world的代码
    Linux项目自动化构建工具make/makefile_第2张图片

  3. 在makefile编写依赖关系,和依赖方法
    Linux项目自动化构建工具make/makefile_第3张图片
    说明:makefile中的第一行表明依赖关系:mycode的可执行程序依赖mycode.c;第二行表明依赖方法:用gcc进行编译mycode.c生成mycode。后面三行是进行项目清理,下面会有介绍,现在可以忽略。

  4. 之后我们编译代码就再也不用用gcc mycode.c这样的指令,而是可以直接make,可执行程序mycode就会生成了。
    Linux项目自动化构建工具make/makefile_第4张图片

  5. 当然我们也可以运行这个可执行程序
    Linux项目自动化构建工具make/makefile_第5张图片

  6. 如果我们不想要mycode可执行程序,在命令行直接输入make clean即可。
    Linux项目自动化构建工具make/makefile_第6张图片
    注意: 通过make/Makefile管理的方式,就是Linux下的自动化构建工具。

3.三个时间

3.1 三个时间的引入

通过上述例子,细心的同志就会发现如果你连续make生成可执行程序,就会生成一个报错mycode is up to date(mycode 是最新生成的),那么Linux是如何判断mycode是不是最新的呢?
Linux项目自动化构建工具make/makefile_第7张图片
毫无疑问,通过比较两个时间,mycode和mycode.c时间,那怎么查看文件的时间呢?stat + 文件名 用来查看时间。
Linux项目自动化构建工具make/makefile_第8张图片
这里通过比较两个文件Modify时间(后文具体介绍三个时间),来判断是否需要生成最新的mycode可执行程序
Linux项目自动化构建工具make/makefile_第9张图片
这里发现mycode的Modefy时间比mycode.c的文件新,所以不需要生成最新的可执行程序mycode,所以报错mycode is up to date也不难理解了。

3.2 三个时间的具体介绍

3.2.1 Access访问时间

Access是最近访问文件的时间,但是由于用户访问文件的次数过多,而且用户对Access的时间需求不大。所以Linux系统优化了这Access的访问时间。可能是访问一定次数更改一次,也可能间隔一定的时间。如果需要准确了解,可能需要源码剖析,有兴趣的同志自行研究。

Linux项目自动化构建工具make/makefile_第10张图片
这里cat访问文件之后,Access的时间并没有进行修改。

3.2.2 Change文件属性修改时间

这个就很好理解了,当文件属性属性修改的时候,Change的时间也会修改。

Linux项目自动化构建工具make/makefile_第11张图片

3.2.3 Modify文件内容修改时间

举例:把mycode.c中的printf赋值三遍
Linux项目自动化构建工具make/makefile_第12张图片
比较两个Modify时间
Linux项目自动化构建工具make/makefile_第13张图片
毫无疑问,modify的时间变了,但这里其实还有一个问题:
问:为什么在Change的时间也更新的呢?
答:当文件的大小发生改变,那大小算不算文件属性的一部分呢?

4.makefile的推导规则

我们在Makefile中编写这样的依赖关系和依赖方法
Linux项目自动化构建工具make/makefile_第14张图片
makefile的推导规则类似于stack结构,先进后出。
mycode 依赖于mycode.o
mycode.o 依赖于 mycode.s
mycode.s 依赖于 mycode.i
mycode.i 依赖于 mycode.c

所以先执行那个依赖方法就很明显了后进去的先执行
Linux项目自动化构建工具make/makefile_第15张图片

5.原理

那么make是如何工作的?

  1. make会在当前目录下找名字叫Makefile或者makefile的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),并把这个目标文件作为最终的文件。
  3. 如果mycode文件不存在,或者mycode所依赖的后面的mycode.o文件修改时间要比mycode要新。那么他会执行后面所定义的命令来生成这个mycode文件。
  4. 如果mycode依赖的文件mycode.o不存在,那么make会在当前文件夹找目标为mycode.o文件的依赖性,如果找到,再根据那个规则生成mycode.o文件。
  5. 这就是整个make的依赖性,make会一层一层去寻找文件的依赖关系,直到最终编译出第一个目标文件。当编译成功第一个目标文件后,make就不往下面进行编译了。
  6. 在寻找的过程中,如果发现错误,那么make会直接退出,并报错。而对于所定义的命令错误,或者编译不成功,make根本不理。
  7. make只管文件的依赖性。即,如果我找到依赖关系后,冒号后面的文件还是不在,那么make就直接罢工。

6.项目清理

  • 还记的我们编写Makefile中的.PHONY:clean吗?它表明clean总是被执行。跳出时间比较,那如果我们进行.PHONY:mycode操作呢?
    Linux项目自动化构建工具make/makefile_第16张图片
    Linux项目自动化构建工具make/makefile_第17张图片
    结果显而易见,我们可以一直make了,在也不用比较两个Modify时间了
  • 像clean这种,没有被第一个目标文件直接或间接关联,那么他后面的所定义的命令不会被自动执行。所以如果我们需要执行它,需要显示执行,如make clean 来清除目标文件,以便重新编译。
    Linux项目自动化构建工具make/makefile_第18张图片
  • 但是一般我们这种clean目标文件,我们将它设置为伪目标。用.PHONY修饰。伪目标的特点:总是被执行。

你可能感兴趣的:(Linux,linux)