【命令行魔法:掌握Linux基础工具开发的独门技艺】(四)

简介: 【命令行魔法:掌握Linux基础工具开发的独门技艺】

【命令行魔法:掌握Linux基础工具开发的独门技艺】(三):https://developer.aliyun.com/article/1425542


4.3原理


  • make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么


1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。


2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“mybin”这个文件, 并把这个文件作为最终的目标文件。


3. 如果mybin文件不存在,或是mybin所依赖的后面的test.o文件的文件修改时间要比mybin这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成mybin这个文件。


4. 如果mybin所依赖的test.o文件不存在,那么make会在当前文件中找目标为test.o文件的依赖性,如果找到则再根据那一个规则生成test.o文件。(这有点像一个堆栈的过程)


5. 当然,你的C文件和H文件是存在的啦,于是make会生成 test.o 文件,然后再用 test.o 文件声明 make的终极任务,也就是执行文件mybin了。


6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。


7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错, 而对于所定义的命令的错误,或是编译不成功,make根本不理。


8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起, 我就不工作啦。


4.4项目清理


  • 工程是需要被清理的
  • 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
  • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
  • 可以将我们的 hello 目标文件声明成伪目标,测试一下。


怎么清理呢?vim打开Makefile        


即命令——“make clean”,以此来清除所有的目标文件,以便重编译。


我们再来改一下vim里面的顺序


1.Makefile和make形成目标文件的时候,默认是从上到下扫描makefile文件的,默认形成的是第一个目标文件。

2.有多个依赖关系和依赖方法,默认只形成一个。


5.Linux第一个小程序-进度条


5.1.缓冲区概念


首先我们将makefile和源文件搭建好


然后我们验证一下我们写的是否有问题


然后我们验证两个代码,观看它们的现象。

#include <stdio.h>
int main()
{
    printf("hello Makefile!\n");
    sleep(3);
    return 0;
}


我们可以发现上面代码的运行结果是先输出printf,然后等待三秒


#include <stdio.h>
int main()
{
    printf("hello Makefile!");
    sleep(3);
    return 0;
}


我们发现上代码的运行结果是先等待三秒,然后再输出printf


但是我们不要被上面的现象所迷惑,C语言代码是遵守顺序结构的,所以我们可以知道上面的代码永远是先执行printf("hello Makefile!");然后在执行sleep(3);但是为什么会出现上面的想象呢?


这是因为我们的C语言有一个缓冲区,当sleep没有执行完的时候,printf的字符串被保存到缓冲区了,当sleep执行完的时候,此时就要求刷新缓冲区,于是此时才输出printf语句,而第一个代码直接输出是因为'\n'字符会立刻刷新缓冲区,于是就先输出了printf语句。

#include <stdio.h>
int main()
{
    printf("hello Makefile!");
    fflush(stdout);
    sleep(3);
    return 0;
}


我们可以通过手动刷新缓冲区,先输出printf内容。


5.2.\n:换行符与\r:回车符之间的区别



所以准备工作已经完成了,现在开始写我们的进度条小程序。


5.3.进度条代码



但是此时我们发现make编译后运行我们的程序没有任何结果


因为我们上面的printf内容被保存到缓存区了,所以没有输出我们想要的结果,所以我们就要使用fflush进行强制刷新缓冲区。


然后我们再运行我们的代码。


这样就实现了我们的倒计时小程序,不过我们上面只能从9倒计时,如果我们想从10倒计时呢?


我们发现我们的程序不能完成从10倒计时,输出的时候后面多了一个0,为什么呢?


当我们向显示器打印10的时候,打印的是字符'1'和'0',当我们后面打印的时候,字符只依次覆盖'1'字符,并没有覆盖'0'字符。怎么解决呢?-2d:表示输出这个整数的时候预留两个字符的空间并左对齐输出这个整数


输出结果:


现在我们就来写一下我们的进度体条小程序,首先学习一下usleep函数,按照微秒的时间进行休眠。


我们先来建立一下多个文件并写上一个简单的打印输出工作


然后我们先验证一下make能否编译


接下来就可以写我们的进度条了。


