0


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


🌈 个人主页:Zfox_
🔥 系列专栏:C++从入门到精通

目录

一: 🔥 make / Makefile背景介绍

💢 首先我们来介绍一下什么是 **

make/Makefile

**,以及它们之间的关系。

🥝 make是什么?

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

🥝 Makefile是干什么的?

  • Makefile 是一个 **文件**。它是一个工程文件的编译规则,它记录了原始码如何编译的详细信息、描述了整个工程的编译链接等规则。
  • Makefile 带来的好处就是——**“自动化编译"**。一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率🚀。

🎯 先来看一下 **

Makefile

** 的【语法】:

target(目标文件):文件1 文件2(依赖文件列表)        //依赖关系<Tab>gcc -o 欲建立的执行文件 目标文件1 目标文件2///依赖方法
     command
     ......
  • target就是我们想要建立的信息,一般称作 **目标文件**。而后面的依赖文件列表就是具有相关性的 object files,也就是目标文件所依赖的文件(可以是一个或多个,也可以没有)。

🎯 然后看一下 **

Makefile

** 的【规则】:

  • 目标文件与依赖文件列表文件之间要使用冒号隔开 **目标文件:依赖文件列表**。
  • target可以是一个目标文件、执行文件,甚至可以是一个标签【后面会提到的伪目标】。
  • 依赖方法前面必须加 **Tab空格键**。
  • 依赖方法以gcc为例,也可以是其他的shell指令【command】。

**💢 【总结一下】:

make 

是一条

命令

makefile

是一个

文件

,两个搭配使用,完成项目自动化构建。**


二: 🔥 Makefile的显式规则

**💢 首先,在Makefile中,#代表着注释,这个是不会被编译进去的。 **

大家注意,在Makefile里,有一个很反人类的规定,指令前必须打一个 **

[Tab]

** 键,按四下空格会报错。

💢 越是接近目标文件的命令,就越是要写在前面。因为程序是按照递归的方式进行依赖文件查找的,看到第一行有一个没见过的依赖文件,就往下一行进行查找,以此类推。

但是有些同学反映,不按照这个顺序来写好像也不会报错,我觉得这可能是和版本有关系,不过保险起见,我建议大家还是按照规范来写Makefile。

举个例子:

hello:hello.o
    gcc hello.o -o hello
    
hello.o:hello.s
    gcc -c hello.s -o hello.o
    
hello.S:hello.i
    gcc -S hello.i -o hello.s
    
hello.i:hello.c
    gcc -E hello.c -o hello.i
  • 假设当前文件夹中有 hello.cMakefile 两个文件,当我们在终端输入make指令的时候,就会自动编译出hello.o,hello.s,hello.i 以及hello可执行文件。
  • 可是,我们又不想要这些不相关的文件,想对这些文件做一些操作,我们把这样的操作叫做伪目标,标志位.PHONY:

在上述代码的最后面加上:

.PHONY:
clear:
    rm hello.o hello.S hello.i

.PHONY:这是固定格式,不能变的,但是下面的clear是自己取的名字,你随便取什么名字都可以,但是clear比较直观。

这样,当我们执行make clear指令后,将只剩下hello.c 和 hello可执行文件。

🥝 2.1 .PHONY的作用

** 我们发现当我们重复make的时候,只有第一次make是有效的,那是因为gcc指令会自动去比较 ./process 和 process.c 等代码文件被修改的时间如果代码没有被修改,也就没有必要重复执行命令了,提高了效率。 **
在这里插入图片描述
在这里插入图片描述
**💢 加上标志位.PHONY:的命令就可以被重复执行了。 **
在这里插入图片描述

  • PHONY 配置项的目标clean并不是其他文件生成的实际文件,使make命令会自动绕过隐含规则搜索过程,也就是说执行命令make clean会自动忽略名为"clean"文件的存在,因此声明.PHONY配置项会改善性能,并且不需要担心实际同名文件存在与否😮
  • 【通俗一点说】:**.PHONY** 修饰的目标clean并不是某个依赖项生成的实际文件,因此make命令不再去搜寻当前文件夹下是否有clean文件,这样少去做一些事,自然会改善性能,并且不用担心当前文件夹下是否有同名的文件。

💢 再来个复杂一点的例子:

# 目标文件:test
# 现有文件:program1.c program1.h program2.c program2.h main.c main.h

test:program1.o program2.o main.o
    gcc program1.o program2.o main.o -o test

program1.o:program1.c
    gcc -c program1.c -o program1.o

program2.o:program2.c
    gcc -c program2.c -o program2.o

main.o:main.c
    gcc -c main.c -o main.o

.PHONY:
clean_all:
    rm program1.o program2.o main.o

** 然后回到命令行,我们来执行一下这个make指令,它就是自动在当前源文件的所在路径下搜寻Makefile,并解释里面命令。之后若是我们需要去编译任何文件,只需要在Makefile里面做一个添加即可,怎么样,是不是很方便。 **
在这里插入图片描述

到这里,Makefile就学会了,就可以用来做事情了,就是这么简单。

后面的内容无所谓你看不看了,放学了…

三: 🔥 依赖关系与依赖方法

通过小小的demo,想必你已经感受到了【自动化构建工具】的强大,我们来仔细看看Makefile中的指令为何要如此书写✍

🥝 概念理清

  • 对于 process:process.c ,冒号左侧是目标文件,右侧是它的依赖文件,所以就可以说它们之间存在一种 ** 【依赖关系】只有 process.c 存在才可以有 process。**
  • 那要如何通过 process.c去生成 process 呢❓ 此时就需要使用到下面的这句 gcc指令 gcc -o process process.c 👉它叫做 ** 【依赖方法】**

四: 🔥 Makefile小知识📚

符号含义=替换%.o任意的.o文件
如果我们写TAR = test,就表示下面的代码中,我们可以用TAR代表test文件

🥝 通配符

符号含义$^所有依赖文件$@所有目标文件$<所有依赖文件的第一个文件

** 即这个 $@ 和 $^,前者表示:左侧被编译的所有内容,即【目标文件】,后者表示:之后所有内容,即【依赖文件】。**
在这里插入图片描述
** 此时,当我们再去make的时候,就可以发现这个特殊符号自动替换成了:两侧的【目标文件】和【依赖文件】。**

五: 🔥 Makefile取消回显

** 写了这么多【

make

】,你是否感觉每次都会出现回显很麻烦呢?能不能像我们在敲普通指令的时候一样,直接给出结果呢?**

  • 这里我们就可以在执行的命令行前加上这个**@**

在这里插入图片描述

  • 此时当我们在【**make】和【make clean**】的时候就不会产生任何回显了,可以达到一样的效果。- 在这里插入图片描述

六: 🔥 共勉

以上就是我对 **

【Linux】makefile自动化编译

** 的理解,觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~😉
在这里插入图片描述

标签: linux 自动化 运维

本文转载自: https://blog.csdn.net/weixin_50776420/article/details/141003888
版权归原作者 Zfox_ 所有, 如有侵权,请联系我们删除。

“【Linux】make/Makefile——项目自动化构建工具”的评论:

还没有评论