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

时间:2023-01-10 16:54:27

目录

1 背景

2 原理

3 Linux第一个小程序-进度条

3.1 行缓冲区概念 

3.2 进度条代码

4 总结


1 背景

在VS中我们知道当我们想要运行程序时直接按f5程序就会自动运行起来,但是在Linux中如果有多个文件好像并不能这样快速进行,那么这时候就提出了Linux项目自动化构建工具 make/Makefile,用这个工具来管理我们的项目就会显得更加方便高效。


2 原理

我们先来看看这个究竟是个啥?

我们首先创建一个hello.c的C文件,向里面写入代码,然后再用gcc编译执行,有了前一篇博客介绍程序的翻译过程我们不难知道想要将C代码转换成可执行文件要进行预处理,编译,汇编,链接的过程(忘了的老铁可以去看看这篇文章gcc/g++的使用). 假如我们想要一步一步执行的话就必须一次一次的敲指令,那现在有什么比较方便的方法吗?答案是有的,这里就可以用make/Makefile.

(注意:接下来我写的这种方法实际中一般都不会这么写,而是直接用gcc全部翻译,我这里这样写是为了大家能够更好的理解make/Makefile)

我们首先创建一个Makefile的文件夹,用vim打开向里面写入:

  1 hello:hello.o
  2   gcc hello.o -o hello
  3 hello.o:hello.s
  4   gcc -c hello.i -o hello.o
  5 hello.s:hello.i
  6   gcc -S hello.i -o hello.s 
  7 hello.i:hello.c
  8   gcc -E hello.c -o hello.i
  9 
 10 .PHONY:clean
 11 clean:                                                                                                                                  
 12   rm -rf  hello.i hello.s hello.o hello

这里我们在介绍为啥要这么写?

hello:hello.o 这一行代表着依赖关系,然后换行回车后要再按一个tab键,这是语法规定。

然后在这一行写上依赖方法。

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

 那下面的clean前面又是什么鬼呢?

clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要 make 执行。即命令 ——“make clean” ,以此来清除所有的目标文件,以便重编 译。 但是一般我们这种clean 的目标文件,我们将它设置为伪目标 , .PHONY 修饰 ,伪目标的特性是,总是被执行的。那前面我们不加.PHONY的文件就是不总是被执行的文件,这一点大家很容易理解。
现在我们只需要执行:make 
程序就会自动执行下面的指令,make clean 程序就会自动清理这些创建出的文件。
[grm@VM-8-12-centos lesson4]$ ll
total 8
-rw-rw-r-- 1 grm grm  76 Jan  7 15:11 hello.c
-rw-rw-r-- 1 grm grm 226 Jan  7 15:50 Makefile
[grm@VM-8-12-centos lesson4]$ make
gcc -E hello.c -o hello.i
gcc -S hello.i -o hello.s 
gcc -c hello.i -o hello.o
gcc hello.o -o hello
[grm@VM-8-12-centos lesson4]$ ll
total 48
-rwxrwxr-x 1 grm grm  8360 Jan  7 15:50 hello
-rw-rw-r-- 1 grm grm    76 Jan  7 15:11 hello.c
-rw-rw-r-- 1 grm grm 16878 Jan  7 15:50 hello.i
-rw-rw-r-- 1 grm grm  1504 Jan  7 15:50 hello.o
-rw-rw-r-- 1 grm grm   451 Jan  7 15:50 hello.s
-rw-rw-r-- 1 grm grm   226 Jan  7 15:50 Makefile
[grm@VM-8-12-centos lesson4]$ ./hello
hello Makefile
[grm@VM-8-12-centos lesson4]$ make clean
rm -rf  hello.i hello.s hello.o hello
[grm@VM-8-12-centos lesson4]$ ll
total 8
-rw-rw-r-- 1 grm grm  76 Jan  7 15:11 hello.c
-rw-rw-r-- 1 grm grm 226 Jan  7 15:50 Makefile
make 是如何工作的 , 在默认的方式下,也就是我们只输入 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 只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

当我们使用make指令后,不清理,在使用make指令就会出现下面这种情况:

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

 这时操作系统就会提醒我们hello已经是最新的了,但是我们如果打开hello.c修改一下里面内容,就又可以用make指令啦,但是依旧只能够用一次:

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

 那有什么办法不修改就可以运行的吗?

答案是有的:

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

 touch +文件名,就会将文件更新成最新的时间。

最后说明:

  • 会不会写makefifile,从一个侧面说明了一个人是否具备完成大型工程的能力 。
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefifile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作 。
  • makefifile带来的好处就是——“自动化编译,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefifile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:DelphimakeVisual C++nmakeLinuxGNUmake。可见,makefifile都成为了一 种在工程方面的编译方法。
  • make是一条命令,makefifile是一个文件,两个搭配使用,完成项目自动化构建。

3 Linux第一个小程序-进度条

在这之前我问大家一个问题:换行和回车是一回事吗?

相信在很多人的印象中都会回答说是的,但是却不是这样的。换行是换到了下一行,但是光标所在的位置依旧是与上一行所对齐的,而回车是让光标回到本行开头。

3.1 行缓冲区概念 

大家先来看看这么一个程序:

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

当我们运行的时候:

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

 我们不难发现程序是先打印出来的字符串然后sleep了3s才结束。

但是当我们去掉字符串中\n时再来运行:

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

 我们可以看见:

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

 这里会先sleep3s再打印字符串的。为什么呢?原因就是\n会刷新我们的行缓冲区。

3.2 进度条代码

这里直接给出代码,相信大家能够看懂

  1 #include<stdio.h>
  2 #include <unistd.h>
  3 #include <string.h>
  4 int main()
  5 {
  6  int i = 0;
  7  char bar[102];
  8  memset(bar, 0 ,sizeof(bar));
  9  const char *lable="|/-\\";
 10  while(i <= 100 ){
 11  printf("[%-100s][%d%%][%c]\r", bar, i, lable[i%4]);
 12  fflush(stdout);
 13  bar[i++] = '#';
 14  usleep(50000);                                                                                                                         
 15  }
 16  printf("\n");
 17  return 0;
 18 }
我们运行起来看看:
【Linux项目自动化构建工具 make/Makefile】

 这样一个简单的进度条就制作完成啦!


4 总结

本篇博客我们总结了Linux项目自动化构建工具 make/Makefile简单的使用,还用动图展示了行缓冲区如何刷新,最后还写了一个简单的进度条。如果该文对你有帮助的话能不能一键3连支持一下呢

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