【Linux】项目自动化构建工具—make/makefile

简介: Linux项目自动化构建工具-make/Makefile的使用和进度条小程序的实现。

1. 什么是make/makefile?

make是一个命令工具,是一个解释makefile中指令的命令工具,那么究竟什么是makefile呢?

其实,在一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作作。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

其实,总的来说,make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。


2. make/makefile的使用

2.1 实例代码

这里我们可以先创建一个test.c文件来写一个简单的C语言程序,然后用vim来创建一个Makefile文件(当然了,文件名是makefile也是可以的),Makefile中的内容和test.c中的内容如下:

image.png

接下来我们使用make这个命令来进行编译:

image.png

在这里我们发现使用make指令后,自动帮我们执行了gcc test.c -o mytest这条指令。并且生成了可执行程序mytest,执行mytest这个可执行程序后,内容已经显示到了屏幕上。

下面我们看一下Makefile文件中原理。


2.2 依赖关系和依赖方法

在Makefile文件中有两行内容,第一行内容中的mytesttest.c依赖关系,因为mytest这个文件的生成必然要依赖于test.c的编译。

但是test.c是如何生成mytest的呢?是通过gcc编译器的编译而形成的。而编译所需要的命令就是gcc test.c -o mytest,所以这条命令就是所谓的依赖方法

image.png

下面我们通过上一篇博客讲到的程序翻译的四个阶段来深刻理解一下所谓的依赖关系和依赖方法:

image.png

当我们使用make指令来执行Makefile这个文件时,依赖关系和依赖方法会自上而下展开,mytest依赖于test.o,但是原来的文件中并不存在test.o,所以会继续向下寻找依赖关系,test.o又是依赖于test.s的,但是test.s还是找不到,所以会依次向下寻找依赖关系,直到最后一次test.i依赖于test.c,而==test.c却是存在的==,所以Makefile会自下而上去执行依赖关系所对应的依赖方法,下面我们用make指令来演示一下这个过程:

image.png


2.3 项目清理

工程是需要被清理的,例如我们在写代码的时候把已经写好的代码编译后生成了可执行程序,但这个可执行程序的执行结果却和我们预想的不一样,那我们就需要将这个可执行程序清理掉,重新编写源代码并生成新的可执行程序,基于这个原因,makefile给我们提供了项目清理工具。

我们可以定义一个clean,这里的clean没有被第一个目标mytest直接或间接依赖,所以clean不会被自动执行:

image.png

我们需要可以在==make命令后面跟clean目标==作为参数来执行其后所定义的命令。

image.png

.PHONY 伪目标

基于上面的clean,我们可以使用.PHONY来修饰,.PHONY修饰的对象就是伪目标,伪目标的特性是:总是被执行的。

这里我们需要注意的是:.PHONY修饰的一定能被反复执行,而能反复执行的不一定被.PHONY修饰。

image.png

当我们不加.PHONY时,clean依然可以被反复执行。但是我们一般都要给clean加上.PHONY,因为我们不知道目标文件是否已经被删除,所以保证每次都清理一遍。


2.4 make是如何确定是否编译的

我们发现如果我们用make编译过一遍我们需要执行的源程序后,第二遍编译的时候就不能再编译了。

image.png

这里我们发现当我们编译过一遍后,他告诉我们的可执行程序mytest已经是最新的了,所以从第二次开始就不能再编译了。那么make是如何知道我们的可执行程序已经是最新的呢?

其实这是因为存在两条时间线,一条是我们源程序的时间线,另一条是我们的可执行程序形成的时间线。而make呢就是通过这两条时间线上我们源程序和可执行程序最新形成的时间对比来确定是否要进行编译的。

image.png

如果可执行程序最新形成的时间在最新的源程序的时间之后,那么make认为当前的可执行程序是最新的,为了提高效率并不需要执行编译。相反,如果可执行程序最新形成的时间在最新的源程序的时间之前,那么make则认为需要重新进行编译形成新的可执行程序。

当然我们也可以通过touch指令来执行我们的源程序,如果touch的文件不存在那就会新建一个文件,如果要是存在的话,就会将文件的时间更新到最新。

image.png


3. Linux第一个小程序—进度条

3.1 \r 和 \n

‘\n’是我们在学习C语言的过程中经常遇到的转义字符,它的意思是 ==回车+换行==,但其实’\n‘原本的意思仅有换行的意思,只不过是在C语言中将它做了优化,让他既具有回车的功能又具有换行的功能。下面我们看一下\r\n原本的意思。

\r:回车,将光标移动到当前行的行首

\n:换行,直接将光标移动到下一行

这里我们可以先提前看一下\r这种转义字符的效果:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 int main()
  5 {
   
   
  6   printf("hello world\r");
  7   fflush(stdout);//刷新一下缓冲区                                                                                                                                                      
  8   sleep(3);
  9   return 0;
 10 }

1.gif


3.2 进度条小程序

首先我们需要先创建三个文件:process.h、process.c、test.c

process.h

  1 #pragma once 
  2 
  3 #include<stdio.h>
  4 
  5 #include<unistd.h>
  6 
  7 #include<string.h>
  8 
  9 #define NUM 101                                                                                                                                        
 10 extern void proccesson();

process.c

    1 #include"process.h"
    2 #define STYLE '='
    3 #define ARR '>'
    4 
    5 void processon()
    6 {
   
   
    7   char bar[NUM];
    8   memset(bar,'\0',sizeof(bar));
    9   const char*lable = "|/-\\";
   10   int n = 0;
   11   while(n<=100)
   12   {
   
   
   13     printf("[%-100s][%-3d%%][%c]\r",bar,n,lable[n%4]);
   14     fflush(stdout);
   15     bar[n++] =STYLE;
   16     if(n!=100) bar[n]=ARR;
   17 
   18 
   19     usleep(100000);
   20   }
   21   printf("\n");                                                                                                                       
   22 }

test.c

    1 #include"process.h"
    2 
    3 int main()
    4 {
   
   
    5    processon();                                                                                                                       
    6   return 0;
    7 }

2.gif


相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
相关文章
|
1月前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
92 8
|
2月前
|
监控 Java Linux
Linux系统之安装Ward服务器监控工具
【10月更文挑战第17天】Linux系统之安装Ward服务器监控工具
64 5
Linux系统之安装Ward服务器监控工具
|
2月前
|
JSON JavaScript Linux
Linux系统之安装cook菜谱工具
【10月更文挑战第15天】Linux系统之安装cook菜谱工具
42 2
Linux系统之安装cook菜谱工具
|
1月前
|
缓存 监控 Linux
Linux性能分析利器:全面掌握perf工具
【10月更文挑战第18天】 在Linux系统中,性能分析是确保软件运行效率的关键步骤。`perf`工具,作为Linux内核自带的性能分析工具,为开发者提供了强大的性能监控和分析能力。本文将全面介绍`perf`工具的使用,帮助你成为性能优化的高手。
141 1
|
1月前
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
51 1
|
2月前
|
关系型数据库 MySQL Linux
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
392 3
|
2月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
496 3
|
2月前
|
算法 Java Linux
java制作海报五:java 后端整合 echarts 画出 折线图,项目放在linux上,echarts图上不显示中文,显示方框口口口
这篇文章介绍了如何在Java后端整合ECharts库来绘制折线图,并讨论了在Linux环境下ECharts图表中文显示问题。
47 1
|
1月前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
252 6
下一篇
DataWorks