Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Linux仓库】Linux内核:深度解剖Makefile如何管理百万行代码?

【Linux仓库】Linux内核:深度解剖Makefile如何管理百万行代码?

作者头像
egoist祈
发布于 2025-05-30 01:38:46
发布于 2025-05-30 01:38:46
6400
代码可运行
举报
文章被收录于专栏:egoistegoist
运行总次数:0
代码可运行

背景

  • 会不会写makefile,从⼀个侧⾯说明了⼀个⼈是否具备完成⼤型⼯程的能⼒
  • ⼀个⼯程中的源⽂件不计数,其按类型、功能、模块分别放在若⼲个⽬录中,makefile定义了⼀系列的规则来指定,哪些⽂件需要先编译,哪些⽂件需要后编译,哪些⽂件需要重新编译,甚⾄于进⾏更复杂的功能操作。
  • makefile带来的好处就是⸺“⾃动化编译”,⼀旦写好,只需要⼀个make命令,整个⼯程完全⾃动编译,极⼤的提⾼了软件开发的效率
  • make是⼀个命令⼯具,是⼀个解释makefile中指令的命令⼯具,⼀般来说,⼤多数的IDE都有这个命令,⽐如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可⻅,makefile都成为了⼀种在⼯程⽅⾯的编译⽅法。
  • make是⼀条命令,makefile是⼀个⽂件,两个搭配使⽤,完成项⽬⾃动化构建

理解make/Makefile

make是一个Linux系统内置的命令;

Makefile是一个需要工程师自己建立的的一个文件!

编写代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
code:code.c
    gcc -o code code.c

.PHONY:clean
clean:
    rm -f code

得到理论

上面这段代码中各自代表什么含义呢?


可以看到程序写完后,进行make时第一次没问题,但是多次make后会显示已是最新的,不能重新编译;但我们进行make clean时却可以无限次,这是为啥呢?

  1. 重复编译是需要耗费时间的,如果多次编译但源代码都是同一份显然是没有必要的;
  2. clean清除所有的⽬标⽂件,以便重编译,且能多次运行。

可以发现,clean的左边加上了 .PHONY ,这是什么意思呢?

.PHONY表示:被修饰的目标是一个伪目标,且伪目标总是被执行的。

啊?伪目标总是被执行是什么意思呢?由小编带着大家一步步解析。

要理解被执行,我们可以从总是不被执行作为切入点

上图中多次make不会再次编译,这就是不被执行。那它又是如何做到不被执行的呢?

在指令章节介绍了stat指令,它可以列出一个文件的访问、内容修改、属性修改时间。

  • Modify: 内容变更,时间更新
  • Change:属性变更,时间更新
  • Access:常指的是文件最近一次被访问的时间。在Linux的早期版本中,每当⽂件被访问时,其atime都会更新。但这种机制会导致⼤量的IO操作。(因此可能是多次访问只会修改一次)

在下图中,我们对一个未修改文件进行修改时,其文件内容最近修改时间发生了变化,此时可以重新make了。

因此,不被执行是根据文件内容最近修改时间与exe时间对比决定是否需要重新编译

那么,总不被执行即是忽略exe和文件内容最近修改时间对比。

结论:.PHONY:让make忽略源⽂件和可执⾏⽬标⽂件的M时间对⽐! 最佳实践:可执行程序,不需要修饰成.PHONY,clean修饰成总是被执行!

推导过程

上面这种方式是一步到位的,能否像gcc那样生成 .i , .s , .o 的临时文件呢?可以的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
​myproc:myproc.o
    gcc myproc.o -o myproc
myproc.o:myproc.s
    gcc -c myproc.s -o myproc.o
myproc.s:myproc.i
    gcc -S myproc.i -o myproc.s
myproc.i:myproc.c
    gcc -E myproc.c -o myproc.i

.PHONY:clean
clean:
    rm -f *.i *.s *.o myproc

