前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux下,Makefile是啥??

linux下,Makefile是啥??

作者头像
Rice加饭
发布2022-05-10 08:41:26
1.2K0
发布2022-05-10 08:41:26
举报
文章被收录于专栏:Rice嵌入式

为什么要学习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分为多个章节进行书写,有些概念描述参考与某些资料。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Rice 嵌入式开发技术分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档