目录
一、为什么开发者需要构建工具?
在软件开发中,我们经常面临这样的场景:一个项目包含数十个源代码文件,需要经过编译、链接、测试等多个步骤。手动执行每个步骤不仅效率低下,更可能因操作失误导致构建失败。这正是GNU make工具及其搭档Makefile大显身手的舞台。
二、make/Makefile
1. Makefile基本规则
target: prerequisites
recipe
-
target:构建目标(通常是文件名或伪目标)
-
prerequisites:依赖文件(目标构建所需的文件或目标)
-
recipe:构建命令(必须以 Tab 开头,不能用空格)
make命令也可以写成是make test,为什么可以将test省略呢?因为make后面什么都不带会自动找到Makefile文件中的第一条依赖关系并执行依赖方法。
2.清理项目
上述示例我们生成了test可执行程序,如何进行清理项目呢?
那为什么要用.PHONY伪目标声明clean呢?
我们先多执行make命令几次试试看
只有修改test.c文件才能重新make,否则make就无效
gcc -o test test.c这个命令执行会有时间对比,它会对比test的修改时间和test.c修改时间,如果test的修改时间比test.c修改时间大,就不会执行(test总是在test.c之后才可形成)
.PHONY:让目标文件对应的方法总是被执行(让依赖方法忽略掉时间对比)
现在我们都注释掉伪目标
三、make的工作原理
make
的工作流程可以分为以下几个步骤:
1) 读取 Makefile
-
make
首先会查找当前目录下的Makefile
或makefile
文件。
2) 确定目标
-
如果没有指定目标(也就是只输入make),
make
会构建 Makefile 中的第一个目标文件(默认目标)。 -
如果指定了目标(例如
make clean
),make
会构建clean目标。
3) 解析依赖关系
-
make
会解析目标的依赖关系,递归检查所有依赖文件是否需要更新。 -
如果依赖文件也是目标,
make
会先构建这些依赖文件。
4) 完成构建
-
当所有目标和依赖都处理完毕后,
make
会结束构建过程。
依赖关系:
- test依赖test.o
- test.o依赖test.s
- test.s依赖test.i
- test.i依赖test.c
test依赖的文件test.o不存在,继续往后找,找到test.o依赖test.s不存在,继续往后找,...到test.i依赖test.c文件存在,就执行gcc -E test.c -o test.i生成test.i文件,依次往上执行(像一个栈的过程)。