【Linux】Linux项目自动化构建工具—make/Makefile

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

一.什么是make/Makefile

Makefile

在Windows下我们使用VS、VS Code这些ide编写C/C++程序去实现一个工程后这些ide就会帮我们处理处理生成这些程序的可执行文件。

而在Linux下如果我们需要自己去通过指令来实现这个工程一个工程中的源文件不计数其按照类型、功能、模块分别放在若干个目录中如果去一一连接实现这是十分不方便的。

而Linux提供了项目自动化编译工具——Makefile其定义了一系列的规则来指定那些文件需要先编译那些文件需要后编译那些文件需要重新编译甚至于进行更复杂的功能操作。Makefile一旦写好只需要一个make命令整个工程完全自动编译极大的提高了软件开发的效率。

所以会不会写Makefile从侧面说明了一个人是否具备完成大型工程的能力。

make

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

如下我们利用Makefile生成C语言文件hello.c的可执行文件
在这里插入图片描述
当一个c程序员所处的开发环境只有一个通过终端连接的Linux时Makefile几乎时构建复杂工程的唯一选择也是项目是否具备工程化的一个分水岭总而言之学习LinuxMakefile足够的重要。

总结

在Linux下make是一个命令Makefile是一个文件二者相辅相成共同实现项目的"自动化构建"。

二.Makefile逻辑

1.简单依赖

Makefile主要由依赖关系依赖方法组成而依赖关系目标依赖组成

最经典的格式如下

target:dependence  #依赖关系
  command          #依赖方法

其中target是要生成的目标dependence是要生成target所需要的依赖两者组成一个依赖关系而command是要生成target所要执行的命令。

注意

  • 依赖关系中的依赖可以有多个也可以没有
  • Makefile也可以写成makefile写成其他make无法识别。该文为Makefile
  • 每条依赖关系前必须以【Tab】键开头

以我们上面的测试代码为例

在这里插入图片描述
为了生成hello文件需要依赖于hello.c文件最后通过下面的依赖生成目标文件hello。

2.复杂依赖

上面测试用例中的依赖关系依赖为该目录下的文件当依赖关系中的依赖不是该目录下的文件时在生成目标文件时系统就会自动在Makefile中的其它目标文件中查找相同的文件如果找到的文件依然不在该目录下则重复进行上述操作。系统采用栈的结果进行操作

我们先将上面的测试用例修改如下
在这里插入图片描述

  • 生成hello文件依赖hello.o文件
  • 生成hello.o文件依赖hello.s文件
  • 生成hello.s文件依赖hello.i文件
  • 生成hello.i文件依赖hello.c文件
  • hello.c文件在该目录下找到直接使用

在我们生成一个hello文件同时生成了其它的三个目标文件并存入该目录下
在这里插入图片描述

依赖关系如下图

在这里插入图片描述

  • 其它目标文件的位置发生改变也不会影响target1的生成依赖是在Makefile文件下查找相同的目标文件和目标文件的位置没有关系。依然采用上面的方法生成文件。

三.make指令

1.make的使用

在Linux下我们输入make命令后系统会在当前目录下查找Makefile文件找到后会执行文件中的第一个依赖关系和依赖方法在屏幕打印出依赖方法并生成目标文件。

我们将上面的Makefile测试案例修改如下
在这里插入图片描述
产生两组依赖关系。clean下面会讲

如下为我们通过make测试

在这里插入图片描述
当我们想要删生成Makefile中其他的目标文件时需要通过指定目标文件方式

make target1 target2   #make后可以有多个target目标文件
  1. make target

在这里插入图片描述

  1. make target1 target2

在这里插入图片描述

2.clean清理

在一个工程中总要对一些不需要的文件进行清理我们常常使用clean来作为项目清理的目标文件。

因为清理文件不需要依赖其它文件所以clean也不存在依赖关系。

当clean不是Makefile第一个目标文件时我们需要在make后加clean来编译它就像之前测试的那样。

在这里插入图片描述

3.伪目标

使用.PHONY修饰的目标称为伪目标格式如下

.PHONY:target

功能使该文件总是可以被执行

当我们多次使用make去生成同一个目标文件时第一次可以编译通过但是之后就无法通过会给出如下结果

在这里插入图片描述
这时我们就可以使用.PHONY来修饰目标文件hello使其变成伪目标总是可以被编译

在这里插入图片描述
注意不是只有使用.PHONY修饰后才可以总是被编译clean目标文件也可以总是编译如下

在这里插入图片描述

4.make如何确定是否编译

上面我们已经测试在不使用.PHONY的情况下make只能被使用一次之后就无法被编译那make是如何确定是否编译呢

当我们在编写完成一个工程后想要去执行实现这个工程一般工程都很大不是我们测试的这么点是需要浪费很多时间和性能的我们不能让其肆无忌惮的执行只有当源文件发生修改后才可以重新实现这个工程生成可执行文件。

make判断是否重复编译根据源文件和目标文件的修改时间对比判断。

  1. 当源文件的修改时间小于目标文件不进行编译
  2. 当源文件的修改时间大于目标文件进行编译

在Linux中每个文件都有三个时间如下

  • 访问时间 (Access)最近访问文件内容时间比如 cat、vim、less
  • 修改时间 (Modify)最近修改文件内容时间比如 nano、vim
  • 改动时间 (Change)最近更改文件属性的时间包括文件名、大小、内容、权限、属主、属组等比如 nano/vim (文件大小改变)

我们可以通过stat指令来查看文件的这三种时间

在这里插入图片描述

访问时间的影响

为什么要对比两个数的修改时间来判断make是否重复编译呢

在Linux下访问一个文件可以通过cat、less指令来进行而通过这两个指令访问后的文件不会修改它本身的访问时间有以下两个原因

  1. 在LInux中访问文件是一个十分频繁的操作而修改文件访问时间每次都需要进行IO操作如果每次访问都对访问时间进行修改那会增加系统的负担。
  2. 一个文件是否被读取是由这个文件的权限决定的既然文件是可读的那么说明文件的拥有者和所属组不建议你去读取也就没必要每次修改访问时间了。

所以Linux访问时间改变有如下两种情况

  1. 访问累计到一定的次数或积累一段时间会更新
  2. 文件的修改时间发生改变时随之改变
    在这里插入图片描述

在这里插入图片描述

  • 上图只使用vim打卡文件并未对其进行修改但也会时修改时间改变

综上如果要判断一个文件是否发生修改判断其修改时间是否发生变化即可。

注意修改时间发生变化文件不一定发生修改

修改时间的影响

当源文件的修改时间改变说明源文件进行了修改此时使用make即可再次编译我们先使用vim更新修改时间判断
在这里插入图片描述
在这里插入图片描述
我们这里在使用touch命令来更新源文件的所有时间touch filefile不存在创建filefile存在更新file所有时间来判断make是否被执行和是否修改源文件内容无关。
在这里插入图片描述
我们从上面的知识可以得出结论make是否被编译和源文件的修改时间有关那我们就可以知道,PHONY就是使目标文件是否被编译不根据修改时间来判断从而达到总是被编译的效果。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: linux