简介
Gnu Make主要用于构建和管理程序包。Makefile文件描述了整个工程的编译、连接等规则。
其中包括:
工程中的哪些源文件需要编译以及如何编译;
需要创建那些库文件以及如何创建这些库文件;
如何最后产生我们想要得可执行文件。
make是一个命令工具,它解释Makefile中的指令(应该说是规则),Makefile中描述了工程中所有文件的编译顺序、规则。
Makefile有自己的书写格式、关键字、函数。像C语言有自己的格式、关键字和函数一样。
而且在Makefile中可以使用shell所提供的任何命令来完成你想要的工作。
详细请看《GNU make中文手册》。
1.make规则
工程中以下几种文件在执行make时将会被编译:
所有的源文件没有被编译过,则对各个C源文件进行编译并进行链接,生成最后的可执行程序。
每一个在上次执行make之后修改过的C源代码文件在本次执行make时将会被重新编译。
头文件在上一次执行make之后被修改。则所有包含此头文件的C源文件在本次执行make时将会被重新编译。
一个简单的Makefile描述规则组成:
TARGET... : PREREQUISITES...
COMMAND
...
...
target:规则的目标。通常是程序中间或者最后需要生成的文件名。可以是.o文件、也可以是最后的可执行程序的文件名。
另外,目标也可以是一个make执行的动作的名称,如目标“clean”,“all”,称为伪目标。
prerequisites:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。
command:规则的命令行。是make程序所有执行的动作(任意的shell命令或者可在shell下执行的程序)。一个规则可以有多个命令行,每一条命令占一行。
注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉make此行是一个命令行。
make按照命令完成相应的动作。这也是书写Makefile中容易产生,而且比较隐蔽的错误。
2. make命名
make工具搜索的makefile名字次序是”GNUmakefile”、”makefile”、”Makefile”。
3.包含其他的makefile文件
include filename
如include $(SD)/config/rules.mk
找不到文件将提示错误,如果用-include 将忽略错误,继续make执行。
4.makefile执行过程
- 依次读取一些特殊环境变量
- 读取makefile文件内容
- 依次读取工作目录makefile文件中使用指示符“include”包含的文件
- 查找重建所有已读取的makefile文件的规则(如果存在一个目标是当前读取的某一个makefile文件,则执行此规则重建此makefile文件,完成以后从第一步开始重新执行。
- 初始化变量值并展开那些需要立即展开的变量和函数并根据预设条件确定执行分支
- 根据“终极目标”以及其他目标的依赖关系建立依赖关系链表
- 执行除“终极目标”以外的所有的目标的规则(规则中如果依赖文件中任一个文件的时间戳比目标文件新,则使用规则所定义的命令重建目标文件)
- 执行“终极目标”所在的规则
5.makefile语法要点
- 变量和函数引用
$(variable)
2.变量赋值与展开
:= 表示立即展开,其他赋值表示延后展开,目标重建时才展开。
3.通配符
*匹配一个或多个的字符
?匹配一个字符
由于变量定义时通配符不会立即展开,需要使用wildcard让其有效。即$(wildcard *.c)即获取所有以.c为后缀的文件名。
4.搜索路径变量VPATH
指Makefile中所有文件的搜索路径,包括依赖文件和目标文件。以空格或者“:”隔开。
当前目录永远都是第一个要搜索的目录。
5.自动化变量
$@ 表示目标文件
$% 规则的目标文件是一个静态库文件时,代表静态库的一个成员名
$< 规则的第一个依赖文件名。如果是隐含规则,则它代表通过目标指定的第一个依赖文件
$? 所有比目标文件更新的依赖文件列表,空格分割
$^ 规则的所有依赖文件列表,使用空格分隔
6.隐含模式
$(OBJ_C) : %.o : %.c
@echo $(SRC_C)
$(CC) $(CC_OPTS) -o $@ $<
表示:重建的目标是$(OBJ_C_32),对目标中的每一个文件,其后缀是.o,将会用对应的.c来重建,重建的命令是$(CC) $(CC_OPTS) -o $@ $<。-o $@表示输出文件名,$<规则的第一个依赖文件名,是.c文件。
7.伪目标
伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时我们也可以将一个伪目标称为标签。
如”all”, “clean”等。需用关键字.PHONY定义:
.PHONY : clean
这样,我们可以直接make clean执行这个伪目标。
直接执行make时,会默认执行all这个伪目标,如果all不存在,则执行第一个遇到的目标
8.命令回显
执行命令前加@即不回显,否则回显。
9.命令行选项
-B 强制重建所有目标
-C DIR 在读取makefile之前,把工作目录切换到DIR
-f=FILE/--file=FILE/--makefile=FILE 指定”FILE”是makefile
-i 忽略规则命令执行错误
-k/--keep-going 执行命令错误时不终止make执行,让其一次性编译所有模块后再来修改。
-n/--just-print只打印执行命令,不执行。
-t/--touch更新目标文件的时间戳到当前系统时间。
来源:https://www.cnblogs.com/yanghong-hnu/p/4748158.html