【Linux】-- 开发工具yum、vim、gcc、g++、gdb、make、makefile使用介绍(三)

简介: 【Linux】-- 开发工具yum、vim、gcc、g++、gdb、make、makefile使用介绍

五、make/Makefile

1.了解make/Makefile

(1)make

       make是一个解释makefile中指令的命令工具。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中。

(2)Makefile

       Makefile是Linux项目自动化构建工具,Makefile规定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。编译的安排就叫做构建。构建规则都写在Makefile文件里面,要学会如何Make命令,就必须学会如何编写Makefile文件。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率,makefile成为了一种在工程方面的编译方法。

       make是一条命令,makefile是一个文件,两者搭配使用,形成可执行程序,完成项目自动化构建。

2.如何写一个Makefile

与源文件同级,创建一个Makefile文件:

将编译InsertSort.c的命令写入Makefile中。其中,第一行叫做依赖关系,第二行叫做依赖方法:

1. InsertSort:InsertSort.c       #依赖关系
2.         gcc InsertSort.c -o InsertSort -std=c99     #依赖方法

第一行开始的InsertSort叫做目标,InsertSort.c叫做前置条件,gcc InsertSort.c -o InsertSort -std=c99是命令,命令前有Tab键:

执行make命令后,会自动执行Makefile文件中的命令:

但是此时想再make一下,会发现不让make了:

因为可执行文件已经是最新了。Makefile默认的目标是文件,如果目标不是真实存在的文件,而是一个命令呢,那么这个目标就是伪目标,伪目标没有依赖关系,只有依赖方法,如下clean就是一个伪目标,make就不会去检查是否存在一个叫做clean的文件,而是每次运行都执行对应的命令:

1. InsertSort:InsertSort.c
2.         gcc InsertSort.c -o InsertSort -std=c99
3. .PHONY:clean      #伪目标
4. clean:
5. rm -f InsertSort

其中:

由于make扫描Makefile文件时,默认只会形成一个目标依赖关系,一般是第一个,因此,现在执行make,并不能达到删除InsertSort可执行文件的目的,因为make会生成第一个目标也就是生成InsertSort可执行程序:

此时要执行非第一个目标时,需要make加上目标:

当把两个目标的顺序交换一下,会发现,执行make时就先执行clean命令:

这下直接make时,就不是编译生成可执行文件了, 而是执行clean命令,如果要生成可执行程序,必须执行make 加上目标:

也可以用$@表示目标文件,$^表示上一行的冒号后面的依赖文件列表:

六、进度条小程序

1.回车和换行

  • 回车:行不变,列回到当前行的最开始
  • 换行:列不变,行切换到下一行

例如,如下代码,当执行打印后,需要等待3秒才结束程序:

enter.c

1. #include<stdio.h>
2. 
3. int main()
4. {
5. printf("33333333\n");
6. sleep(3);
7. 
8. return 0;
9. }

Makefile

1. enter:enter.c
2.         gcc -o $@ $^
3. .PHONY:clean
4. clean:
5. rm -f enter

那么打印内容会在屏幕上出现3秒以后程序才结束:

如果不加\n,那么一开始就不会打印字符串,等待3秒后,才会打印出字符串:

 

这两个程序运行结果并不代表sleep先于printf执行,其实只是printf已经执行,但是数据没有被立即刷新到显示器上而已。当没有\n时,字符串会暂时保存到用户C语言级别的缓冲区当中,显示器设备的刷新策略就是行刷新(\n),即立即刷新。

如果想在不带\n的情况下,让数据立即刷新出来, 可以调用fflush接口,不过fflush的参数是文件流:

那么对于这个程序,应该给fflush传什么参数呢?

由于在C语言中的文件操作,系统会默认地帮我们把对应的文件以C语言的方式打开,并且会默认打开3个输入输出流:

为什么程序会默认打开着3个输入输出流呢?因为程序为了帮我们计算数据,就有数据源和数据结果,C语言为了避免我们麻烦,默认给我们打开了这3个输入输出流,供我们读写。

对于刚刚的程序,想让代码立即刷新出来,我们借助fflush函数,因为printf是向stdout打印,那么刷新也是向stdout刷新,所以将stdout作为fflush的参数:

再执行make clean;make,会发现先刷新字符串,但是再等了3秒程序才结束:

对于\r,仅回车,行不变,列回到当前行的最开始,由于没有\n,所以每次循环的打印结果不会被显示出来:

1. #include<stdio.h>
2. 
3. int main()
4. {
5. int count  = 5;
6. while(count)
7.         {
8. printf("%d\r",count);
9.                 count--;
10. sleep(1);
11.         }
12. 
13. return 0;
14. }

那么为了让打印结果显示出来,可以使用fflush:

但是结果就变成在这个位置倒计时:

 

假如将count初始化为10,执行结果就更离谱:

这是因为显示器是字符设备,凡是显示到显示器上面的内容都是字符,凡是从键盘读取的内容也都是字符。所以上面第一次打印的count值为10并不是数字10,而是字符'1'和字符'0'。再对count--时,count的值只有一个字符,比如9,所以只能覆盖到一个字符,因此字符'0'永远都不会动。要解决这个问题,可以输出2个字符,这样就会把字符'0'给覆盖了:

执行结果:

 

2. 实现进度条小程序

假如实现进度条小程序,在同一行打印'#',每次刷新就多打印一个'#',以下代码是实现不了的,因为显示器是行刷新,没有\n就刷新不出来进度条:

