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

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

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键,这是语法规定。

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

af3b7eb05e254f8a9dfe23de32db5ebf.png

那下面的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指令就会出现下面这种情况:

46429ae7e66046dca39827df25cd2f31.png

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

4ad4252c799c4a0cbff2b9f19101fc66.png

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

答案是有的:

76ca1b6beefc42949a116e4f2bf93d4a.png

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

最后说明:

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

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

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

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

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

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

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

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

3.1 行缓冲区概念

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

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

当我们运行的时候:

6fce914b9d3043bf8ed4965f29b54aa8.gif

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

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

649da170531c423582251a7eda2e4378.png

我们可以看见:

adf4bc7d5b234facaad78edc78bdb60a.gif

这里会先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 }

我们运行起来看看:

a5daa5aea5bc490e9a286a547b444182.gif

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


4 总结

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

目录
相关文章
|
11月前
|
Java 关系型数据库 MySQL
在Linux平台上进行JDK、Tomcat、MySQL的安装并部署后端项目
现在,你可以通过访问http://Your_IP:Tomcat_Port/Your_Project访问你的项目了。如果一切顺利,你将看到那绚烂的胜利之光照耀在你的项目之上!
530 41
|
10月前
|
NoSQL Linux 开发工具
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
本文介绍了yum 包管理工具、Vim 编辑器、gcc/g++ 编译器、gdb 调试器、编译原理及 Makefile 的使用,同时还配备了如何使用,以及图解。旨在帮助读者更好地理解和应用这些工具与技术。
471 0
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
970 20
|
Linux Android开发 开发者
linux m、mm、mmm函数和make的区别
通过理解和合理使用这些命令,可以更高效地进行项目构建和管理,特别是在复杂的 Android 开发环境中。
878 18
|
关系型数据库 MySQL Linux
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
基于阿里云服务器Linux系统安装Docker完整图文教程(附部署开源项目)
2914 3
|
Linux 开发工具 C语言
韦东山Linux教学视频中的makefile文件详细介绍
韦东山Linux教学视频中的makefile文件详细介绍
496 0
|
Linux Windows 程序员
|
7月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
791 1
二、Linux文本处理与文件操作核心命令

热门文章

最新文章