【Linux】项目自动化构建工具make / Makefile 及进度条小程序

简介: 【Linux】项目自动化构建工具make / Makefile 及进度条小程序

👉make项目管理器的基础👈


在实际应用中,一个 C 语言的工程项目常常由多个文件组成,此时为了对多个文件进行管理和处理,可以使用 make 项目管理器。


使用项目管理器的主要目的是用于管理较多的文件。在上一篇博客介绍过 C 语言代码的编译过程分为预处理、编译、汇编和链接,其中编译阶段仅检查语法错误以及函数与变量是否被正确地声明了,在链接阶段则主要完成函数链接和全局变量的链接。因此,那些没有改动的源代码根本不需要重新编译,只要把它们重新链接进去就可以了。这是, make 项目管理器就应运而生了。


实际上,make 项目管理器也就是个“自动编译管理器”。这里的“自动”是指它能够根据文件的时间戳自动发现更新过的文件而减少编译的工作量,同时其通过读入 makefile 文件的内容来执行大量的编译工作。用户只需编写一次简单的编译语句就可以了,所以大大提高了实际项目的工作效率。


注:make 是一个命令,而 makefile 是一个文件。


👉makefile的基本结构👈


makefile 是 make 项目管理器中使用的配置文件,其通常有一下几个部分组成。

目标体:make 项目管理器生成的目标文件或者可执行文件。

依赖文件:make 项目管理器创建目标体所需要的文件,通常是 C 语言的源文件和头文件等。

相关操作命令:make 项目管理器使用依赖文件来创建目标体所需要的命令,这些操作命令必须以制表符(Tab)开头。

makefile 存在的意义就是为了构建项目。

注:Makefile 也是可以的。


Makefile 文件样例


616edd32729e45a992f82119ff0691a6.png

0ef7660adc434cc1ae56ff2461e1a18b.png

make clean 清理文件

67baa4ad904d49cbbf4026bf5e03e248.png


7ada998ceb3a4142875af02aba0683b0.png


02d1cb4972a240f0804920d735bc7969.png


上图告诉我们,可执行程序 mycode 已经是最新了。为什么会这样呢?系统是如何得知的呢?为了解决这个问题,我们先来想一个问题:如果一份源代码没有任何的修改,该代码是否还需要再编译一次呢?答案是,肯定不需要。


虽然 make 指令连续使用,系统会提示你。但是 make clean 指令连续使用,系统并不会提示任何的信息。


1e9cc7fc9e9447ffb77ad87b06414448.png


其实这就是.PHONY的作用所在。被.PHONY关键字修饰的对象是伪目标,伪目标总是会被执行相关操作命令的。其实我们所要生成的目标体,也可以用.PHONY关键字修饰,那么 make 指令就可以被连续执行了。但是通常来说,我们所要生成的目标体是不需要被.PHONY关键字修饰的。

bcd771712bfe49fab0132b773d1918af.png4dd958c9f5024aa3b053784439041f7d.png


那么,我们现在来回答上面的问题:gcc 是如何得知我们的源代码不需要再编译了呢?这就需要涉及文件的三个时间了。

e243f1247774424caccee8df7baa6ab7.png

4c3d710db84949bb8b212464d95c9d5d.png

ac05fdadbe0f4d03b0099dfe0f9bdbf7.png


上图所示,我们多次访问 mycode.c 文件,但该文件的访问时间 Access 却没有变化,这是为什么呢?在之前,只要你访问了文件,那么文件访问时间 Access 就会改变。但是现在不会。因为在操作文件的时候,访问文件的操作比较多;如果每访问文件一次,就修改文件的访问时间 Access,那么 Access 时间将会被频繁地修改,这就需要进行更多次的 IO。而且文件的访问时间 Access 也不是特别的重要。所以新的 Linux 系统要求一段时间后访问文件,才会修改文件的访问时间。


