当前位置: 首页 > news >正文

《Linux系统编程》5.Linux基础开发工具(中)-makefile,进度条

💡Yupureki:个人主页

✨个人专栏:《C++》 《算法》《Linux系统编程》


🌸Yupureki🌸的简介:


目录

1. make/makefile

1.1 makefile基本语法

1.2 使用变量

1.3 伪目标

1.4 自动变量

1.5 基本用法

2. 第一个Linux程序:进度条

2.1 缓冲区初识

2.2 进度条


1. make/makefile

我们在Linux中把源文件编译成可执行程序时需要手动输入命令,让gcc/g++编译

但是这样就很麻烦,假如我们有个很大的项目,源文件众多,一个一个打就很不舒服

因此就引入了一个自动化执行命令的工具-makefile

make是 Linux/Unix 环境下一个非常实用的构建自动化工具。它通过读取一个名为Makefile(或 makefile)的文件,自动判断大型程序中哪些部分需要重新编译,并执行相应的命令来完成编译、链接等任务。简单来说,make 帮助开发者管理项目构建过程,避免每次都手动输入冗长的编译命令。

1.1 makefile基本语法

创建makefile

使用touch创建makefile或者Makefile

注意:

不能带后缀,名字只能是makefile或者Makefile

makefile基本语法

Makefile 的核心是规则,一个规则的基本格式如下:

目标: 依赖文件列表 <TAB> 命令
  • 目标:通常是要生成的文件名,也可以是伪目标(如clean)。

  • 依赖文件列表:生成目标所依赖的文件,多个文件用空格分隔。

  • 命令:由一到多条 shell 命令组成,每条命令前必须有一个 Tab 键开头(不能用空格代替)。

如:

test:表示要生成的目标文件

test.cpp:表示依赖的文件(生成test需要test.cpp)

下面的g++ test.cpp -o test 表示具体的指令(由你来定)

在makefile编写完后,在命令行中输入make,就自动执行当前目录下的makefile文件内容了

推导过程:

makefile的推导推导过程自上而下

test需要test.o,而test.o不存在,又需要test.s来创建......,以此类推到test.cpp源文件,然后从下到上推导

1.2 使用变量

可以定义变量来简化 Makefile:

在makefile的前面定义变量,然后在具体方法中用$(变量名)来代替,在执行的时候可以当作宏替换,自动将$(C)替换为了g++

1.3 伪目标

伪目标不代表实际文件,用于执行一些特定操作(如清理文件)。需要用.PHONY声明:

执行make clean就会执行rm命令。

1.4 自动变量

make 提供了一些自动变量,方便在命令中引用:

  • $@:表示规则中的目标。

  • $<:表示第一个依赖文件。

  • $^:表示所有依赖文件(去重)。

这有两个推导过程

第一个推导过程的$^表示所有的依赖文件,而hello依赖hello.o和main.o,因此自动填入这两个文件。而$@表示目标文件,因此是hello

第二个推导过程的$<表示第一个依赖文件,就是hello.c

1.5 基本用法

在命令行中执行make命令时,如果不指定目标,则默认执行 makefile 中的第一个目标。

常用选项:

  • make target:构建指定的目标(如make clean)。

  • make -f 文件名:指定使用的 Makefile 文件(默认是Makefilemakefile)。

  • make -n:打印出要执行的命令,但不实际执行(用于调试)。

  • make -j N:并行执行 N 条命令,加快构建速度。

2. 第一个Linux程序:进度条

2.1 缓冲区初识

我们先来观察下面几种现象

#include <stdio.h> #include <unistd.h> int main() { printf("hello world\n"); sleep(3);//Linux中的sleep函数的库文件是<unistd.h> return 0; }

我们发现在程序休息前就打印出了hello world

那如果把\n去掉呢?

我们发现程序休息前没有打印hello world,而在程序结束后打印了

那如果在printf后面强制刷新缓冲区会怎么样?

我们发现在程序休息前就打印了

这是因为我们printf打印"hello world"时并不是直接往显示器上打,而是先存在一个缓冲区

只有当满足一定条件时,才会刷新

而如果字符串带了\n或者\r,则不会存在缓冲区内,而是直接刷新到显示器上,这就是行刷新

为什么要设计缓冲区?

最主要的原因:减少系统调用,提升效率

printf最终需要通过系统调用(如write)将数据发送给内核,再由内核驱动显示到终端。系统调用的开销较大(涉及上下文切换、权限检查等)。如果每次输出一个字符或短字符串都立即执行系统调用,那么频繁的调用会严重拖慢程序运行速度。

缓冲区的作用:将多次小数据合并成一次大数据块,再通过一次系统调用发送出去。这样能大幅减少系统调用次数,显著提升吞吐量。

