跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
CPay

Linux 构建工具核心:make、进度条与 Git 仓库管理

围绕 Linux 开发中的三个常见主题展开:用 make 和 Makefile 管理多文件工程的编译与清理,说明依赖关系、Tab 语法、.PHONY 和自动变量的用法;结合缓冲区刷新、\r 和 fflush(stdout) 讲清倒计时与进度条的实现;最后整理 Git/Gitee 的本地仓库初始化、提交、关联远程与后续推送流程。

flc发布于 2025/10/19更新于 2026/9/1246 浏览
Linux 构建工具核心:make、进度条与 Git 仓库管理

一、make 与 Makefile 的关系

在 Linux 开发里,项目一旦从几个文件扩展到几十个、上百个源文件,手动敲 gcc 命令就会变得很吃力:编译参数容易漏,依赖关系也不好维护。make 和 Makefile 正是为了解决这类问题而生的。

  • make 是命令行工具,负责读取规则并决定哪些文件需要重新构建。
  • Makefile 是规则文件,make 会按照它里面写好的依赖关系和执行命令去工作。

简单理解就是:make 负责执行,Makefile 负责描述'怎么做'。

二、Makefile 的基本写法

写 Makefile 时,最核心的是把'目标、依赖、方法'这三件事讲清楚。

  • 目标:最终要生成什么,比如可执行文件 Hello。
  • 依赖:目标由哪些文件生成,通常是 .c、.h 文件。
  • 方法:具体怎么生成目标,一般就是编译命令。

一个典型的规则长这样:

Hello: main.o func.o
	gcc -o Hello main.o func.o

main.o: main.c
	gcc -c main.c

func.o: func.c
	gcc -c func.c

.PHONY: clean
clean:
	rm -f *.o Hello

这里有几个地方很容易踩坑。

1. 命令前面必须是 Tab

Makefile 里目标下面的执行命令前面不是空格,而是 Tab。这一点非常关键,很多人第一次写都会卡在这里。

2. make 是按时间判断是否需要重建

make 不会每次都无脑重编译,它会比较文件的修改时间:如果依赖文件比目标文件更新,就说明目标需要重新生成。

这也是为什么你执行过一次 make 之后,再次执行时可能提示'没有需要更新的目标'。如果你改动了源文件,却没有触发重新编译,可以用 touch 刷新文件时间戳,或者直接修改源文件内容。

3. .PHONY 让伪目标更可靠

像 clean 这种目标,本质上不是一个真实文件。为了避免目录里刚好有个同名文件导致执行异常,通常会写成:

.PHONY: clean

这样 make clean 就会始终执行,不受同名文件影响。

4. 常用自动变量

Makefile 里有几个很实用的自动变量:

  • $@:目标文件名
  • $^:所有依赖文件
  • $<:第一个依赖文件

例如:


	gcc -o  
Hello: main.o func.o
$@
$^

这种写法更简洁,也更适合后期维护。

三、使用流程

实际使用时,通常就是这几步:

  1. 在项目目录下创建 Makefile 或 makefile。
  2. 把编译规则写进去。
  3. 直接执行 make,生成可执行文件。
  4. 需要清理时执行 make clean。

如果规则写得合理,后续修改某个源文件后,再次执行 make 时,它只会重新编译受影响的部分,不会把整个项目重新来一遍。这就是 make 真正省时间的地方。

四、系统程序里的进度条实现

进度条这类小程序,看起来简单,背后其实很能说明问题:它依赖的是终端输出、缓冲区刷新,以及回车符 \r 的配合。

1. 缓冲区和换行

在终端里,printf 的输出并不一定会立刻显示出来,很多时候它会先进入缓冲区。只有满足某些条件时,数据才会真正刷到屏幕上。

常见的触发方式有两种:

  • 遇到 \n,在行缓冲模式下通常会刷新;
  • 主动调用 fflush(stdout),强制刷新标准输出缓冲区。

这里要注意,fflush(stdout) 不是 Linux 指令,而是 C 标准库函数,它的作用就是把缓冲区里的内容尽快推到终端。

\r 和 \n 的区别也值得单独拎出来看:

术语英文缩写ASCII 码转义字符作用
回车CR0x0D\r回到当前行开头
换行LF0x0A\n移到下一行

进度条一般会用 \r 回到行首,然后覆盖原来的内容,这样就能制造出'原地更新'的效果。

2. 倒计时的思路

倒计时的实现并不复杂,核心就是'打印内容 -> 刷新缓冲区 -> 休眠 -> 继续下一轮'。

如果不手动刷新,输出可能会一直攒在缓冲区里,直到程序结束才一次性显示出来,那就看不到动态变化了。

五、一个简单的进度条实现

进度条通常由三部分组成:头文件、主函数、具体逻辑函数。思路很直接,但真正运行时,\r 和 fflush(stdout) 缺一不可。

头文件

#ifndef PROGRESS_H
#define PROGRESS_H

void progress_bar();

#endif

主函数

#include "progress.h"

int main()
{
    progress_bar();
    return 0;
}

进度条逻辑

#include <stdio.h>
#include <unistd.h>
#include "progress.h"

