文章目录
在终端输入make命令
就会调用make
工具,make
会在当前目录按照文件名顺序
寻找Makefile
文件,依次按照:GNUmakefile
、makefile
、Makefile
。
如果找到其中的任何一个(通常习惯采用的文件名是Makefile
),就读取并按照其中的规则执行
,否则报错。
Makefile 的规则:
1、目标
Makefile
的基本语法格式是:
target : prerequisites
<Tab> command
序号 | 组成 | 描述 |
---|---|---|
1 | target | 编译目标 target 既可以是目标文件 ,也可以是可执行文件 |
2 | prerequisites | 依赖关系文件 ,即生成target 所需要的文件 或者目标 |
3 | command | 生成target 所需执行的命令 |
make
会根据时间戳
来决定哪些文件需要重新编译
。对照这个规则来解释就是:在prerequisites
中,如果有一个以上
的文件比target
文件要新的话,command
所定义的命令就会被执行
。
2、伪目标
【伪目标】是一个【标签】,这个目标【只执行命令】,【不创建目标】,还能避免目标与工作目录下的实际文件名冲突
。写法如下:
.PHONY : 标签
在实际应用中,通常会有一个【clean】目标,这个目标几乎都会被设置为【伪目标】,用于【清除】编译产生的【中间文件】和【可执行文件】。在进行源码打包或者发布的时候,先通过make clean
命令清除,可得到纯净的代码文件
。
.PHONY : clean
<Tab> -$(RM) $(OBJ) $(EXE)
clean
伪目标的命令为-rm
,在rm
命令前加了-
,含义是如果这条命令执行失败
,make
将忽略
这个错误,继续往下执行;如果不加-
,则make
会停止。如果一个工程连续进行两次make clean
操作,那么在进行第二次clean
的时候,由于相关文件已经不存在了,所以make
会报错。加了-
,如果clean
出错,会被忽略
,而不加-
则不忽略。
3、自定义变量
make
支持在Makefile
文件中定义变量
。合理使用变量,能增强Makefile
文件的通用性,并简化Makefile
文件编写。一般的Makefile
文件编写中,通常会为源文件
、可执行文件
以及编译参数
等分别定义一个变量
,并予以赋值
,在编译规则中则直接引用这些变量。变量的定义
和赋值方法
通常是:
VAR = value
在用到变量
的地方,通过 美元符号$
和 括号()
一起来完成变量引用
,如 $(VAR)
。
4、makefile 变量
make
本身有一些特殊变量可以在Makefile
中使用,能进一步简化Makefile
的编写。这些特殊变量包括:环境变量
、自动化变量
和预定义变量
。
4.1 环境变量
环境变量
就是系统的环境变量
。Makefile
中基本上可以直接引用几乎所有
的系统环境变量
,比如代表当前登录用户的(USER)
,系统外部命令搜索路径(PATH)
等,这些变量都可以直接以$(VAR)
的方式引用。
4.2 自动化变量
自动化变量
不用定义,且会随着上下文的不同而发生改变。make
的自动化变量都是一些比较难记住的符号,都以美元符号$
开头。使用了自动化变量的Makefile
文件读起来会显得抽象和生涩一些。常用的make
自动化变量如表:
序号 | 自动化变量 | 描述 |
---|---|---|
1 | $@ | 目标文件名 |
2 | $< | 目标的第一个依赖文件名 |
3 | $^ | 目标所对应的所有依赖文件的列表 ,以空格 分隔 |
4 | $? | 目标所对应的依赖文件 新于目标文件 的文件列表,以空格 分隔 |
5 | $(@D) | 目标文件的目录部分 (如果目标在子目录中) |
6 | $(@F) | 目标文件的文件名部分 (如果目标在子目录中) |
4.3 预定义变量
预定义变量
。make
的预定义变量用于定义程序名称
以及传递给这些程序的参数
和标志位
等。常见的预定义变量和描述如表:
序号 | 预定义变量 | 描述 |
---|---|---|
1 | AR | 归档维护程序,默认值为 ar |
2 | AS | 汇编 程序,默认值为 as |
3 | CC | C语言编译 程序,默认值为cc |
4 | CPP | C语言预处理 程序,默认值为cpp |
5 | RM | 文件删除 程序,默认值为rm -f |
6 | ARFLAGS | 传递给AR程序 的标志,默认为 rv |
7 | ASFLAGS | 传递给AS程序 的标志,默认值无 |
8 | CFLAGS | 传递给CC程序 的标志,默认值无 |
9 | CPPFLAGS | 传递给CPP程序 的标志,默认值无 |
10 | LDFLAGS | 传递给链接程序 的标志,默认值无 |
5、隐式规则 和 显式规则
make
有一些既定的目标生成规则,称之为隐式规则
。例如对于一个file.o
文件,make
会优先寻找同名的file.c
文件,并按照gcc -c file.c -o file.o
的编译规则生成file.o
文件。对于不同语言
,有不同的隐式规则
,所以一般来说,不推荐用隐式规则。
5.1 显式规则
是用户自定义的规则
。
在使用隐式规则有隐患的情况下,更应当使用【显式规则】,明确指定生成规则
。例如前面提到的隐式规则,用【显式规则】来定义可为:
OBJ : $(SRC)
<Tab> $(CC) -o $(OBJ) -c $^
6、模式规则
如果不用【自定义变量】,还可以这么写,也称为【模式规则】:
%.o : %.c
<Tab> $(CC) -o $@ -c $<