我们的程序输出的进度条主要在processbar.c中实现的,字符数组设置为102是因为在我们的程序中,循环共循环了101次,bar[100]='#',如果设置数组大小101,此时下标最大就是100,而100下标处存放了bar[100]='#',没有位置存放'\0',这样程字符串就没有结束的标识,程序就达不到预期的结果。这里要注意最后一次,下标的位置是bar[100]='#',那从0开始到100不就有101个'#'符号吧吗?并不是,我们自己看我们的程序,当下标为0的时候,我们的程序时不打印'#'的,下标为1的时候才打印'#'的。

#include <iostream>
using namespace std;
int main()
{
  int cnt = 0;
  char bar[5];
  memset(bar, '\0', sizeof(bar));
  while (cnt <= 3)//下标为0,1,2,3
  {
    printf("[%s]", bar);
    bar[cnt++] = '#';
  }
  return 0;
}

运行结果:


所以此时小程序下标就是100,即可输出100个字符'#",结果运行:


但是我们平常的进度条不是#,我们期待能出现一个箭头的形式,我们可以在0下标处设置为字符'<',后续用字符'='覆盖前面的字符'<',我们来看一下程序的运行结果:


我们发现上面的程序输出了101个字符,我们期待最后一个字符应该是'=',我们来看一下我们的程序,当i=100的时候,此时bar[100]='>',循环再次进入的时候,最后一个元素输出是'>',然后i++,bar[100]位置被修改为'=',然后i++变为101,此时不再进入循环,虽然bar[100]位置被修改为'=',但是此时没有执行打印输出工作,所以最后一个仍然是'>'字符。

#include <iostream>
using namespace std;
int main()
{
  int cnt = 0;
  char bar[6];
  memset(bar, '\0', sizeof(bar));
  bar[0] = '>';
  while (cnt <= 3)//下标是0,1,2,3
  {
    printf("[%s]", bar);
    bar[cnt++] = '=';
    if (cnt <= 3)
      bar[cnt] = '>';
  }
  return 0;
}

运行结果:


监视窗口可以看到bar最后一个元素是'=',只不过输出的时候没有打印出来。


因此我们可以修改一下我们的程序,当i<100的时候就不要再执行修改'>'了。


但是实际上进度条并不是一个独立的程序,而是依附于其他应用的,比如我们下载一个文件就要进度条,进度条应该表现为下载量除以文件大小。接下来我们模拟一个下载的场景。


运行结果:


因此我们可以改善一下进度条。


上面的程序我们使用了我们的函数指针,通过回调函数可以调用函数,并且我们修改旋转光标不和rate进度条相关,并且给printf输出加上颜色打印,使我们的进度条更加美观。


进度条:

相关文章
|
15天前
|
Linux 数据安全/隐私保护
适用于 Linux 的最佳命令行下载加速器
适用于 Linux 的最佳命令行下载加速器
37 3
|
28天前
|
监控 数据可视化 Ubuntu
|
1月前
|
监控 Unix Linux
Linux系统工具
Linux系统工具
44 6
|
29天前
|
监控 Java Linux
Linux系统之安装Ward服务器监控工具
【10月更文挑战第17天】Linux系统之安装Ward服务器监控工具
50 5
Linux系统之安装Ward服务器监控工具
|
1月前
|
JSON JavaScript Linux
Linux系统之安装cook菜谱工具
【10月更文挑战第15天】Linux系统之安装cook菜谱工具
36 2
Linux系统之安装cook菜谱工具
|
20天前
|
缓存 监控 Linux
Linux性能分析利器:全面掌握perf工具
【10月更文挑战第18天】 在Linux系统中,性能分析是确保软件运行效率的关键步骤。`perf`工具,作为Linux内核自带的性能分析工具,为开发者提供了强大的性能监控和分析能力。本文将全面介绍`perf`工具的使用,帮助你成为性能优化的高手。
66 1
|
20天前
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
25 1
|
1月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
84 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
2月前
|
人工智能 监控 Shell
常用的 55 个 Linux Shell 脚本(包括基础案例、文件操作、实用工具、图形化、sed、gawk)
这篇文章提供了55个常用的Linux Shell脚本实例,涵盖基础案例、文件操作、实用工具、图形化界面及sed、gawk的使用。
479 2
|
2月前
|
监控 安全 Linux
如何利用Kali Linux进行网站渗透测试:最常用工具详解
如何利用Kali Linux进行网站渗透测试:最常用工具详解
123 6