linux下,Makefile是啥??

2022-05-10 08:41:26 浏览数 (1)

为什么要学习Makefile?

Linux环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是Unix程序员。在Linux(unix)环境下使用GNU的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一些时间去完成一个或者多个称之为Makefile 文件的编写。

--引用某du

根据上面黄色标注的文字,你觉得需要学习Makefile吗?

《概念篇》

Makefile的概念

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile就像一个Shell脚本一样,也可以执行操作系统的命令。

Makefile的命名规则

默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、 “makefile”、“Makefile”的文件,在这三个文件名中,最好使用“Makefile”。因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好不要用“GNUmakefile”,是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,大多数的make都支持“makefile”和“Makefile”这两种默认文件名。

Makefile也可以为其他名字,比如makefile.linux,但你需要使用make的参数(-f or --file)制定对应的文件,例如:

代码语言:javascript复制
make -f makefile.linux

Makefile的规则

Makefile的规则:

代码语言:javascript复制
target: prerequisites
    command
  • target:可以是一个object file(目标文件),也可以是一个执行文件,还可以是一个标签(label)。
  • prerequisites:生成该target所依赖的文件和/或target
  • command:该target要执行的命令

上面三者的关系:target这一个或多个的目标文件依赖于prerequisites中的文件, 其生成规则定义在command中。

举个例子,比如我们平时要编译一个文件:

代码语言:javascript复制
gcc main.c -o main

换成Makefile的书写格式:

代码语言:javascript复制
main:main.c
  gcc main.c -o main

Makefile的工作流程

  1. 执行make会在当前目录下找名字叫“Makefile” or “makefile”的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“main”这个 文件,并把这个文件作为最终的目标文件。
  3. 如果main文件不存在,或是main所依赖的后面的.o文件的文件修改时间要比main这个 文件新,那么,他就会执行后面所定义的命令来生成main这个文件。
  4. 如果main所依赖的.o文件也不存在,那么make会在当前文件中找目标为 .o文件 的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
  5. 当然,你的C文件和H文件是存在的啦,于是make会生成.o文件,然后再用.o文件生 成make的终极任务,也就是执行文件main了。

执行make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在执行过程中,如果出现错误,比如被依赖的文件找不到,那么make就会直接退出,并报错,而对于所 定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性。

在上述黄色自体中,可以明确的是,make执行时,它会校验依赖文件的更性时间,如果目标文件跟依赖文件时间一致,则不会相应的命令。

Makefile包含什么内容

Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

  1. 显式规则。显式规则说明了如何生成一个或多个目标文件。这是由Makefile的书写者明显指出要生成的 文件、文件的依赖文件和生成的命令。
  2. 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较简略地书写 Makefile,这是由make所支持的。
  3. 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像你C语言中的 宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
  4. 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中 的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一 样;还有就是定义一个多行的命令。
  5. 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用#字符,这个就 像C/C 中的//一样。如果你要在你的Makefile中使用#字符,可以用反斜杠进行 转义,如:#

make的工作方式

make的执行步骤如下:

  1. 读入所有的Makefile。
  2. 读入被include的其它Makefile。
  3. 初始化文件中的变量。
  4. 推导隐晦规则,并分析所有规则。
  5. 为所有的目标文件创建依赖关系链。
  6. 根据依赖关系,决定哪些目标要重新生成。
  7. 执行生成命令。

Makefile分为多个章节进行书写,有些概念描述参考与某些资料。

0 人点赞