< 6 > Linux 自动化构建工具:makefile 详解 + 进度条实战小项目

1. 自动化工程构建 make / makefile ------ 前置语法知识讲解

make是一个命令

makefile是一文件------描述的是如何编译当前工程
先看看怎么使用的:

1.1 依赖关系,依赖方法

makefile:依赖关系 和 依赖方法 的集合!
依赖关系:我(code.c) 和 我爸(code),我依赖我爸。我们是依赖关系

依赖方法:我可以找我爸拿生活费,我爸可以让我干事情

有了依赖关系,那还要有依赖方法,事情才能干成。不能只挂名,不干事

1.2 make执行时,会默认只执行第一个目标文件,及其依赖方法

make执行时,会默认执行第一个出现的目标,及其依赖方法
这也就是为什么,刚刚 make 会直接执行gcc命令,因为code 是从上到下 第一个目标,gcc是其依赖方法

如果反过来,那就先执行rm了!

1.3 makefile自动编译推导过程

其实:

  • make 内部维护一个栈,从第一个目标开始解析;
  • 如果目标无法直接生成 ,就把它的生成方法压入栈 ,然后向下查找能生成该依赖的目标;
  • 重复这个过程:无法生成 → 压栈 → 继续向下找 ,直到找到最底层能直接生成的文件(如 .c 文件);
  • 找到后,开始弹栈执行所有方法;
  • 因为栈是后入先出 ,所以执行顺序和压栈顺序完全相反,从最底层一步步向上生成,最终完成第一个目标

总结:

无法直接生成目标文件,就会 方法压栈 + 向下递推,直到找到能执行的方法+依赖链闭环,再全部弹栈,最终生成目标文件 ,找不到就报错,停止。
依赖关系相对应,逻辑闭环,就会压栈此方法 并 返回弹栈,但是依赖方法执行不了,就会报错中止,后面的方法不再执行。

1.4 构建工程,清理工程

1.5 .PHONY ------ 伪目标

.PHONY :伪目标 也是 目标,也有依赖文件,依赖方法

它的意义是:强制执行依赖方法!总是执行当前依赖方法

最佳实践:clean等,清理工程的方法,都建议用 .PHONY 修饰! 其他都不建议!

1.6 增量编译 / 有效编译 ------ 提高编译效率,不让重复编译

1.7 ACM时间 ------快速定位被修改的文件

之前说过:Access,Modify,Change,3个文件的时间信息。

再次复习一次:

名称 核心含义 触发更新的操作 make 是否关注?
Access 文件被读取 / 打开的时间 访问,打开文件、读取文件内容 ❌ 不关注
Modify 文件内容被改动的时间 写入、追加、覆盖文件内容,内容实质性变化时 ✅ 核心判断依据
Change 文件元数据被改动的时间 修改权限、重命名、修改文件大小等文件元信息 时,并且Modify时间变了!Change时间一定改变 ❌ 不直接关注

1.71 文件M时间改变,make必定重新编译

make 会读取 M 时间 : 文件内容被修改,M时间更新。

一旦M时间更新,就代表可能更新编译结果,make就必须重新编译它!

1.72 短时间高频访问,A时间不会每次都改变

读取文件内容指令,几乎是最高频的命令。这意味着A时间会频繁改动。但是它又没有实质性的内容,信息变动,又显得不那么重要!

所以Linux对A时间有更新策略:短时间高频访问,视为一次动作!不会多次改变A时间!

目的是减少多次"几乎无意义"的更新,以提高Linux效率!

2. Makefile 的 实用语法指令

2.1 @ ^ ------ 目标文件 和 依赖文件列表

$@ 代表目标文件

$^ 代表依赖文件列表

2.2 B=A ------ 全局定义变量名,类似于C的宏替换

B=A ------ 全局定义变量名,类似于C的宏替换

等号两边不建议空格,实用例子:

2.3 @ ------ 避免指令语句回显,打乱观察

2.4 $(A) ------ 原文件名可被 echo 打印,用于debug

2.5 $< ------ 将依赖文件列表所有文件,逐个编译

2.6 %.c %.o ------ 展开当前文件所有.c / .o 文件

有了它,才是真正的泛型编程!上面都是对单,这下可以对群!整体自动推导,整体编译!


整体替换:

2.7 (shell ls \*.c) ------ ()表达式可以写入shell指令

2.8 $(Src:.c=.o) ------ 将Src的所有.c文件变为同名.o

2.9 $(wildcard *.c) ------ 函数,自动获取所有 .c 文件

3.0 makefile 最终版本

3. Linux 第一个 系统程序 ------ 进度条

3.1 前置知识:\r\n 与 \n :回车换行 与 换行

我们经常混淆回车,换行,回车换行 这三个概念,以为都** 是换到下一行**,实际上:

名称 转义符 作用(核心含义)
回车 \r 光标回到当前行的开头 ,不换行
换行 \n 光标换到下一行,不回到行首
回车换行 \r\n 回到行首 + 换到下一行,完整换行

C/C++ 的换行,其实是回车换行! 实际上应该是:\r\n

3.2 前置知识:printf存在缓冲区,不会立刻打印内容,fflush立即刷新

编写一段程序:包含:打印内容,休眠3秒


为什么? 难道是先执行sleep,然后执行printf吗?

不是!C/C++程序是严格按照上到下的顺序执行,执行sleep前,printf一定执行完毕!

答案是:已经打印好了,但是缓存在内存缓存区里了!程序结束时,会强制刷新缓存,缓冲区会自动刷新,把缓存中的内容,一次性全打打印到屏幕上
怎么才能立即刷新?

\n 或者 fflush(stdout) :这两个可以立即刷新!

3.3 前置知识3:\r 的作用 ------ 回到行首,作用:覆盖上一次的结果

3.4 进度条纯享版------展示功能

我的问题:

1.没注意宏定义

2.命名不够规范

3.旋转光标,我写了字符数组,不够规范

另外还有头文件、主函数测试用例文件,简单调用声明

3.5 进度条进阶版------可实际使用

相关推荐
小码哥_常2 小时前
一套自己部署的 IM,客户端是同一份 Flutter
前端·后端
Decay__3 小时前
05_MySQL 常用 SQL 大全 —— 诊断、管理、优化辅助 SQL 与三大系统库速查
运维·数据库·sql·mysql·架构
贞明电子5 小时前
工业三色报警灯怎么接入项目系统?开关量与RS485控制应用指南
运维·网络·微信公众平台·贞明电子
学长毕设5 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
HideF5 小时前
Linux
linux·服务器·网络
万联WANFLOW5 小时前
海外网络故障怎么排查?Cloudflare 三季度断网报告解读与 mtr 实战
运维·网络·故障分析
ZhuoAIStage6 小时前
舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线
人工智能·自动化·工作流编排·舞台工艺·审图智能体
Ruiery7 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
努力的小雨7 小时前
给 AI 眼镜开发应用有多难?我从零做了一个陪练,还上架了
后端
乌恩大侠8 小时前
从 AI-RAN 到 AI Agent:基于 NVIDIA Nemotron 构建 5G/6G 智能网络故障诊断系统
服务器·人工智能·5g·o-ru·ai-ran·电信大模型