makefile学习笔记
Makefile 学习笔记
Makefile 执行步骤
- 读入Makefile
- 读入被include的其它Makefile
- 初始化Makefile中的变量
- 推导隐晦规则,并分析所有规则
- 为所有目标创建依赖关系链
- 根据依赖关系,决定哪些目标需要重新生成
- 执行生成命令
Makefile 概念
- 目标(target):指要做什么
- 依赖(dependency):告诉 make 如何去做以实现目标
- 伪目标:没有依赖的目标,makefile也不会判断该目标是否需要更新;一般使用 .PHONY 来修饰,例如:.PHONY:clean
- 执行命令:达成目标需要执行的动作,使用 作为前缀;存在命令行的目标,不会使用自动推导
Makefile 工作原理
make [-f file] [options] [target] Make 默认在当前目录中寻找文件名为 GUNmakefile,Makefile,makefile 的文件作为 make 的输入文件。
- -f 可以指定除上述文件名之外的文件作为输入文件;
- -v 显示版本号;
- -n 只输出命令,但并不执行,一般用来测试;
- -s 只执行命令,但不显示具体命令,此处可在命令中用@符抑制命令输出;
- -w 显示执行前执行后的路径
- -C dir 指定 makefile 所在的目录
没有指定目标时,默认使用第一个目标。如果指定,则执行对应的命令。
简单 Makefile
准备文件
- 在当前目录下创建一个 C 文件
#include <stdio.h>
int main(int argc, char**argv)
{
printf("hello world!\n");
return 0;
}
- 文件夹下的文件:
.
├── main.c
└── Makefile
- Makefile 文件内容:
main:
gcc main.c
- 执行 make 命令后
.
├── a.out
├── main.c
└── Makefile
这里,make 会执行 gcc 命令生成 a.out 可执行文件。
在这里 test 目标没有依赖,只有一个执行命令 gcc,该命令会直接将 main.c 编译并生成可执行文件 a.out
注:
命令行的开头使用 标记,不能使用空格
给 Makefile 中的目标添加依赖
下面我们将 Makefile 文件更改一下
1 main:main.o
2
3 main.o:
4 gcc -c main.o main.c
执行后的文件夹
.
├── main
├── main.c
├── main.o
└── Makefile
Makefile 中:
-
第一行
main:main.o
表示生成目标为main
,该目标依赖于main.o
-
由于第一行没有找到依赖
main.o
所以先会执行第三行; -
第三行
main.o
表示生成一个没有依赖的目标,该目标执行的命令为gcc -c main.o main.c
-
当第三行生成目标
main.o
后,会根据第一样的依赖关系生成最终的目标文件main
这里的第一行只有依赖没有可执行命令,其实是使用了 make 的自动推导功能,即由 main.o 生成 main 的过程,make 可以自动识别并调用响应的命令去执行。其实这里可以将 Makefile 简化成一个依赖,即
main:main.o
,make 会自动进行编译和链接。
Makefile 变量
- 自定义变量
变量定义:变量名=变量值
变量引用:$(变量名)或 ${变量名}
A = xxx // 延时变量
B ?= xxx // 延时变量,只有第一次定义时赋值才成功;如果曾定义过,此赋值无效
C := x