1. #include<stdio.h>
2. #include<string.h>
3. #include<unistd.h>
4. 
5. #define NUM 100
6. 
7. int main()
8. {
9. char bar[NUM+1];
10. memset(bar,'\0',sizeof(bar));
11. 
12. int i = 0;
13. while(i <= 200)
14.         {
15. printf("%s",bar);//没有\n,在显示器上显示不出来‘#’
16.                 bar[i] = '#';
17.                 i++;
18. sleep(1);
19.         }
20. 
21. return 0;
22. }

那么加了\n以后呢?虽然'#'可以打印出来,但是打印却变成了不在同一行显示'#',这不符合我们的要求:

 

所以考虑到使用fflush:

但是发现运行结果,是每隔1秒自动多打印n个'#':

这不符合我们的需求,我们需要每次增加一个'#'。可以加上\r

现在每次刷新增加一个#":

这下达到了我们的要求,但是有没有发现好像刷新的太慢了,那就把刷新间隔缩短一些:

这下快一些了 :

但是i的上限是200,程序要执行好久才能看到最终的执行结果,而且还刷屏,不好观察,将i的上限改为20:

执行结果发现,执行完毕时提示符[delia@VM-8-17-centos progressBar]$ 和进度条在同一行呢:

能不能把提示符去掉?可以在程序执行结束时,换行:

现在程序执行结束就换行了:

如果想让进度条被[ ]包起来呢?

发现进度条从右向左显示:

加上'-'就从左向右显示了:

执行结果如下:

想加上数字百分比呢?

执行结果如下:

想在结尾增加光标旋转呢?

执行结果如下:

 

假如想更换进度条颜色呢?比如换成绿色:

执行结果如下:

好啦,进度条做好啦。完整代码段:

1. #include<stdio.h>
2. #include<string.h>
3. #include<unistd.h>
4. 
5. #define NUM 100
6. 
7. int main()
8. {
9. char bar[NUM+1];
10. memset(bar,'\0',sizeof(bar));
11. 
12. const char *token = "|/-\\";
13. 
14. int i = 0;
15. while(i <= 100)
16.         {
17. printf("\033[32m[%-100s][%d%%] [%c]\r",bar,i,token[i%4]);
18. fflush(stdout);
19.                 bar[i] = '#';
20.                 i++;
21. usleep(50000);
22.         }
23. 
24. printf("\n");
25. return 0;
26. }
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
10月前
|
NoSQL Linux 开发工具
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
本文介绍了yum 包管理工具、Vim 编辑器、gcc/g++ 编译器、gdb 调试器、编译原理及 Makefile 的使用,同时还配备了如何使用,以及图解。旨在帮助读者更好地理解和应用这些工具与技术。
506 0
|
Rust Ubuntu Java
[Linux工具] Makefile
Makefile是Linux环境下用于自动化编译和链接程序的配置文件,常用于简化大型项目的编译流程。通过定义目标文件、依赖文件及生成命令,Makefile能高效管理编译任务。它不仅适用于C语言项目,还可扩展到其他编程语言和非编程任务中。
[Linux工具] Makefile
|
Unix Linux C语言
【Linux】 Linux makefile 教程
本文详细介绍了 Linux 环境下 Makefile 的基本结构、语法和使用方法,并通过一个简单的 C++ 项目示例演示了 Makefile 的实际应用。Makefile 是一个强大而灵活的工具,通过合理配置,可以极大地简化项目的编译和管理过程,提高开发效率。希望本文能帮助您更好地理解和应用 Makefile,在实际项目中高效管理代码的编译和构建。
913 20
|
Unix Linux C语言
【Linux】 Linux makefile 教程
本文详细介绍了 Linux 环境下 Makefile 的基本结构、语法和使用方法,并通过一个简单的 C++ 项目示例演示了 Makefile 的实际应用。Makefile 是一个强大而灵活的工具,通过合理配置,可以极大地简化项目的编译和管理过程,提高开发效率。希望本文能帮助您更好地理解和应用 Makefile,在实际项目中高效管理代码的编译和构建。
352 16
|
Linux C++
Linux c/c++之makefile的基础使用
Linux下C/C++项目中makefile的基本使用,包括基础、进阶和高级用法,以及如何创建和使用makefile来自动化编译过程。
227 0
Linux c/c++之makefile的基础使用
|
Java Linux C++
【Linux】Make和Makefile快速入门
【Linux】Make和Makefile快速入门
150 0
|
Java Linux 编译器
编写和使用Linux Makefile
编写和使用Linux Makefile
|
7月前
|
安全 关系型数据库 MySQL
CentOS 7 yum 安装 MySQL教程
在CentOS 7上安装MySQL 8,其实流程很清晰。首先通过官方Yum仓库来安装服务,然后启动并设为开机自启。最重要的环节是首次安全设置:需要先从日志里找到临时密码来登录,再修改成你自己的密码,并为远程连接创建用户和授权。最后,也别忘了在服务器防火墙上放行3306端口,这样远程才能连上。
1800 16
|
6月前
|
存储 关系型数据库 MySQL
MySQL介绍和MySQL包安装 -- RHEL系列(Yum资源库安装MySQL)
MySQL是一款开源关系型数据库,高性能、易用、跨平台,支持多种存储引擎,广泛应用于Web开发、企业级应用等领域。本教程介绍其特点、架构及在主流Linux系统中的安装配置方法。
1182 0
MySQL介绍和MySQL包安装 -- RHEL系列(Yum资源库安装MySQL)
|
10月前
|
缓存 Ubuntu 前端开发
yum的安装和使用(包含安装过程中遇到的问题及解决方法)
yum的安装和使用(包含安装过程中遇到的问题及解决方法)
1575 1
yum的安装和使用(包含安装过程中遇到的问题及解决方法)