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

一. 为什么需要 Makefile

我们都知道在 Linux 下可以使用 gcc 来编译源程序, 当源文件不多的时候, gcc 足以承担编译的工作. 但是一个工程的源文件不计其数, 按照其类型, 功能, 模块分别放在若干个目录当中, 每次使用 gcc 进行编译无疑会使得编译效率低下, 于是项目自动化构建工具 Makefile 就应运而生了.

自动化编译

Makefile 定义了一系列的规则来指定: 哪些文件需要先编译, 哪些文件需要后编译, 甚至于进行更复杂的功能操作. Makefile 带来的好处就是"自动化编译", 一旦写好, 只需一个 make 命令, 整个工程完全自动编译, 极大地提高了软件开发的效率. make是一条命令, Makefile是一个文件,两个工具搭配使用, 完成项目自动化构建.

二. 如何使用 make/Makefile

创建 makefile / Makefile 文件

touch Makefile 创建 Makefile 文件.

接下来, 我们需要在 Makefile 文件中阐明多个文件之间的依赖关系 & 依赖方法.

依赖关系 & 依赖方法

在使用 make/Makefile 前我们首先应该理解各个文件之间的依赖关系 以及它们之间的依赖方法.

  • 依赖关系: 文件 A 的变更会影响到文件 B, 那么就称文件 B 依赖于文件 A.

例如: hello 文件是由 hello.c 文件通过预处理, 编译, 汇编, 链接之后生成的文件, 所以hello.c 文件的变更会影响 hello 文件, 所以说 hello 文件依赖于 hello.c 文件.

  • 依赖方法: 如果文件 B 依赖于文件 A, 那么通过文件 A 得到文件 B 的方法, 就是文件 B 依赖于文件A 的依赖方法.

例如: hello 文件依赖于 hello.c 文件, 而 hello.c 通过 gcc hello.c -o hello 指令就可以得到 hello, 那么 hello 依赖于 hello.c依赖方法就是 gcc hello.c -o hello.

vim Makefile 打开 Makefile 文件, 并在其中编辑好 hellohello.c 的依赖关系和依赖方法.

创建出 hello.c 文件并在其中编辑文本.

执行 make 指令, 并运行可执行文件 hello.

项目清理

在我们每次重新生成可执行程序前,都应该将上一次生成可执行程序时生成的一系列文件进行清理,但是如果我们每次都手动执行一系列指令进行清理工作的话,未免有些麻烦,因为每次清理时执行的都是相同的清理指令,这时我们可以将项目清理的指令也加入到 Makefile 文件当中.

显示执行 make clean 指令.

像 clean 这种没有被第一个目标文件直接或间接关联的文件, 那么它后面所定义的命令将不会被自动执行.

提示: 一般将这种 clean 的目标文件设置为伪目标, 用.PHONY修饰. 伪目标的特性是: 总是被执行.

Makefile 文件中依赖关系的简写方式

  • $@: 表示依赖关系中的目标文件 (冒号左侧)
  • $^: 表示依赖关系中的依赖文件 (冒号右侧)

上图中的依赖关系可以改写为:

三. make/Makefile 的一些问题

stat 指令

我们可以通过 stat 指令来查看源文件和可执行文件的所有属性, 重点需要关注如下属性.

  • Access: 最后一次访问该文件的时间.
  • Change:最后一次改变该文件属性的时间.
  • Modify:最近一次修改文件内容的时间.

make 命令的执行机制

当我们使用 make 命令生成目标文件后, 再次 make 就会得到 'hello' is up to date (hello 文件已经是最新的) 的信息.

那么 make 指令是否执行, 究竟取决于什么呢?

取决于目标文件与其所依赖的文件的 Modify 时间谁更新.

可以看到目标文件 hello 的 Modify 时间在 hello .c 文件的 Modify 时间之后, 所以 make 指令不执行.

当目标文件 hello 的 Modify 时间在 hello .c 文件的 Modify 时间之前, make 指令执行, 无论目标文件是否存在.

相关推荐
YuTaoShao24 分钟前
【LeetCode 每日一题】36. 有效的数独
linux·算法·leetcode
NiKo_W1 小时前
Linux 开发工具(1)
linux·运维·服务器
笑口常开xpr1 小时前
Linux动静态库开发基础:静态库与动态库的编译构建、链接使用及问题排查
linux·c语言·动态库·静态库
艾莉丝努力练剑1 小时前
【C++】类和对象(下):初始化列表、类型转换、Static、友元、内部类、匿名对象/有名对象、优化
linux·运维·c++·经验分享
风_峰1 小时前
PuTTY软件访问ZYNQ板卡的Linux系统
linux·服务器·嵌入式硬件·fpga开发
数智顾问2 小时前
从ENIAC到Linux:计算机技术与商业模式的协同演进——云原生重塑闭源主机,eBPF+WebAssembly 双引擎的“Linux 内核即服务”实践
linux
-SGlow-2 小时前
Linux相关概念和易错知识点(45)(网络层、网段划分)
linux·运维·服务器·网络
三体世界2 小时前
测试用例全解析:从入门到精通(1)
linux·c语言·c++·python·功能测试·测试用例·测试覆盖率
过尽漉雪千山2 小时前
Flink1.17.0集群的搭建
java·大数据·linux·flink·centos
csdn_aspnet2 小时前
Windows、Linux 系统 nodejs 和 npm 版本更新及错误修复
linux·windows·npm·node.js