Makfile 中的变量
我们应该时刻记住makefile 只不过是make的输入文件而已,make是一个程序,Makefile的语法是针对make这个程序而言的,它不是shell语法
本文参考了如下文献:
-Makefile中的变量定义
变量的定义
在Makefile中,除了目标,就是变量【当然,其他的诸如自定义函数之类的就不作为主体考虑了】 在Makefile中变量的定义遵循以下的规则。
- make对变量名的大小写是敏感的,O和o是不同的名字
- 变量不能包括特殊字符#,、,$, etc.
- 自动化变量,make 自带了一群自动化变量,诸如: $@,$^,$< and $.
- 变量的赋值包括四种方式,
CC := abc #立即赋值
CC = abc #延后赋值
CC ?= abc #条件赋值
CC += abc #增加赋值
变量的展开
常见的一些表达式
$(MKCONFIG) $(@:_config=) arm xxx xxx xxx
# $(@:_config=)的含义:, $(subaddr:%.c=%.o)这个函数的意思就是把变量subaddr中所有符合%.c要求的都替换为%.o. 这是Makfile中的替换引用规则; 同样的道理,$(@:_config=)的意思就是将@中符合_config的部分直接替换成空,也就是去掉_config.(@实际上代表的就是目标target)。不过要注意,如果后面有字符,则需要有通配符。例如:sub=abc.c bbc.c ccd.c
@echo $(sub:bbc=hhh) #这个规则下是不会有任何动作的。因为bbc不能和bbc.c通配。
- MAKECMDGOALS
MAKECMDGOALS
变量代表的是make
的目标,比如说
make hello world
那么在Makefile 文件中,MAKECMDGOLAS变量就代表的是hello world
常见函数
ifeq, ifneq
ifeq和ifneq是makefile里的判断,ifeq ($(MAKECMDGOALS), clean)
判断变量MAKECMDGOALS是不是clean . 同理 ifneq 就是判断不相等,ifneq ($(CC),gcc)
意思就是如果$CC不等于gcc 则xxxxx。ifeq ($(target),) $(error "please specify the make target with make target=xxxx") # 如果target为空就终止makefile 的执行, error 函数就是停止并提示错误的函数 endif
上述这段代码中,还有一个地方就是,make命令可以向makefile 传递参数,比如说,
make all target=x86
其中target这个参数就会传递到Makefile中,用 $(target) 就可以获得这个参数,你可以尝试打印一下 echo $(target),结果会是x86.subst 和patsubst
subst , patsubst
两个都是替换函数,不过前者和后者是不一样的,patsubst
是正则匹配替换。比如$(patsubst %.c,%.s,$(SRC))
patsubst只会替换所有匹配%.c格式的输入,有人会问,如果是h.ca 这种格式的呢? 是不是符合%.c ? 答案是不符合,%.c 匹配必须是.c结尾的。
subst
纯粹就是替换子字符串的,输入需要替换什么,输出就把它替换了,比如说,把src目标里的abc替换成hef就用$(subst abc,hef,$(SRC))
注意,被替换的目标里如果有两个abc的话,它照样都会替换,比如$(subst abc,edf, abcxyzabc)
结果会替换成edfxyzedf.
除了替换函数,还有很多其他的函数,比如notdir
去除路径;wildcard
通配符扩展,这个函数比较常用,比如说我的 /src目录下有 a.c,b.c,xxxx.c 等很多c文件,具体列出来有很多不妥,因为src里的文件随着你项目的发展是不断增多的,不可能每增加文件就修改Makfile。使用wildcard即可 如:$(wildcard /src/*.c)
返回的就是列举了src下的所有.c文件。再配合一下notdir,就可获得src目录下所有的.c文件名称,且不带路径。例如:
#src下有 a.c , b.c e.c
echo $(wildcard src/*.c) #结果是 src/a.c src/b.c src/e.c
echo $(notdir $(wildcard src/*.c) #加上了去掉路径的函数,所以返回结果是a.c b.c e.c