Linux - Makefile

Makefile是什么?

Makefile 可以简单的认为是一个工程文件的编译规则,描述了整个工程的编译和链接等规则。
其中包含了哪些文件需要编译、哪些文件不需要编译、哪些文件需要先编译、哪些文件需要后编译、哪些文件需要重建等等。编译整个工程需要涉及到的,在Makefile 中都可以进行描述。
换句话说,Makefile 可以使我们的项目工程的编译变得自动化,不需要每次都手动输入一堆源文件和参数。

以 Linux 下的C语言开发为例说明一下:

多个源文件编译生成一个文件,编译的命令如下所示:
gcc -o outfile name1.c name2.c ...

outfile: 是要生成的可执行程序的名字;
nameN.c(N = 1,2,3,…): 是源文件的名字。

如果我们遇到的源文件的数量不是很多的话,可以选择这样的方式进行编译.

如果源文件非常多的话,使用这样的方式就会遇到下面的问题:

1)编译的时候需要链接库的问题。

拿C语言来举例,编译的时候 gcc 只会默认链接一些基本的C语言标准库,很多源文件依赖的标准库都需要我们手动链接。

下面列举了一些需要我们手动链接的标准库:

  • name1.c 用到了数学计算库 math 中的函数,我们就要手动添加参数 -lm;
  • name2.c 用到了小型数据库 SQLite 中的函数,我们得手动添加参数 -lsqlite3;
  • name3.c 使用到了线程,我们需要手动添加参数 -lpthread。

因为有很多的文件,还要去链接很多的第三方库。所以在编译的时候命令会很长,并且在编译的时候我们可能会涉及到文件链接的顺序问题,所以手动编译会很麻烦。

如果我们学会使用 Makefile 就不一样了,它会彻底简化编译的操作。把要编译的库文件放在 Makefile 中,制定相应的规则和对应的链接顺序。这样只需要执行 make 命令,工程就会自动编译。每次想要编译工程的时候就执行 make ,省略掉手动编译中的参数选项和命令,非常的方便。

2)编译大的工程会花费很长的时间

如果我们去做项目开发,免不了要去修改工程项目的源文件,每次修改后都要去重新编译。一个大的工程项目可不止有几个的源文件,里面的源文件个数可能有成百上千个。例如一个内核,或者是一个软件的源码包。这些都是我们做开发经常会遇到的。要完成这样的文件的编译,我们消耗的时间可不是一点点。如果文件特别大的话我们可能要花上半天的时间。

对于这样的问题我们 Makefile 可以解决吗?当然是可以的,Makefile 支持多线程并发操作,会极大的缩短我们的编译时间,并且当我们修改了源文件之后,编译整个工程的时候,make 命令只会编译我们修改过的文件,没有修改的文件不用重新编译,也极大的解决了我们耗费时间的问题。

这些是我们遇到的比较常见的问题,当然可能遇到的问题还会有很多,比如:工程文件中的源文件的类型很多,编译的话需要选择的编译器;文件可能会分布在不同的目录中,使用时需要调价路径。这些问题都可以通过 Makefile 解决。并且文件中的 Makefile 只需要完成一次,一般我们只要不增加或者是删除工程中的文件,Makefile 基本上不用去修改,编译时只用一个 make 命令。为我们提供了极大的便利,很大程度上提高编译的效率。

Makefile的书写规则

我们已经知道了 Makefile 描述的是文件编译的相关规则,它的规则主要是两个组成部分,分别是依赖的关系和执行的命令,其结构如下所示:

在这里插入图片描述
相关说明如下:
在这里插入图片描述

举例如下:
在这里插入图片描述

简单概括一下 Makefile 中的内容,主要包含五个部分,分别是:

在这里插入图片描述

Makefile的工作流程

  • 当我们在执行 make 条命令的时候,make 就会去当前文件下找要执行的编译规则,也就是 Makefile 文件。
  • 我们编写 Makefile 的时候可以使用名称:“GNUmakefile”、“makefile”、“Makefile”,make 执行时会去寻找 Makefile 文件。
  • 我们推荐使用 Makefile(一般在工程中都这么大写,大写的会比较规范)。如果文件不存在,make 就会报错,提示:make:*** 没有明确目标并且找不到 makefile。停止

通过一个具体的例子来看,创建一个包含有多个源文件和 Makefile 的目录文件,源文件之间互相关联。在 Makefile 中添加下面的代码:
在这里插入图片描述

在我们编译项目文件的时候,默认情况下,make 执行的是 Makefile 中的第一规则(Makefile 中出现的第一个依赖关系),此规则的第一目标称之为“最终目标”或者是“终极目标”。

在 shell 命令行执行的 make 命令,就可以得到可执行文件 main 和中间文件 main.o、test1.o 和 test2.o,main 就是我们要生成的最终文件。通过 Makefile 我们可以发现,目标 main"在 Makefile 中是第一个目标,因此它就是 make 的终极目标,当修改过任何 C 文件后,执行 make 将会重建终极目标 main。

它的具体工作顺序是:当在 shell 提示符下输入 make 命令以后。 make 读取当前目录下的 Makefile 文件,并将 Makefile 文件中的第一个目标作为其执行的“终极目标”,开始处理第一个规则(终极目标所在的规则)。在我们的例子中,第一个规则就是目标 “main” 所在的规则。规则描述了 “main” 的依赖关系,并定义了链接 “.o” 文件生成目标 “main” 的命令;make 在执行这个规则所定义的命令之前,首先处理目标 “main” 的所有的依赖文件(例子中的那些 “.o” 文件)的更新规则(以这些 “.o” 文件为目标的规则)。

对这些 “.o” 文件为目标的规则处理有下列三种情况:

  • 目标 “.o” 文件不存在,使用其描述规则创建它;
  • 目标 “.o” 文件存在,目标 “.o” 文件所依赖的 “.c” 源文件 “.h” 文件中的任何一个比目标 “.o” 文件“更新”(在上一次 make 之后被修改)。则根据规则重新编译生成它;
  • 目标 “.o” 文件存在,目标 “.o” 文件比它的任何一个依赖文件(".c" 源文件、".h" 文件)“更新”(它的依赖文件在上一次 make 之后没有被修改),则什么也不做。

清除工作目录中的过程文件

在这里插入图片描述
我们先简单介绍这些吧,更详细的可以参考下面的参考资料。
在这里插入图片描述

参考资料

Makefile

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值