实战Makefile
1.1 手动编译
1.2 文件编译依赖树
<1>. 没有makefile的日子
1.1 程序是如何编译的?
如果存在这么一个工程目录结构:
如果想要编译上面的工程,在没有使用makefile的情况下,可能需要使用如下的编译命令:
通过上面的命令生成nomakefile工程编译完成的文件。那么可能比较懒的程序员就在想这个很类似于一个批处理的过程,那么能不能将整个过程编写成脚本的形式,减少命令的输入,makefile就是用来将手动编译自动化的一个工具。
1.2 文件编译依赖树
查看上面的手动编译流程的话,为了生成nomakefile文件,需要存在foo.o文件和main.o文件,如果想要生成foo.o文件,需要编译foo.c,为了生成main.o,那么需要编译main.c文件,如此即生成一个所谓的文件编译依赖树:
通过手动编译文件的话,显然是将文件全部重新编译,在makefile中如果说依赖的文件没有更新的话,那么目标文件是不会重新编译的。
<2>. 快速体验makefile
还是上面例子如果使用makefile来管理,事情会变得如此简单,首先编写makefile文件:
# makefile comment
.
查看上面的makefile,可以看出:
1. makefile中可以使用#添加行注释
2. makefile文件笼统的将是一个个规则的集合,每个规则是由目标开始,然后是该目标依赖的文件,下一行以tab键开始,然后是生成目标所需的命令。
目标:依赖文件,以空格隔开
生成目标文件的命令
3. makefile在执行默认会将第一个目标做为最终目标,在这个文件就是hellomakefile,make在执行时将自动生成“最终目标”所依赖的文件,也就是main.o和foo.o文件。
4. makefile中可以定义变量(或者称之为宏),在程序的其他部分中使用,这里也就是变量(宏) OBJECTS。
5. makefile中可以使用内建函数,例如上面中的@echo函数。
<3>. makefile变量
makefile中用户可以自定义变量,例如:OBJECTS=foo.o main.o,那么在下面的makefile中可以使用${OBJECTS}代替该变量定义的值(foo.o,main.o)。另外可以使用默认变量:
$@:表明的是目标文件名,例如在foo.o:foo.c foo.h中$@表示的就是foo.o
$<:表明的是目标所依赖的文件的第一个文件,例如在 foo.o:foo.c foo.h表明的是就是foo.c文件。
$?:表明的是所有比目标文件更新的文件的集合,其中使用空格个风格。对于 foo.o:foo.c foo.h,如果更新了foo.c文件,那么重新make时,将$?将显示foo.c。这里需要注意的是如果更新了foo.h文件,那么$?将显示foo.c和foo.h文件,主要原因是在foo.c文件中包含了foo.h文件。
<4>. 条件编译
makefile中可以使用类似于编程语言中的跳转命令,如果满足一定的条件,将执行一定的动作。常见的条件编译指令:
ifeq(arg1, arg2) .. endif:如果arg1和arg2相等的话,将执行该区域中的内容。
ifneq(arg1, arg2) .. endif:如果arg1和arg2不相等的话,将执行该区域内的内容。
ifdef ARG .. endif:判定ARG变量是否已经定义
ifndef ARG .. endif:和ifdef相反
上面的语句可以和else一起来使用:
ifneq ("same", "diff")
<5>. makefile函数
makefile中可以使用内建函数,makefile中的内建函数大多是和字符串相关和目录相关函数。makefile中函数使用$(function-name function-arg),例如$(strip($(STR))),makefile中内建函数大多是和字符串相关的函数,常用函数:strip,finstring等,这些函数和高级语言中的string类的方法是极为类似的,具体可以参考[这里]。
<6>. 参考资料
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?