Linux 项目自动化构建工具 —— make/makefile
创始人
2024-11-09 22:11:13

Linux 项目自动化构建工具 —— make/makefile

  • 入门使用
  • 原理
    • 自动化构建
      • 递归式自动推导
    • 清理
    • 注意
  • 特殊符号

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

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

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

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

入门使用

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

现在在当前路径下有 code.c 代码,需要手动 touch 一个名为 makefileMakefile 的文件

在里面写上如下代码:

mycode:code.c 	gcc -o mycode code.c -std=c99 .PHONY:clean clean: 	rm -f mycode 
  • 构建可执行文件
    • mycode:code.cmycode 是指未来形成的 可执行程序code.c 是指此可执行程序依赖 code.c 文件
    • gcc -o mycode code.c -std=c99 这一行前面有一个 Tab 键,内容就是 编译 指令,不多说
  • 清理
    • 接下来的指令就都是清理所用

返回命令行,运行 make 指令,即可构建可执行程序 mycode ;运行 make clean 即可清理 mycode 文件

至此,你已经完成了入门使用 ^ ^

原理

自动化构建

先看下图:
在这里插入图片描述

这里的每一行都有其名称

  • 依赖关系
    • : 右边是 依赖文件列表 ,图中就只有 code.c 文件;可以为空,但若有多文件,以空格为分隔符,例: code1.c code2.c code3.c
    • : 左边是 目标文件 ,图中为 mycode 可执行程序
  • 依赖方法
    • 在单纯语法上,这一行 必须以 Tab 键开头,也不可是 4 个空格

当你在运行指令 make 后,会在当前目录下寻找 makefile 文件,根据 makefile 文件里的 依赖关系 ,遵循 依赖方法 ,为你完成 依赖方法 里的工作,生成 目标文件

递归式自动推导

当你知道目标文件如何生成时,再来看看类似 递归式的连锁生成
先来看看 makefile 文件:

mycode:code.o 	gcc code.o -o mycode code.o:code.s 	gcc -c code.s -o code.o code.s:code.i 	gcc -S code.i -o code.s -std=c99 code.i:code.c 	gcc -E code.c -o code.i 

这就是 gcc 编译的每一步明细,在这里不做详细解释(如不明白,请查阅过往 gcc 拙作)

  1. 我们知道最终的目标文件是 mycode 可执行程序,但 : 后面的依赖文件 code.o 在我们当前路径下并没有
  2. 于是 make 就会在 makefile 文件里寻找名为 code.o 的目标文件
  3. 找到之后会根据 : 后面的依赖文件,再根据依赖方法来生成 code.o 目标文件
  4. 但当前路径下 code.o 的依赖文件 code.s 也没有,那 make 就会继续在 makefile 文件里寻找名为 code.s 的目标文件
  5. 于是一直找到 code.i 目标文件,它的依赖文件是存在的,那么就会生成 code.i ,继而生成 code.scode.o 直至最后的 mycode 可执行程序

那么这就很类似 栈式结构的递归调用 ,而上述就是 自动推导 makefile 中的依赖关系 的过程,即使乱序也可构建执行

清理

先看看 makefile 里的 clean 部分

clean: 	rm -f code.i code.s code.o mycode 

是否感觉和你要自动化构建的可执行程序写法十分相似?

实际上 clean 就是 makefile 里的 目标文件,只是它没有 依赖文件 而已(依赖文件列表可以为空),而下面就是 依赖方法 ,完成 依赖方法 里的工作,即为清理完成

而你要执行清理,就是生成 clean 这个目标文件,命令行也就需要在 make 后面指定要生成的目标文件,所以是:

make clean 

注意

  • 当你直接 make 时,make 会默认生成 makefile 里的第一个目标文件
  • 如果你要生成 makefile 里的其他的目标文件,就在 make 后面带上你要生成的目标文件( clean 就是如此)
  • 当你第二次再运行 make 时,只要 源文件 没有被更新修改,就会告诉你要生成的 目标文件 是最新的,不让你继续 make ,因为没有必要,为了提高效率(实现方法就是对比 源文件目标文件 的最近修改时间)
  • 要想 目标文件总是被执行,需要在 目标文件 前添加 .PHONY 声明,相当于告诉 make 不要管什么时间问题;而此时的 目标文件 也被称为 伪目标

特殊符号

依赖关系 里存在 目标文件依赖文件列表

那么在 依赖方法 里,就可以利用 $@$^ 分别表示 目标文件 和整个 依赖文件列表

在我们成功 make 时,命令行会给我们回显自动化构建的步骤,如果不想回显,可在 依赖方法 最前面添加 @

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...