例如,循环输出1000个字符,如果每次putchar都立即刷新,就需要1000次write;而缓冲后可能只需几次甚至一次write

2.2 进度条

我们要设计一种动态加载的下载进度条,那么我们要先设计一个download函数,每秒下载多少数据

double total = 1024.0;//总共1024MB数据 double speed = 1.0;//一定时间内下载1MB数据 void DownLoad() { double current = 0; while(current <= total)//循环,知道下载完成 { FlushProcess(total, current);//刷新缓冲区 // 下载代码 usleep(3000); current += speed;//一定时间内下载speed个数据 } printf("\ndownload %.2lfMB Done\n", current); }

至于刷新,我们知道如果不带\r和\n就会写到缓冲区内,因此我们带上\r,保证一个循环自动更新进度条

对于具体的刷新函数,我们需要传入一共要下载多少的数据,和当前下载了多少数据,进行比例计算,这样不仅能以百分比显示下载进度,还能计算填充多大的进度条

void FlushProcess(double total, double current)//一共要下载多少数据,现在下载了多少 { char buffer[NUM]; memset(buffer, 0, sizeof(buffer)); const char *lable="|/-\\"; int len = strlen(lable); static int cnt = 0; // 不需要自己循环,填充# int num = (int)(current*100/total); // 11.0 / 1000(比例计算) int i = 0; for(; i < num; i++) { buffer[i] = STYLE;(根据比例,填充进度条) } double rate = current/total; cnt %= len; printf("[%-100s][%.1f%%][%c]\r", buffer, rate*100, lable[cnt]); cnt++; fflush(stdout); }

到了具体的main函数,只需要调用download函数即可

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

测试:

http://www.jsqmd.com/news/425071/

相关文章:

  • 光甘草定为什么能够实现安全美白?附2026美白去黄水乳推荐 - 资讯焦点
  • P7687 [CEOI 2005] Critical Network Lines TJ
  • 贪心做题笔记
  • 32并发输出速度519.87t/s!四卡T10(Turing, sm75) Qwen3-27B-FP8 并发吞吐量测试
  • 小学剑桥原版线上英语课推荐|家长实测不踩坑,选课直接抄作业 - 品牌测评鉴赏家
  • 现在分词
  • 从技术到口碑,惠耳神逸助听器彰显国产硬核实力 - 资讯焦点
  • 初中英语提分难?6个宝藏学习平台实测推荐,覆盖同步、口语、冲刺全场景 - 品牌测评鉴赏家
  • 2026年特氟龙输送带TOP10厂商评测排名 - 资讯焦点
  • 口碑较好的小型冰箱排行榜——2026年非常值得入手的选项 - 资讯焦点
  • 2026实测|初中英语线上辅导机构哪家好?避坑不花冤枉钱,家长直接抄作业 - 品牌测评鉴赏家
  • 2026线上少儿英语培训班推荐|家长闭眼抄作业不踩坑 - 品牌测评鉴赏家
  • 揭秘 Qt 的底层黑魔法:元对象系统 (MOS) 与元对象编译器 (MOC) 深度解析
  • 2026年知名的振动温度传感器厂家行业热门推荐 - 品牌鉴赏师
  • 小学生剑桥英语选课指南,3大主流品牌实测,新手家长直接抄作业 - 品牌测评鉴赏家
  • 西门子PLC结构化编程_数值改变检测标准块
  • 初中生必看|3款剑桥原版线上英语课实测,告别无效刷题 - 品牌测评鉴赏家
  • 2026男士防脱产品哪个牌子最好?十大明星级防脱生发品牌排行榜推荐,榜首效果惊艳 - 资讯焦点
  • 小学0基础线上英语课推荐|家长实测不踩坑!新手娃入门抄作业 - 品牌测评鉴赏家
  • NMN哪个牌子好?2026年全球NMN品牌深度横测:认准三项硬核指标 - 资讯焦点
  • 小学生线上剑桥英语选课|实测3家热门款,闭眼抄作业不踩坑 - 品牌测评鉴赏家
  • LangGraph4j 学习系列(7)-流式响应
  • hi3519dv500 Tsensor驱动
  • 基于深度学习的YOLO目标检测+智能计数系统之木材数量计数图像数据集 树木卡车图像计数数据集 detr图像数据集第10115期
  • TinyTeams.xyz:小团队创造大奇迹的科技名人堂
  • 基于机器学习的无人机的人群密度分析图像数据集 人员密度图像识别 无人机巡逻巡检人群数据集 cnn人员密度检测
  • 对于 UTF-16 的高低代理项码点的解析
  • 具身智能2026年产业图谱:智平方引领下的技术分化与价值落地
  • 春晚带火具身智能!2026 核心技术推荐 五强企业解锁智能新未来
  • PMMA塑料光纤怎么提高耐热性