Linux——环境基础开发工具的使用(3)

简介: Linux——环境基础开发工具的使用(3)

五、Linux项目自动化构建工具 — make/Makefile

1.make/Makefile的背景

1.会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力 。

2.一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

3.makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

4.make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefifile都成为了一种在工程方面的编译方法。

5.make是一条命令,makefifile是一个文件,两个搭配使用,完成项目自动化构建。

2.依赖关系和依赖方法

       想要生成可执行程序,需要经过预处理、编译、汇编和链接,它们之间存在依赖关系和依赖方法,如下图所示:

1ecd1b2606ed46e9956a89f231c9802c.png

从上图可以发现,想要得到可执行程序,我们首先要得到test.o文件,要得到test.o文件就要得到test.s文件,以此类推,只要我们写好了源代码,通过这样的依赖关系及依赖方法,最终就能得到可执行程序。


       当我们有很多文件时,就需要用到make/Makefile来对这些文件的依赖关系及依赖方法进行编写,就不需要每次gcc编译每个程序。当然上图中的关系是细分到每一步的,我们在编写的过程中不需要细分到每一步。

3.如何编写Makefile文件

1.创建Makefile文件

make是依赖于makefile的,要运行make,当前目录下就必须有makefile此目录名的文件。

makefile是阐述依赖关系和依赖方法的。

makefile文件命名只允许首字母大写或小写,其余都是小写。

1ecd1b2606ed46e9956a89f231c9802c.png

2.编写Makefile文件

在编写Makefile文件时,先表明依赖关系(如A : B 表示A依赖于B)紧接着书写依赖方法

1ecd1b2606ed46e9956a89f231c9802c.png

1ecd1b2606ed46e9956a89f231c9802c.png

以上两种写法都可以,解释一下第二种写法:

$@: 表示依赖关系中的目标文件,也就是mytest

$^ : 表示依赖关系中的文件列表,也就是mytest.c;(不仅仅只有mytest.c可能有更多)

3.效果展示

1ecd1b2606ed46e9956a89f231c9802c.png

4.make的原理

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

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

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

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

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

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

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

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

5.项目清理

       项目清理类似于VS下的清理解决方案,也就是将之前生成的所有文件清理掉,如果我们进行手动清理,那么在有多个文件的情况下,手动清理未免太过麻烦,此时我们可以将项目清理加入到Makefile文件中。

1ecd1b2606ed46e9956a89f231c9802c.png

1ecd1b2606ed46e9956a89f231c9802c.png .PHONY类似于关键字,是用来修饰clean的,它是一个伪目标,表示总是被执行。

1ecd1b2606ed46e9956a89f231c9802c.png

问题:为什么在使用Makefile时,只需要输入make;使用clean时,输入却是make clean?

解析:因为Makefile文件在执行是从上至下的,只输入make,它会默认执行第一个依赖关系

六、Linux第一个小程序 — 进度条

1.回车换行的概念

回车(\n):表示将光标移动到文本的行首;

换行(\r):表示将光标移动到下一行,但是相对位置并没有发生改变(列不变)

2.行缓冲区的概念

我们首先观察以下三种不同的程序运行起来有什么不同的现象

//程序1
#include <stdio.h>
#include <unistd.h>
int main()
{
   printf("hello Makefile!\n");//带换行
   sleep(3);//休眠3秒
   return 0;
}
//程序2
#include <stdio.h>
#include <unistd.h>
int main()
{
   printf("hello Makefile!");//不带换行
   sleep(3);//休眠3秒
   return 0;
}
//程序3
#include <stdio.h>
#include <unistd.h>
int main()
{
   printf("hello Makefile!");//不带换行
   fflush(stdout);//刷新缓冲区
   sleep(3);//休眠3秒
   return 0;
}

程序1:立即打印出 hello Makefile! 然后换行,休眠3秒后,程序结束;


程序2:未立即打印 hello Makefile! 休眠3秒后才显示打印内容,程序结束;


程序3:立即打印出 hello Makefile! 休眠3秒,程序结束;


