虽然makefile手写比较麻烦,已经被CMakeLists取代,但是makefile编写对于以前老项目编译流程了解还是十分重要的,以前makefile也算是风靡一时,终究被时代发展所遗弃。因为CMakeLists简洁和方便,直接干翻makefile,但是CMakeLists其实底层还是makefile,大家在cmake时候发现会生成makefile,可见CMakeLists是为了简化makefile开发流程而开发出来的。好了废话不多说。makefile整个是建立在目标-依赖-命令规则基础,比如下面一个场景
一盘菜:酱油 盐 油
开始炒菜
上面就是基于类似于规则
all: target1 target2 target3
target1: # 编译规则1
target2: # 编译规则2
target3: # 编译规则3
all被设置为第一个目标,并且target1、target2和target3被列为all的依赖。当你在命令行中运行make时,make命令会寻找并执行all目标规则,这将依次执行target1、target2和target3的编译规则。因此,通过在Makefile中设置all作为默认目标规则,你可以简化构建过程,只需运行make命令即可执行整个编译过程,无需显式指定目标
(1)常见$符合用法
^ 表示所有的依赖文件@ 表示生成的目标文件
(2)变量赋值
1、"="是最普通的等号,在Makefile中容易搞错赋值等号,使用 “=”进行赋值,变量的值是整个Makefile中最后被指定的值。
VIR_A = A
VIR_B = $(VIR_A) B
VIR_A = AA
经过上面的赋值后,最后VIR_B的值是AA B,而不是A B,在make时,会把整个Makefile展开,来决定变量的值
2、“:=” 表示直接赋值,赋予当前位置的值。
VIR_A := A
VIR_B := $(VIR_A) B
VIR_A := AA
最后BIR_B的值是A B,即根据当前位置进行赋值。因此相当于“=”,“:=”才是真正意义上的直接赋值
3、“?=” 表示如果该变量没有被赋值,赋值予等号后面的值。
VIR ?= new_value
如果VIR在之前没有被赋值,那么VIR的值就为new_value。
VIR := old_value
VIR ?= new_value
这种情况下,VIR的值就是old_value
4、"+="和平时写代码的理解是一样的,表示将符号后面的值添加到前面的变量上
(3)自带变量
代码语言:javascript复制CC = gcc #arm-linux-gcc
CPPFLAGS : C预处理的选项 -I
CFLAGS: C编译器的选项 -Wall -g -c
LDFLAGS : 链接器选项 -L -l(4)makefile常用函数
代码语言:javascript复制1. wildcard – 查找指定目录下的指定类型的文件
src=$(wildcard *.c) //找到当前目录下所有后缀为.c的文件,赋值给src
2. patsubst – 匹配替换
obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o(5)makefile退出码
make 退出码Makefile的退出码有以下3种:
0 :: 表示成功执行
1 :: 表示make命令出现了错误
2 :: 使用了 “-q” 选项, 并且make使得一些目标不需要更新
(6)自动变量
(7)命令参数变量
更多命令参数变量:
[RM] rm -f
[AR] ar
[CC] cc
[CXX] g++
(8)通配符
通配符 *表示任意一个或多个字符
? 表示任意一个字符
[...] [abcd] 表示a,b,c,d中任意一个字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一个数字
(9)伪目标
伪目标 .PHONY
代码语言:javascript复制.PHONY : clean
clean :
-rm edit $(objects)