make
和 makefile
是 Linux
/Unix
开发环境中用于自动化构建的强大工具,尤其在多文件编译的项目中,用于管理文件之间的依赖关系和构建规则。通过定义编译规则,Make工具可以根据源文件的更新情况,自动决定哪些部分需要重新编译,从而提高开发效率。Make
make
是一个自动化构建工具,通过解析 makefile
文件中的规则,管理项目的构建流程。它的主要功能是根据源文件的修改情况,自动更新目标文件,避免手动输入复杂的编译命令。
make
的主要功能make
工具执行 make
命令时,make
会自动查找当前目录下的 Makefile
或 makefile
文件,并根据文件中的规则执行第一条命令(其余的需要显示调用):
make
Makefile
的基本结构Makefile
是定义构建规则的文件,其核心部分是规则描述。每一条规则的基本格式如下:
Target : Dependencies
Command
Target
):需要生成的文件或任务。Dependencies
):生成目标所需的文件或条件。Command
):实现目标的具体操作,需以Tab键开头。code:code.c
gcc code.c -o code
.PHONY:clean
clean:
rm -f code
具体说明:
code
是需要生成的可执行文件,其生成需要依赖 code.c
文件,通过 gcc code.c -o code
生成。clean
的作用是清理生成的 code
文件,但是没有直接跟 code
关联,需要显示调用 make clean
来清除 code
以便重新编译。.PHONY
修饰 clean
,clean
就会成为伪目标,伪目标是指不对应具体文件的目标,常用于定义清理任务或其他辅助操作,其特性就是总是能够被执行,原因在于 .PHONY
让 make
忽略源文件和可执行文件的 Modify
时间补充:
文件的相关时间有3个,可以通过 start
来查看。
补充:
执行 make
时,code
被编译成 code.c
,之后当文件内容没有发生更改时,是无法再次 make
的,这是通过比较 code.c
与 code
的修改时间 (Modification Time
) 来做到的,当 code.c
的修改时间早于 code
的修改时间时就无法再次 make
。
而.PHONY
的作用就是让 make
忽略源文件和可执行文件的 Modify
时间,哪怕文件没有修改就可以执行 make
。
makefile
支持变量的定义,便于规则复用和代码维护。变量的值可以在定义时赋值,也可以在命令行传入;也提供了一些自动变量,用于简化规则中的目标和依赖项引用。
# 定义变量
CC = gcc
TARGET = main
OBJS = main.o utils.o
# 默认目标
$(TARGET): $(OBJS)
$(CC) -o $@ $^
# 自动生成目标文件
%.o: %.c
$(CC) -c $< -o $@
# 清理目标
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET)
\$(CC)
:变量CC的值,其他变量同理。$@
:当前规则的目标文件名。$<
:当前规则的第一个依赖项。$^
:当前规则的所有依赖项。%.o: %.c
:所有的.o文件都可以通过对应的.c文件生成Make
和 Makefile
的优缺点优点
缺点
CMake
)简化管理。倒计时
#include <stdio.h>
#include <unistd.h>
int main()
{
int i = 10; // 初始化计数器 i 为 10
while(i >= 0) // 当 i 大于等于 0 时,进入循环
{
printf("%-2d\r", i); // 使用 %-2d 格式化输出 i,左对齐,保证占用 2 个字符的宽度,并且在输出后添加回车符 \r
fflush(stdout); // 刷新输出缓冲区,强制将数据立即输出到屏幕上
i--; // i 每次递减 1
sleep(1); // 程序暂停 1 秒
}
return 0;
}
代码解析:
%-2d
:在 printf
中,%-2d
是用来打印整数的格式化字符串。%-2d
表示将数字左对齐并且占用至少 2 个字符的宽度。假设 i
是个位数时,输出会带有一个空格,如 1、 2 等。这样保证打印数字时,光标位置不会被打乱。、\r
:回车符 \r
的作用是将光标移动到当前行的最前面。因此,每次打印一个新的数字后,光标会回到行首,覆盖之前打印的数字,达到每次更新显示数字的效果。fflush(stdout)
:printf
输出通常是缓冲输出,也就是说数据会先保存在缓冲区中,直到缓冲区满或者程序结束时才会输出。为了确保每次打印的数字能够立即显示在屏幕上,使用 fflush(stdout)
强制刷新缓冲区。sleep(1)
:sleep(1)
使得程序每次打印数字后会暂停 1 秒,形成倒计时的效果。进度条
#define NUM 101
#define STYLE '#'
double total = 1024.0; //总下载量(1024 MB)
double speed = 1.0; //下载速度 (每次增加 1MB)
void process_v2(double cur)
{
char buffer[NUM]; // 用于存储进度条的字符数组
memset(buffer, 0, sizeof(buffer)); // 初始化数组,将所有元素置为 0
const char* lable = "|/-\\"; // 动态指示器(显示的符号)
int len = strlen(lable); // `lable` 字符串的长度(4)
static int cnt = 0; // 静态变量,记录动态符号的位置
cnt %= len; // 每次更新时,cnt 取值为 0~3,用来循环显示 `|/-\`
int num = (int)cur * 100 / total; // 当前下载进度的百分比
int i = 0; // 根据当前进度填充进度条
for(;i < num;++i)
buffer[i] = STYLE;
double rate = cur / total; // 计算当前进度的比例
printf("[%-100s][%.1lf%%][%c]\r", buffer, rate * 100, lable[cnt]); // 输出进度条、百分比和动态符号
fflush(stdout); // 刷新输出缓冲区,确保立即显示
cnt++; // 更新动态符号的索引
}
void DownLoad()
{
double cur = 0; // 当前下载量初始化为 0
while(cur <= total) // 当下载量小于等于总下载量时,持续更新进度条
{
process_v2(cur); // 调用 process_v2 更新进度条
usleep(5000); // 暂停 5 毫秒,模拟下载过程
cur += speed; // 每次增加 1MB
}
printf("\ndownload %.2lfMB Done\n", cur); // 下载完成后输出提示信息
}
int main()
{
DownLoad(); // 启动下载过程
return 0;
}
代码解析:
NUM
是定义的进度条长度(101 个字符)。STYLE
是进度条中用来表示已下载部分的符号(#
)。total
表示总下载量(1024 MB)。speed
定义了每次增加的下载量(1 MB),表示每次下载的增量。process_v2
函数 buffer
数组用于存储进度条的显示状态,长度为 NUM
(101)。lable
字符串包含 4 个字符 |
, /
,-
, \
,通过变量 cnt
控制这些字符的循环显示,给人一种“加载中”的感觉。num
= (int
)(cur
* 100 / total
) 计算当前下载量 cur
相对于总下载量 total
的百分比,然后用这个百分比来填充进度条。printf
输出格式化的进度条,%-100s
表示左对齐且占据 100 个字符的空间,%.1lf%%
显示进度百分比,[%c]
显示动态字符。fflush(stdout)
确保每次进度条输出后立即刷新,避免缓冲区延迟输出。DownLoad
函数 cur
是当前已下载的量,初始值为 0。while(cur <= total)
循环执行,直到下载量达到总量 total
。process_v2(cur)
更新进度条,并暂停 5 毫秒(usleep(5000)
),然后增加下载量。cur
超过 total
后,跳出循环并打印下载完成信息。该程序会动态显示一个进度条,模拟下载进程。屏幕输出会类似如下:
[##########################################----------------------------------------][50.0%][|]
[####################################################------------------------------][70.0%][-]
[###############################################################------------------][90.0%[\]
[##################################################################################][100.0%]\]
download 1024.00MB Done
Have a good day😏
See you next time, guys!😁✨🎞
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有