前言
带大家入门Makefile,学习目标和依赖的关系
一.什么是Makefile
Makefile是一个定义了如何构建一个软件项目的文本文件。
Makefile通常包含了一系列的规则和指令,这些规则和指令描述了如何从源代码和其他资源文件构建出一个软件项目的目标文件(如可执行文件或库文件)。它的主要作用是自动化编译过程,确保只编译修改过的源文件,从而提高编译效率。以下是Makefile的一些关键点:
- 规则和依赖:Makefile中定义了目标文件及其依赖关系,以及生成这些目标所需的命令。
- 自动化编译:通过使用Makefile,开发者可以简化编译过程,只需执行
make
命令,就可以自动执行所有必要的步骤来构建项目。- 变量和函数:Makefile支持变量和函数的使用,这可以帮助管理复杂的项目结构和路径,以及避免重复的命令。
- 默认和模式规则:Makefile允许定义默认目标和模式规则,使得可以根据文件的扩展名自动应用特定的规则。
- 工具链:Makefile通常与编译器、链接器和其他工具一起使用,以形成一个完整的工具链,用于从源代码到最终可执行文件的转换。
- 跨平台兼容性:Makefile可以在不同的操作系统和平台上使用,只要相应的编译工具可用。
- 调试和维护:Makefile还可以包含用于调试和维护的特定指令,如清理生成的文件或打印调试信息。
- 版本控制集成:Makefile可以与版本控制系统(如Git)集成,以实现源代码管理和构建过程的自动化。
- 性能优化:通过合理的Makefile设计,可以减少不必要的编译步骤,提高整体构建性能。
- 灵活性:Makefile可以根据项目需求进行高度定制,满足不同项目的特定构建需求。
Makefile是软件开发中不可或缺的一部分,它通过提供一个标准化的构建流程,确保了代码的一致性和可重复性。在企业级项目中,尤其是那些包含大量源文件和复杂结构的项目中,Makefile的作用尤为重要。
二.Makefile入门
2.1 Makefile入门
在开发的过程当中,假设我们对 x.c 这个源文件进行了修改,那么,为了在最终的 image
当中体现出来,我们必须重新编译生成 x.o,然后必须重新编译链接生成 image 文件,此
过程中,其他未经修改的文件以及他们的目标文件都不需要改动:现在,make 的工作目的就很清楚:编译那些需要编译的文件,那么究竟哪些文件需要
重新编译呢?这个原理也非常简单:根据文件的时间戳来进行判断。每个文件都会记录其最
近修改时间,我们只需要对比源文件及其生成的目标文件的时间戳,就可以判断他们的新旧
关系,从而决定要不要编译。比方说我们刚刚修改了 x.c 这个文件,那么他的时间戳将会被
更新为当前最新的系统时间,这样 make 通过对比就可以知道 x.c 比 x.o 要新,因此在需
要使用 x.o 的时候就会自动重新编译 x.o,这样又会导致 x.o 的时间戳比 image 要新,于
是 image 也会被自动重新编译,这种递推关系会在每一层目标-依赖之间传递。
2.2 书写格式
上面讲到,其实 make 的工作原理就是分析判断所谓的“目标-依赖”对,根据他们的
存在性和时间戳,来决定下一步动作,这个最根本最原始的工作原理其实跟什么工程管理是
没有关系的,比如我们可以写一简单的 Makefile:
2.3 目标依赖
2.3.1 目标不存在,依赖不存在
当even目标不存在时
even: echo "hello even"
2.3.2 目标存在,依赖不存在
如果目标文件已经存在,规则中有写依赖并且依赖文件比目标文件更新,则规则会被执行 注意制表符表示后面紧接着的是一个Shell 命令
目标even存在时,无依赖
even: echo "hello even"
这是一个Makefile的输出信息,表示目标文件"even"已经是最新的,不需要重新编译。
2.3.2 目标存在,依赖存在
目标存在,依赖时间戳比目标新
目标存在,依赖时间戳比目标晚:则不会执行
2.3.2 目标存在,依赖不存在
目标存在,依赖不存在
三.目标依赖嵌套
目标与依赖的互相嵌套(类似函数调用)
even:ccc echo "hello even" ccc:cui echo "hello ccc" cui:zhangsan echo "hello cui" zhangsan:
可以看出结果为
四.动态库make编译测试
这里给出了一个动态库,/lib/libmy_lib.so环境已经默认配好了。现在我们需要在/bin/目录下生成可执行文件main
Makefile文件
./bin/main:./src/*.c gcc ./src/*.c -o ./bin/main -I./inc -L./lib -lmy_lib
输入make运行
可以看出在/bin/目录下已经生成main文件了
运行./bin/main;可以运行
以上是本期内容,若有不懂或者错误欢迎评论!!!