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 指令执行, 无论目标文件是否存在.

相关推荐
青青草原技术员灰太狼1 天前
Nginx的https搭建
linux·服务器·网络
xu_yule1 天前
网络和Linux网络-4(应用层)序列化和反序列化(网络计算器)
linux·网络
YongCheng_Liang1 天前
Zabbix 6.4 完整部署教程:从环境准备到监控实战
linux·运维·zabbix
小白电脑技术1 天前
旧电脑安装流畅的系统?用虚拟机先体验一下Linux Mint!
linux·电脑
爱吃萝卜的美羊羊1 天前
ubuntu下国内升级ollama
linux·运维·ubuntu
mzhan0171 天前
Linux: console: printk: console_no_auto_verbose
linux·运维·服务器
Savvy..1 天前
天机学堂-Day01
linux·服务器·网络
w***15311 天前
ubuntu 安装 Redis
linux·redis·ubuntu
liweiweili1261 天前
Linux 中替换某个目录下所有文件中的特定字符串
linux·运维·服务器
弓弧名家_玄真君1 天前
Ubuntu 20.04.3 LTS 安装vnc (Xfce4 + Xvfb)
linux·运维·ubuntu