Makefile 是一种常用于编译的脚本语言,它可以更好更方便的管理你的项目的代码编译,节约编译时间(没改动的文件不编译)。
注意 Makefile 文件命令必须是 Makefile 或者 makefile,并使用 make 命令编译。
1. 1个规则
目标...: 依赖... 目标:即要生成的文件;依赖:即目标文件由哪些文件生成
命令1 命令:注意每条命令前必须有且仅有一个 tab 保持缩进,这是语法要求。
命令2
...
伪目标:
在Makefile中,.PHONY后面的target表示的是一个伪造的target, 而不是真实存在的文件target,注意Makefile的target默认是文件。
如:对于工程的清理,需要写一个clean功能,这种类似的功能,不需要依赖文件,这种命令称作伪目标。
.PHONY关键字介绍:
小结:
用.PHONY声明的伪目标,在同级目录下
单词“clean”不代表此Makefile中的文件名;
Makefile与名为“clean”的文件无关
2. Makefile中的变量
1.用户自定义变量 --宏
OBJ = main.o func1.o ...
hello : $(OBJ)
gcc $(OBJ) -o hell
2.预定义变量
AR --> ar
CC --> 编译器
ARFLAGS --> 库编译选项
CFLAGS --> C编译器选项
#举例 CFLAGS = -g -c
gcc $(CFLAGS) func.c
3.自动变量
$* --> 不包含扩展名的目标文件名称 #main.o : main.c $* 表示main.o 中的main
$< --> 表示第一个依赖文件的名称
$? --> 所有时间戳比目标文件晚的依赖文件
$@ --> 目标文件的完成名称
$^ --> 所有不重复的依赖文件
# hello : main.o func1.o
# $(CC) $^ -o $@
3. makefile 条件判断
ifeq ($(CC),gcc) #不等于ifneq ($(变量名),比较值);ifeq和小括号之间右空格
gcc $^ -o $@
else
$(CC) $^ -o $@
endif
注意:条件判断不能用tab 打头,要顶格书写
4. Makefile的嵌套和引用
1)引用:include proc/makefile
Makefile中的include命令与C语言中的include命令类似,命令include file.dep,即把file.dep文件在当前Makefile文件中展开,亦即把file.dep文件的内容包含进当前Makefile文件;
如果Makefile中有以file.dep为目标的规则,make会先使用规则对file.dep文件进行更新,然后将更新后的file.dep文件包含进当前Makefile文件。
2)嵌套
$(MAKE) -C subdir(cd subdir ; 执行make命令)
make -C ./toolchain/ clean all(cd ./toolchain/ ; 执行 make clean + make all命令)
5. makefile 管理命令
-C dir 执行指定文件夹下面的makefile
-f file 读入当前文件夹下的file 为 Makefile(当同一级别中有多个makefile文件)
-i 忽略所有命令执行的错误
-I dir 指定被包含(include)的Makefile 的路径
6. 常用函数
1)wildcard(通配符匹配函数)
在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard”
如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空
例如:
$(wildcard *.c)来获取工作目录下的所有的.c文件列表(默认当前目录)
2)notdir
notdir用于去掉文件的绝对路径,只保留文件名。一般结合wildcard使用;
格式:$(notdir 文件列表)
例子:
$(notdir $(wildcard *.sh)):对匹配的全部脚本只保留文件名
3)patsubst(模式字符串替换函数)
格式:$(patsubst <pattern>,<replacement>,<text> )
功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换。
这里,<pattern>可以包括通配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含义的“%”字符)
返回:函数返回被替换过后的字符串。一般结合wildcard/notdir使用;
例子:
SCRIPTS = $(notdir $(wildcard *.c)) #匹配全部的.c文件
FILES = $(patsubst %.c,%.sh, $(SCRIPTS)) #将.c文件全部转换为.sh脚本文件
注意:只是在代码中进行模式替换,真实文件类型未改变