根据上面这段程序及make工作规则进行解析:

  1. make会在当前⽬录下找名字叫“Makefile”或“makefile”的⽂件
  2. 如果找到,它会找⽂件中的第⼀个⽬标⽂件(target),在上⾯的例⼦中,他会找到 myproc 这个⽂件,并把这个⽂件作为最终的⽬标⽂件。
  3. 如果 myproc ⽂件不存在,或是 myproc 所依赖的后⾯的 myproc.o ⽂件的⽂件修改时间要⽐ myproc 这个⽂件新,那么,他就会执⾏后⾯所定义的命令来生成myproc 这个⽂件。
  4. 如果 myproc 所依赖的 myproc.o ⽂件不存在,那么 make 会在当前⽂件中找⽬标为myproc.o ⽂件的依赖性,如果找到则再根据那⼀个规则⽣成 myproc.o ⽂件。(像⼀个堆栈的过程)
  5. 就是整个make的依赖性,make会⼀层⼜⼀层地去找⽂件的依赖关系,直到最终编译出第⼀个⽬标⽂件。
  6. 在找寻的过程中,如果出现错误,⽐如最后被依赖的⽂件找不到,那么make就会直接退出,并报错,⽽对于所定义的命令的错误,或是编译不成功,make根本不理。
  7. make只管⽂件的依赖性,即如果在我找了依赖关系之后,冒号后⾯的⽂件还是不在,那么对不起,我就不⼯作啦。

简单而言 make/makefile 只默认形成一个目标,就是从上到下遇到的第一个目标,并根据依赖关系寻找,如果没有找到依赖关系就会报错,直到找到源文件为止。

但上面这种方法在实践中并不经常使用,像 .i .s 这种临时文件一般是不需要保留的,在vs上也是这样处理的,只保留 .o文件和 可执行程序。因此Makefile的最佳实践如下所示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
code:code.c
    gcc -o $@ $^ //$@ 代表:左边部分 $^代表:右边部分

.PHONY:clean
clean:
    rm -f code