知道了文件的三个时间,我们就能回到上面的问题了。第一次编译时,源代码的修改时间肯定是早于可执行程序的修改时间的。如果源代码的修改时间晚于可执行程序的修改时间,那么就需要重新编译源代码,否则不需要编译源代码。

d1cd4a2c96954dbea4078ab95649a2ff.png

touch 已经存在的文件 #将文件的时间更新为现在的时间


1f7f099df6fd4132827c9a2103f3c8f9.png


那么,.PHONY关键字就是不管源文件和可执行程序的修改时间的新旧,你只要帮我重新编译就行了。


注:makefile 中的第一个目标体,使用 make 命令时可以省略目标体名称。make 命令默认从上到下执行,执行形成一个目标体,形成一个目标体后,后面的相关操作命令便不会执行了。


cf842cdb328e429aa01fd0e7011d75f7.png

makefile 的依赖关系


6d71b6e9b4624755b30d578ee8e45ef9.png


:不建议这么来写 makefile 文件。


👉小程序进度条👈


缓冲区问题


sleep 函数原型


9b6cd007c79d4370adc279cbd2fddb01.png


1de309d88e5b423387aeed670f702b44.png

dd9038654c97486bad563548d6bb9bfe.png


现象:先打印字符串"you can see me...",然后睡了两秒。

e92792616cc849bd811932a516a805cb.png


d486e2e79fad4bbc9ddc0caeb5ee8001.png

现象:先睡两秒,再打印字符串"you can see me..."。


关于第二个列子的现象,首先执行的一定是 printf 函数,因为我们的代码是顺序结构。先执行 printf 函数不代表数据先显示。所以该现象的解释就是已经执行 printf 函数,只不过该数据没有被立即显示出来。睡完两秒后,数据才被刷新出来。那休眠的期间,printf 函数一定执行完成打印了,那么对应输出的数据在哪里呢?答案是在缓冲区里面!


那如果我们想要 print 函数打印的内容立即显示出来,怎么才能做到呢?答:调用 fflush 函数刷新缓冲区。


3f7bee8790874581a021f158f2e90ce0.png


11e1b58f6f19498c9a5912903c6a6dcd.png


cc976a08d3544ae9a3bd5977cf1abc0a.png


那想问大家一个问题:为什么第一个例子中加了个'\n'就能够马上打印内容呢?其实'\n'是行缓冲,有'\n'的话,就会把一行内容刷新出来,没有就不刷新。

现象:先打印字符串"you can see me...",然后睡了两秒。


回车和换行


  • 回车\r是回到当前行的最开始
  • 换行\n是换到下一行
  • 一般而言,\r\n是回车换行。但在语言层面上,\n就是回车换行


补充知识:显示器为什么能显示各种符号?显示器面板上有各种像素点,那么点亮显示器上对应的像素点就能显示各种符号了。凡是显示到显示器上的东西,都是字符。


倒计时程序


#include <stdio.h>
#include <unistd.h>
int main()
{
    int cnt = 10;
    while(cnt)
    {
        printf("剩余时间:%2d\r",cnt--); // %2d一次刷新两个字符
        fflush(stdout); // 刷新缓冲区
        sleep(1); // 休眠一秒钟
    }
    return 0;
}


进度条程序


dc76a777f5e54c32b6c891cff1399989.png


注:头文件不用在 makefile 里写,编译器能够在当前目录下找到。


// makefile文件里的内容,注:-D N=1为命令行参数
ProcessOn:process.c main.c
  gcc process.c main.c -o ProcessOn -D N=1
.PHONY:clean
clean:
  rm -f ProcessOn


