《Linux 构建工具核心:make 命令、进度条、Gitee》
前引:在 Linux 开发与运维场景中,当我们面对包含数十个甚至上百个源文件的项目时,手动输入gcc编译命令不仅繁琐易错,更会因文件依赖关系混乱导致编译效率极低 —— 修改一个核心头文件后,如何快速定位并重新编译所有关联的源文件?如何统一管理编译选项、输出路径与清理操作?make 指令与 makefile 文件正是解决这些问题的 “利器”!
目录
【一】make与makefile介绍
【二】makefile文件的编写
(1)语法
(2)注意
【三】使用
【四】系统程序-进度条
(1)缓冲区
(2)倒计时实现
(3)进度条实现
【五】Gitee
(1)什么是Gitee
(2)Linux指令Gitee安装
(3)本地与远程关联
(4)提交代码到本地仓库
(5)提交代码到远程仓库
(6)后续提交到远程仓库
【一】make与makefile介绍
首先我们需要知道:make属于命令,makefile(Makefile也可以)属于文件。二者配套使用
make
是一个命令行工具,本质是一个 “构建引擎”。它的核心功能是:根据预先定义的 “规则”,自动判断项目中哪些文件需要重新编译,并执行相应的编译命令,最终生成可执行程序或目标文件
makefile
是一个文本文件(通常命名为Makefile
或makefile
),它是make
工具的 “操作手册”
简而言之:通过执行make命令来调用makefile文件,而过程的实现放在makefile文件里面!
【二】makefile文件的编写
(1)语法
在学习编写之前,我们需要学习依赖关系和依赖方法的概念:
依赖关系:完成某个目标涉及到的对象(例如你想要生活费,那么你应该找你爸)
依赖方法:完成这个目标需要的方法实现(例如你需要各种理由向你爸开口打钱给你)
首先我们打开创建的makefile文件,编写格式解读如下:
首先是目标文件:目标文件代表整个过程输出的可执行程序(例如编译之后需要产生Hello文件)
依赖关系文件:代表生成可执行程序需要涉及到的文件(例如这里是源文件)
依赖方法:代表方法的实现(例如这里采用gcc编译)注:依赖方法前面是 tab 键,不是四个空格
clean:代表自动清理,不需要依赖任何关系文件
(2)注意
(1)clear需要放在执行中间过程的后面,因为makefile的执行是从顶到下的
(2)依赖方法的实现是根据执行关系执行的,例如可以把各个编译过程逐个进行
(3)如果我们make或者make clean了一次之后执行第二次、第三次.....会出现无法执行的问题:
这是因为make的执行是根据源文件或者文件修改时间来判断的,执行 stat 命令可以查看文件的各种信息:例如最近读取时间(一般固定时间刷新)、文件内容修改、元数据修改(大小.....)
我们可以使用 touch 命令来刷新文件的所有信息,只要文件各种数据信息发生变化,就可二次执行make和make file!例如:
而我们一般将clean使用 .PHONY 修饰clean或者目标文件,这样被修饰可以直接二次执行
同时我们可以用 ¥@ 代表目标文件,¥^ 代表后面所有的依赖关系,用 @ 修饰的依赖方法可以在make执行文件的时候不显示具体的执行命令!
【三】使用
现在我有一个完成编写的代码文件:
现在我们来用make和makefile完成源文件到可执行程序:
(1)我们先在当前目录下touch一个命令为makefile/Makefile的文件
(2)vim打开这个文件,完成编写
(3)用make命令执行makefile,生成可执行文件和删除可执行文件
这样我们就完成从源文件到可执行程序再到删除可执行程序的过程!
【四】系统程序-进度条
(1)缓冲区
在开始,回车、换行其实是两个键:
回车是回到当前行的开头,换行是换到第二行但是不回开头,现在将两个键合二为一了!例如:
术语 | 英文缩写 | ASCII 码 | 转义字符 | 核心功能(现代终端) |
---|---|---|---|---|
回车 | CR | 0x0D | \r | 将光标移动到当前行的开头(不换行) |
换行 | LF | 0x0A | \n | 将光标移动到下一行的同一列(不回开头) |
缓冲区:
操作系统在内存中开辟的临时存储区域,你可以这么理解:由用户程序(如 C 语言、Shell 脚本)在用户空间(非内核空间)自行分配的缓冲区,用于暂存程序处理的数据,减少与内核缓冲区的交互次数(即先将程序处理数据存到缓冲区,程序运行完毕,再输出程序结果)而使用 \n
会触发刷新缓冲区,即直接刷新缓冲区,例如:
// 代码1:无换行符,不刷新
#include <stdio.h>
#include <unistd.h>
int main() {printf("hello"); // 数据存入行缓冲,不显示sleep(3); // 等待3秒printf("\n"); // 遇到\n,刷新缓冲区,显示"hello"return 0;
}// 代码2:有换行符,立即刷新
#include <stdio.h>
#include <unistd.h>
int main() {printf("hello\n"); // 遇到\n,立即显示"hello"sleep(3);return 0;
}
(2)倒计时实现
实现思路:输出->刷新缓冲区->(可以使用sleep控制休眠)->循环
补充:
fflush(stdout)
并非 Linux 系统指令,而是 C 语言标准库(stdio.h)中的一个函数,主要作用是 强制刷新标准输出流(stdout)的缓冲区,将缓冲区中暂存的数据立即写入到对应的输出设备(通常是终端或文件),而不等待默认的缓冲刷新条件(如缓冲区满、遇到换行符\n
或程序结束)
这里为什么用函数指令而不是 \n ?
\n
:以换行为主,刷新为辅,仅在行缓冲模式下附带刷新效果,本质是控制字符fflush(stdout)
:以刷新为主,与换行无关,无视缓冲模式(除无缓冲)强制刷新,本质是函数
实现:
我们先创建三个文件,类似C/C++工程项目:
然后像语言那样完成程序的写入和头文件的包含:
然后我们用makefile完成文件的依赖关系准备编译:
我们查看执行结果:
(3)进度条实现
安装上面我们学习的缓冲区原理,我们来做一个简单的进度条!
说明:进度条的实现无非是利用回车或者换行....这些刷新缓冲区,打印结果显示出来
(1)头文件的实现
(2)现在我们来完成main函数的实现
(3)现在我们来完成函数的实现
注意:\r 会回到当行开头,不要放错位置了!
这是基本的实现,有其它想法可以自己利用缓冲区刷新、\r、\n的特性去丰富!
进度条的实现主要是利用了两个关键的地方:
(1)\r 每次打印完回到开头,后面会不断覆盖
(2)fflush(stdout) 直接刷新缓冲区立刻输出,否则会等程序全部跑完一起输出
【五】Gitee
(1)什么是Gitee
可理解为Gitee是用来维护你的代码的,那维护的过程又是怎么样的呢?
个人开发者(你)->提交代码到本地仓库->远程仓库。解释如下:
- 提交到本地仓库:是为了给自己的开发过程 “留痕”,解决 “个人开发中的版本管理、分支并行、回滚需求”,让你敢改代码、不怕出错
- 同步到远程仓库:是为了让团队 “对齐进度”,解决 “多人协作、数据备份、权限管控” 的问题,让团队开发有序、可靠
下面我们开始学习Linux指令版的本地\远程仓库的安装和上传!
(2)Linux指令Gitee安装
(1)首先我们检查是否安装了Gitee:
git --version
(2)如果没有安装Gitee,(Centos)执行下面命令:
yum install git
(3)本地与远程关联
需要输入下面两个指令:
# 替换为你的Gitee用户名(不是昵称,是登录账号)
git config --global user.name "你的Gitee用户名"# 替换为你的Gitee绑定邮箱
git config --global user.email "你的Gitee邮箱"
注意:用户名是@后面的字符
注意:邮箱需要打开设置,在邮箱管理里面即可查看
(4)提交代码到本地仓库
(1)首先进入一个项目目录下
(2)初始化本地仓库
git init
执行后会生成一个隐藏git文件,可以查看:
(3)将文件添加到暂存区
# 添加单个文件(替换为你的文件名) git add 文件名.py# 添加当前目录所有文件(包括子目录,常用) git add .# 添加所有.txt文件(示例) git add *.txt
- 暂存区:临时存放待提交的文件,可多次执行
git add
添加不同文件
(4)提交代码到本地仓库
# -m 后面是提交说明(必须填写,描述本次修改内容)git commit -m "feat: 初始化项目,添加登录功能代码"
例如:
(5)查看本地提交记录
git log # 详细历史(按q退出)git log --oneline # 简洁历史(一行显示一个提交)
例如:
(5)提交代码到远程仓库
首先需要在Gitee上建立一个仓库:选择开源公开最好
(2)创建之后然后选择初始化
(3)点击克隆/下载,复制这个
然后回到Linux指令界面,执行下面命令:
git clone xxxxx
(6)后续提交到远程仓库
可以查看自己仓库是main还是master:
注意:提交需要进入到本次仓库,进入里面创建文件,执行下面一连串指令即可正确提交!
# 1. 假设在本地修改了app.py(修复bug)
vim app.py # 编辑文件(或用其他编辑器)# 2. 将修改的app.py加入暂存区
git add app.py# 3. 提交到本地仓库(写清楚修改内容)
git commit -m "fix: 修复app.py中用户登录失败的bug(处理空密码场景)"# 4. 拉取远程最新代码(避免冲突)
git pull origin master# 5. 推送到远程仓库(让团队看到修改)
git push
(7)如何删除
如果删除我们需要使用 rm -rf 仓库名
后面要建立新的仓库,直接跳到(5)开始操作即可