扩展

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux自动化构建-make/Makefile
查看状态, 我们可以看到以下三个时间。 文件 = 内容 + 属性 以下简称acm时间, a表示最近一次访问的时间, M表示内容最近被修改的时间, C表示最近一个属性被修改的时间。 例如 : cat proc.c就是访问文件(但是访问频繁影响效率, 现在的操作系统已经这一块已经发生了变化。) chmod o-r proc.c 就是改变属性 vim proc.c 就是修改内容
用户11317877
2024/12/20
1430
Linux自动化构建-make/Makefile
自动化构建-make/Makefile 【Linux基础开发工具】
• 会不会写makefile,从一个侧面说明了一个⼈是否具备完成大型工程的能力 • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作 • makefile带来的好处就是⸺“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。 • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。 • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
小志biubiu
2025/02/27
2450
自动化构建-make/Makefile 【Linux基础开发工具】
【Linux系统编程】—— 自动化构建工具Makefile指南
Makefile 是衡量开发者是否具备完成大型工程能力的一个重要标志。在一个工程中,源文件的数量可能极多,这些文件会按照类型、功能或模块分布在多个目录中。Makefile 通过定义一系列规则,指定文件的编译顺序、依赖关系以及清理规则,从而实现自动化构建。
用户11286421
2025/01/17
2200
【Linux系统编程】—— 自动化构建工具Makefile指南
【linux篇】动静态库和自动化构建的“神之一手”:make、Makefile
在创建一个Makefile文件,里面写入如下代码。表示mycode文件依赖于code.c,下面就是正常的gcc编译
用户11456817
2025/05/28
1970
【linux篇】动静态库和自动化构建的“神之一手”:make、Makefile
【Linux必备工具】自动化构建工具makefile的使用详解
项目构建时遇到的各种挑战如文件编译顺序、库链接、依赖文件的管理等,在不同开发环境中会有不同的解决方案。
IsLand1314
2024/10/15
5100
【Linux必备工具】自动化构建工具makefile的使用详解
【Linux】自动化构建工具-make/Makefile
在上一篇中已经了解了【Linux】编译器-gcc/g++使用,这次来一起看看make/Makefile。
zxctscl
2024/03/21
1930
【Linux】自动化构建工具-make/Makefile
Linux项目自动化构建工具-make/Makefile
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
南桥
2024/02/18
2110
Linux项目自动化构建工具-make/Makefile
Linux项目自动化构建工具-make/makefile
会不会写makefile可以从侧面说明一个人是否具备完成大型工程的能力。 当在公司工作时,往往一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。 makefile带来的好处就是–”自动化编译“,只要预先写好makefile,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。 make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make。Visual C++的nmake,Linux下的GNU的make.可见,makefile都成为了一种在工程方面的优秀编译方法。 注意:make是一条命令,makefile是一个文件,两个需要搭配使用,完成项目自动化构建。
Yui_
2024/10/16
1170
Linux项目自动化构建工具-make/makefile
深入了解Linux —— make和makefile自动化构建工具
make是一个命令工具,是一个解释makefile在指令的命令工具,大多数的IDE都存在这个命令。
星辰与你
2024/12/29
4890
深入了解Linux —— make和makefile自动化构建工具
自动化构建与进度显示:全面解读 make 与 Makefile
make 是一个自动化构建工具,通过解析 makefile 文件中的规则,管理项目的构建流程。它的主要功能是根据源文件的修改情况,自动更新目标文件,避免手动输入复杂的编译命令。
HZzzzzLu
2024/12/26
3070
自动化构建与进度显示:全面解读 make 与 Makefile
【Linux系统】第五节—编译器gcc/g++和自动化构建makefile/Makefile(详解)
在我们的实际开发中,不可能将所有代码放在⼀个源⽂件中,所以会出现多个源⽂件,⽽且多个源⽂件之间不是独⽴的,⽽会存在多种依赖关系,如⼀个源⽂件可能要调⽤另⼀个源⽂件中定义的函数, 但是每个源⽂件都是独⽴编译的,即每个*.c⽂件会形成⼀个*.o⽂件,为了满⾜前⾯说的依赖关系,则 需要将这些源⽂件产⽣的⽬标⽂件进⾏链接,从⽽形成⼀个可以执⾏的程序。这个链接的过程就是静 态链接。静态链接的缺点很明显:
云边有个稻草人
2025/05/14
1170
【Linux系统】第五节—编译器gcc/g++和自动化构建makefile/Makefile(详解)
【Linux系统编程】Linux项目自动化构建工具——make/Makefile
make和makefile提供了自动化构建的能力,可以根据源文件的依赖关系和规则自动决定哪些文件需要重新编译。而直接使用gcc需要手动指定每个源文件的编译命令,不具备自动化的构建功能。
YIN_尹
2024/01/23
3740
【Linux系统编程】Linux项目自动化构建工具——make/Makefile
【Linux】————Makefile编写
此时目录下会有两个我们刚才创建的文件:Makefile和test.c 我们直接执行make命令:
用户11036582
2024/09/09
2380
【Linux】————Makefile编写
【linux】gcc makefile
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?
用户11029103
2024/09/25
4530
【linux】gcc makefile
【linux学习指南】Linux项目自动化构建工具 make /makefile&&进度条代码
一个工程中的源文件多不技计数,其按其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
学习起来吧
2024/09/11
7840
【linux学习指南】Linux项目自动化构建工具 make /makefile&&进度条代码
Linux项目自动化构建工具-make/Makefile
当多个源文件编译形成可执行程序时,只对其中的一两个文件进行修改时,重新编译源文件时,是全部重新编译还是编译部分?
绝活蛋炒饭
2024/12/16
1290
Linux项目自动化构建工具-make/Makefile
Linux基础——Linux开发工具(下)_make/makefile
前言:在经过前面两篇学习,大家对Linux开发工具都有一定的了解,而在此之前最重要的两个工具就是vim,gcc。
Eternity._
2024/06/14
5140
Linux基础——Linux开发工具(下)_make/makefile
【Linux操作系统】自动化编译make和Makefile
makefile中的[tab键]不可省略,更不可用空格代替,[tab键]不等于4个空格也不等于8个空格,1个tab键实际是4个字符,只不过代表的是4个字符.
MicroFrank
2023/01/16
9220
Linux项目自动化构建工具-make/Makefile
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
青衫哥
2023/03/31
8080
Linux项目自动化构建工具-make/Makefile
【Linux】gcc/g++的使用 自动化构建工具make/makefile的使用
所以我们现在要使用gcc编译生成可执行文件时,只需一次性把代码写到makefile文件里,在使用make命令就可以一件生成了,省去了重复写的麻烦,并且这个make是递归式生成的,所以写依赖关系和依赖方法时,不用担心顺序的问题。
aosei
2024/01/23
4740
【Linux】gcc/g++的使用 自动化构建工具make/makefile的使用
推荐阅读
相关推荐
Linux自动化构建-make/Makefile
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验