// process.h
#pragma once
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define NUM 101
#define S_NUM 5
extern void  ProncessOn(); //函数的声明
// process.c
#include "process.h"
void ProncessOn() //函数定义
{
    int count = 0;
    char bar[NUM];
    memset(bar, '\0', sizeof(bar));
    //reserve
    const char* lable = "|/-\\";
    // 进度条样式
    char style[S_NUM] = {'+', '#', '>', '-', '.'};
    while(count <= 100)
    {
        printf("\033[42;34m[%-100s][%d%%][%c]\033[0m\r", bar, count, lable[count%4]);  //%-s向左对齐
        fflush(stdout);
        bar[count++] = style[N];
        //sleep(1); //sleep参数的单位为秒,休眠时间太长
        usleep(50000);    //usleep参数的单位为微妙
    }
    printf("\n");
}
// main.c
#include "process.h"
int main()
{
    ProncessOn(); //函数调用
    return 0;
}


颜色控制格式


1c054662eb6f4579a1d95f65f325ab1e.png

dc3bef81490a4a00be8dab70c8aa74c9.png



👉总结👈


本篇博客主要讲解 make、makefile 以及 Linux 下的第一个小程序进度条。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️


















相关文章
|
6月前
|
安全 Linux Shell
四、Linux核心工具:Vim, 文件链接与SSH
要想在Linux世界里游刃有余,光会“走路”还不够,还得配上几样“高级装备”。首先是Vim编辑器,它像一把瑞士军刀,让你能在命令行里高效地修改文件。然后要懂“软硬链接”,软链接像个快捷方式,硬链接则是给文件起了个别名。最后,SSH是你的“传送门”,不仅能让你安全地远程登录服务器,还能用scp轻松传输文件,设置好密钥更能实现免-密登录,极大提升效率。
462 4
|
6月前
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
500 16
|
6月前
|
安全 Linux iOS开发
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
290 0
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
|
5月前
|
人工智能 监控 Kubernetes
77_自动化脚本:Makefile与Airflow
在当今AI大模型时代,高效的工作流管理对于模型训练、推理和部署至关重要。随着大模型规模的不断增长和复杂度的提升,传统的手动脚本管理方式已无法满足需求。自动化脚本和工作流调度系统成为构建健壮、可重复、可扩展的LLM Pipeline的关键工具。其中,Makefile作为经典的自动化构建工具,与Airflow作为现代工作流调度平台的结合,为LLM开发团队提供了强大的工作流管理能力。
|
8月前
|
缓存 监控 Linux
Linux系统性能调优技巧和相关工具
Linux 作为一种应用应展和系统服务的优选操作系统,在处理性能和端到端点评估上持有出色表现。但是,在处理进程或系统处于低效状态时,性能调优就显得十分重要。本文将探讨一些 Linux 系统性能调优的常用技巧,并介绍相关工具
223 0
Linux系统性能调优技巧和相关工具
|
8月前
|
Linux 数据安全/隐私保护 iOS开发
推荐Linux环境下效能优良的双向文件同步工具
综合上述条件,对于Linux环境下的双向文件同步需求,Unison 和 Syncthing 是两个非常出色的选择。它们都有良好的社区支持和文档资源,适用于不同规模的环境,从个人使用到商业部署。Unison 特别适合那些需要手动干预同步过程、需要处理文件冲突解决的场景。而 Syncthing 更加现代化,适合需要自动、实时的数据同步与备份的环境。对于选择哪一个,这将取决于个人的使用场景和具体需求。
851 16
|
7月前
|
数据采集 编解码 运维
一文讲完说懂 WowKey -- WowKey 是一款 Linux 类设备的命令行(CLT)运维工具
WowKey 是一款面向 Linux 类设备的命令行运维工具,支持自动登录、批量执行及标准化维护,适用于企业、团队或个人管理多台设备,显著提升运维效率与质量。
|
网络协议 Linux C语言
linux 系统获取网络ip, mask, gateway, dns信息小程序
net_util.c          #define WIRED_DEV                   "eth0"     #define WIRELESS_DEV                "ra0"               #define PPPOE_DEV                   "ppp0" #define DEBUG_PRT(fmt, arg.
1494 0
|
6月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
677 1
二、Linux文本处理与文件操作核心命令
|
6月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
418 137

热门文章

最新文章