虽然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)自带变量
CC = gcc #arm-linux-gcc
CPPFLAGS : C预处理的选项 -I
CFLAGS: C编译器的选项 -Wall -g -c
LDFLAGS : 链接器选项 -L -l
(4)makefile常用函数
1. wildcard – 查找指定目录下的指定类型的文件
src=$(wildcard *.c) //找到当前目录下所有后缀为.c的文件,赋值给src
2. patsubst – 匹配替换
obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o
(5)makefile退出码
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
.PHONY : clean
clean :
-rm edit $(objects)