比较三个程序,我们发现他们打印的时机不一样,这是由于行缓冲造成的。


什么是行缓冲?

       当输入输出遇到换行符的这类缓冲定义为行缓冲。标准输入和标准输出都是行缓冲。

缓冲区刷新的条件:

       1.进程结束

       2.遇到\n

       3.缓冲区满

       4.手动刷新缓冲区fflush(stdout)

       5.调用exit(0);但是还可以调用_exit(0),不刷新缓冲区。

3.进度条代码

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
   int i = 0;
   char bar[102];
   memset(bar, 0 ,sizeof(bar));
   const char *lable="|/-\\";//类似于加载的过程
   while(i <= 100 )
   {
       printf("[%-100s][%3d%%][%c]\r", bar, i, lable[i%4]);
       fflush(stdout);//刷新缓冲区
       bar[i++] = '#';
       usleep(50000);
   }
   printf("\n");
   return 0;
}

1ecd1b2606ed46e9956a89f231c9802c.png

1ecd1b2606ed46e9956a89f231c9802c.png


目录
相关文章
|
2天前
|
编解码 Linux 5G
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
AVS3,中国制定的第三代音视频标准,是首个针对8K和5G的视频编码标准,相比AVS2和HEVC性能提升约30%。uavs3d是AVS3的解码器,支持8K/60P实时解码,且在各平台有优秀表现。要为FFmpeg集成AVS3解码器libuavs3d,需从GitHub下载最新源码,解压后配置、编译和安装。之后,重新配置FFmpeg,启用libuavs3d并编译安装,通过`ffmpeg -version`确认成功集成。
14 0
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
|
4天前
|
运维 Linux Docker
ChatGLM3在Docker环境部署,Linux运维免打包多渠道统计如何实现
ChatGLM3在Docker环境部署,Linux运维免打包多渠道统计如何实现
|
4天前
|
运维 Linux Docker
ChatGLM3在Docker环境部署(1),Linux运维电话面试技巧
ChatGLM3在Docker环境部署(1),Linux运维电话面试技巧
|
4天前
|
Web App开发 Ubuntu Linux
Linux无图形界面环境使用Python+Selenium实践
【5月更文挑战第1天】Linux无图形界面环境使用Python+Selenium实践
46 2
|
4天前
|
数据可视化 Unix Linux
Linux|基础环境开发工具使用(1)
Linux|基础环境开发工具使用(1)
|
6天前
|
关系型数据库 MySQL Linux
在Linux系统上实现高效安装与部署环境的全方位指南
在Linux系统上实现高效安装与部署环境的全方位指南
|
6天前
|
Linux 开发工具 Android开发
【Linux修行路】基础开发工具——yum
【Linux修行路】基础开发工具——yum
|
6天前
|
运维 NoSQL Linux
linux环境收集core文件步骤
请注意,生成core文件可能会占用磁盘空间,因此应谨慎使用。一旦完成故障排查,建议将相关的core文件删除以释放磁盘空间。
42 5
|
6天前
|
运维 NoSQL Linux
linux环境收集core文件步骤
请注意,生成core文件可能会占用磁盘空间,因此应谨慎使用。一旦完成故障排查,建议将相关的core文件删除以释放磁盘空间。
23 4
|
6天前
|
Linux 开发者
【亮剑】Linux系统中的四种文件锁定机制:flock、fcntl、lockfile和flockfile,用于多进程环境下协调共享资源访问,防止数据损坏和竞争条件
【4月更文挑战第30天】本文介绍了Linux系统中的四种文件锁定机制:flock、fcntl、lockfile和flockfile,用于多进程环境下协调共享资源访问,防止数据损坏和竞争条件。flock适合脚本,fcntl提供底层灵活性,lockfile用于管理锁定文件,flockfile则结合两者功能。选择锁定策略时需考虑应用场景,如脚本可选flock,复杂需求则用fcntl。理解并正确使用这些工具对保证系统稳定性和数据一致性至关重要。