Linux篇(八) Make 与 Makefile 超详细入门教程|从零基础到手写自动化编译

在上一篇掌握 GCC 基础编译指令后,本篇正式学习 Linux 开发必备技能 ------Make 与 Makefile,告别手动逐条输入编译命令,实现项目一键自动化编译,大幅提升代码开发与项目运维效率。

目录

[一、前言:为何要学习 Make 与 Makefile](#一、前言:为何要学习 Make 与 Makefile)

[二、基础认知:make 命令与 Makefile 文件含义](#二、基础认知:make 命令与 Makefile 文件含义)

[2.1 什么是 make 工具](#2.1 什么是 make 工具)

[2.2 什么是 Makefile 编译规则文件](#2.2 什么是 Makefile 编译规则文件)

[2.3 学习 Makefile 的实际意义](#2.3 学习 Makefile 的实际意义)

[三、Makefile 核心基础语法](#三、Makefile 核心基础语法)

[3.1 三大核心组成](#3.1 三大核心组成)

[3.2 书写格式规范](#3.2 书写格式规范)

四、依赖关系实战讲解

[4.1 简单依赖逻辑](#4.1 简单依赖逻辑)

[4.2 单文件最简 Makefile 编写](#4.2 单文件最简 Makefile 编写)

[伪目标:.PHONY 的作用](#伪目标:.PHONY 的作用)

[2.4.1 什么是伪目标?](#2.4.1 什么是伪目标?)

4.3make扫描规则

[4.4加入变量优化的单文件 Makefile](#4.4加入变量优化的单文件 Makefile)

多文件处理

一、前言:为何要学习 Make 与 Makefile

在小型单文件代码编写中,我们直接使用 gcc 命令即可完成编译运行,但在实际企业级项目里,一个工程包含数十上百个源文件,分布在不同文件夹内,手动编译繁琐且极易出错。

而 Makefile 能够统一规划项目编译顺序、编译规则、文件清理等全部操作,仅输入一行简单命令就能完成整体构建,是后端开发、嵌入式开发必备核心技能。

二、基础认知:make 命令与 Makefile 文件含义

2.1 什么是 make 工具

make 是 Linux 系统自带的自动化构建命令工具,专门用来读取解析 Makefile 内部编写的编译规则,自动执行对应的编译、链接、清理等操作。

2.2 什么是 Makefile 编译规则文件

Makefile 是存放项目编译规则的文本文件,无需复杂语法,仅规定文件之间依赖关系与执行指令,相当于项目编译的专属执行说明书。

2.3 学习 Makefile 的实际意义

|----------------------|
| 1.简化编译流程,一键完成整体项目编译 |
| 2.实现增量编译,仅编译修改过的代码文件 |
| 3.统一项目编译标准,团队开发格式统一 |
| 4.适配大型工程项目,适配多文件分层编译 |

三、Makefile 核心基础语法

3.1 三大核心组成

标准 Makefile 规则由目标、依赖文件、执行命令三部分构成:

目标 :最终生成的可执行程序或中间文件
依赖 :生成目标所需要的源码文件
命令:实现编译的具体操作语句

3.2 书写格式规范

命令行前方必须使用 Tab 键缩进不可使用空格,格式错误会直接导致 make 编译失败。

四、依赖关系实战讲解

4.1 简单依赖逻辑

依赖关系简单来说:想要生成最终程序,必须先拥有对应的源码文件,源码文件发生变动,最终程序就要重新编译。

4.2 单文件最简 Makefile 编写

我们可以发现,输入 make 即可一键完成编译,生成了可执行文件(绿色文件)简洁高效。

与之前的gcc等命令简便多了。

如果我们对源文件进行修改那么生成的可执行文件就也要进行修改,那原来的可执行文件就要删除,重新进行编译

于是,就有了新的指令

伪目标:.PHONY 的作用

2.4.1 什么是伪目标?

伪目标就是不是真正的文件名的目标,比如我们上面的 clean。

如果你的项目目录里,正好有一个叫 clean 的文件,make 就会把它当成普通目标文件,发现它已经存在,就不会执行 clean 里的 rm 命令了0。

用 .PHONY: clean 声明之后,make 就会知道 clean 不是一个文件,每次执行 make clean 时,都会无条件执行里面的命令,不受文件是否存在的影响。

4.3make扫描规则

直接输入make指令时,make扫描makefile默认执行Makefile 里写在最前面的目标

为什么会有文件总是被执行这一说呢?那么什么又是总是不被执行呢?

make 检查发现,目标文件 myproc(你的可执行程序)比它依赖的源文件 myproc.c 还要新,所以不需要重新编译,直接跳过构建步骤。

那么系统是怎么进行识别呢?

其实文件都是有属性的,通过文件的属性就可以判断了

然而,一个源文件在编译生成可执行文件时并不是那么简单的

他们之间有明确的依赖关系

因此,在执行时,需要根据他们依赖的关系进行查找文件,直到找到.c文件为止,然而在查找的过程中,会进行一种入栈的形式

4.4加入变量优化的单文件 Makefile

变量优化的优点:

|------|--------------------------|
| 易维护 | 改编译参数、路径只需改变量一处,不用通篇改代码 |
| 复用性强 | 变量可全局共用,适配多文件、多目录工程 |
| 可读性高 | 语义清晰,一眼看懂编译器、库、源码路径配置 |
| 灵活扩展 | 方便加编译选项、切换编译器、增减模块 |
| 减少冗余 | 避免重复写相同命令,精简 Makefile 篇幅 |

可以看到,命令也被显示出来了,也可以让其隐藏

有了上面的铺垫,我们可以对文件编译进行变量设置

多文件处理

对于单文件操作,上面的指令就已经足够了,但是在工程项目中,对于多文件来处理,用上面的变量来一个一个添加依赖文件和目标文件未免也太费时费力了

于是就有下面的makefile了

我们发现,较上面的makefile,这次多了**@ ^ $< %.c %.o**,那么他们代表什么呢?


效果

相关推荐
orion5713 小时前
Missing Semester Class1:course overview and introduction of shell
linux
SkyWalking中文站17 小时前
认识 Horizon UI · 6/17:Trace 探索器
运维·监控·自动化运维
用户1204872216119 小时前
Linux驱动编译与加载
linux·嵌入式
火车叼位21 小时前
写给初级开发者:SSL、SSH、HTTPS 与证书体系全解析
运维
用户805533698031 天前
Input 子系统架构:Core、Handler、Driver 三层是怎么协作的
linux·嵌入式
用户805533698031 天前
RK-Forge外设系列开篇 - 把板子从「能启动」变成「能用」:Ethernet/SPI/MMC 三个纯接线外设
linux·github·嵌入式
小猿姐1 天前
唯品会大规模数据库云原生实践:基于 KubeBlocks 管理数千实例的统一运维之路
运维·elasticsearch·云原生
七歌杜金房2 天前
我终于又有了自己的 Linux 电脑
linux·debian·mac
SkyWalking中文站2 天前
认识 Horizon UI · 5/17:3D 基础设施地图
运维·监控·自动化运维
tntxia3 天前
linux curl命令详解_curl详解
linux