void progress_bar()
{
    int i = 0;
    char bar[101] = {0};

    for (; i <= 100; ++i)
    {
        bar[i] = '#';
        bar[i + 1] = '\0';
        printf("\r[%s]%d%%", bar, i);
        fflush(stdout);
        usleep(100000);
    }
    printf("\n");
}

这个实现里有两个关键点:

  • \r 会把光标拉回行首,下一次打印就会覆盖旧内容;
  • fflush(stdout) 会强制刷新输出,否则进度变化很可能不会实时显示。

如果你想把它做得更漂亮,还可以继续扩展,比如在进度条两侧加上左右边界、显示加载状态文本,或者把耗时任务包进去,让它更接近真实场景。

六、Gitee 的本地仓库与远程仓库

Gitee 可以理解为代码托管平台,配合 Git 使用时,最常见的流程就是:本地开发、提交到本地仓库、再同步到远程仓库。

本地仓库的意义在于记录开发过程,方便回滚、分支管理和阶段性保存;远程仓库则更偏向协作、备份和统一管理。

1. 配置本地身份

在使用 Git 之前,先配置用户名和邮箱:

git config --global user.name "你的用户名"
git config --global user.email "你的邮箱"

这一步很基础,但很重要。后续提交记录里显示的作者信息,基本就来自这里。

2. 初始化本地仓库

进入项目目录后执行:

git init

执行完成后,当前目录会多出一个 .git 隐藏目录,这就是 Git 仓库的核心数据所在。

3. 提交到本地仓库

常见操作顺序是:

git add .
git commit -m "第一次提交"
git log
  • git add 把文件放入暂存区;
  • git commit 把暂存区内容提交到本地仓库;
  • git log 可以查看提交记录。

4. 关联远程仓库

远程仓库创建好后,需要把本地仓库和远程仓库建立关联。通常会先添加远程地址,再推送第一次提交:

git remote add origin 远程仓库地址
git branch -M main
git push -u origin main

如果你的默认分支是 master,把 main 换成 master 即可。

5. 后续提交

后面的流程就比较顺了:

git add .
git commit -m "修复登录失败问题"
git pull origin main
git push

这里的 pull 不是每次都必须,但在多人协作场景里,先拉取远程最新代码再推送,会更稳妥一些,能尽量避免冲突。

七、删除仓库

如果本地仓库不再需要,直接删除仓库目录即可:

rm -rf 仓库目录

后续如果重新建仓库,只要重新 git init,再按前面的流程走一遍就可以了。

八、总结

make 和 Makefile 解决的是项目构建自动化问题,进度条演示的是终端输出、缓冲区刷新和回车覆盖的机制,而 Git/Gitee 则负责把代码管理、版本记录和远程同步这件事变得可控。三块内容看似分散,其实都很贴近 Linux 开发的日常:写得少一点,重复劳动就少很多,出错的机会也会明显下降。

目录

  1. 一、make 与 Makefile 的关系
  2. 二、Makefile 的基本写法
  3. 1. 命令前面必须是 Tab
  4. 2. make 是按时间判断是否需要重建
  5. 3. .PHONY 让伪目标更可靠
  6. 4. 常用自动变量
  7. 三、使用流程
  8. 四、系统程序里的进度条实现
  9. 1. 缓冲区和换行
  10. 2. 倒计时的思路
  11. 五、一个简单的进度条实现
  12. 头文件
  13. 主函数
  14. 进度条逻辑
  15. 六、Gitee 的本地仓库与远程仓库
  16. 1. 配置本地身份
  17. 2. 初始化本地仓库
  18. 3. 提交到本地仓库
  19. 4. 关联远程仓库
  20. 5. 后续提交
  21. 七、删除仓库
  22. 八、总结

更多推荐文章

查看全部
  • OpenClaw 本地安装与环境配置实战
  • AI 大模型评测方法总结与案例分析
  • Copilot/Codex 中文乱码修复与自动化配置方案
  • C++ 红黑树实现详解:规则、结构与核心操作
  • Qt/C++ 皮肤生成器与界面定制方案
  • C++ 继承机制详解:实现栈、同名隐藏与派生类默认成员函数
  • 大模型本地部署与优化实战指南
  • OpenClaw 接入摄像头实战:WSL2 环境下的 OpenCV 方案
  • GitHub Copilot 接入第三方 OpenAI 兼容模型方案
  • C++20 概念(Concepts):模板参数的语义约束定义
  • C++ STL 容器详解:序列、关联与适配器
  • OpenClaw 全平台安装指南:Windows/macOS/Linux 一键脚本
  • 滑动窗口算法核心思路与经典例题解析
  • 国内如何升级 GitHub Copilot 到专业版
  • 大模型 API 对接指南:OpenAI、Claude 与 LLaMA 3 调用技巧
  • HarmonyOS Stage 模型架构解析与应用指南
  • 基于 LangGraph 与 Mem0 实现 AI Agent 的长期记忆与个性化体验
  • Java 对象比较详解:equals、Comparable 与 Comparator
  • Linux 进程优先级与 O(1) 调度算法详解
  • Dart 设计模式:适配器模式

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online