变量的特征:
1: 变量可通过等号(=)定义,也可通过define定义,引用都通过$()
2: 变量可以存储 文件列表,编译列表等
3: 变量明不可包括':', '#', '=', 前置空白, 尾空白。最好使用字母 数字 下划线。
4: 变量名对大小也敏感。建议局部使用小写字母的变量,全局是有大写字母的变量
5: 自动化变量,$<:第一个依赖; $@:目标; $^: 所有依赖; $?: 变化的依赖; $*: 目标的前缀
变量引用:
1: make中使用$()或者${}引用变量
SUBDIRS := src tool
.PHONY subdir
subdir:
@set -e;for d in $(SUBDIRS); do \
$(MAKE) -C d || exit 1; \
done
以上例子含义:去子目录下执行相应的make,出错立即退出。
递归展开式变量 "="
foo = $(bar)
bar = $(ugh)
ugh = HHH
在引用$(foo)的时候顺序如下: $(foo)被$(bar)替换,$(bar)被$(ugh)替换,最后$(ugh)被HHH替换。
递归展开的优点:可以引用未定义变量
递归展开缺点:
1:定义的变量在变量值中定义,导致死循环。e.g. CFLAGS = $(CFLAGS) -g
2:如果变量的值中是函数,则每次引用变量时,函数都会被执行。
直接展开式变量 ":="
不管变量值是一个引用还是一个函数,最后只会将最终的值替换到当前变量的值。
x:=foo
y:=$(x) bar
x:=later
$(warning $(y)) $(warning $(x))
输出结果 $(y)为 foo bar,$(x)为 later
CFLAGS := $(foo) -o
foo := -g
$(warning $(CFLAGS)) 输出的信息为:-o,因为在CFLAGS变量展开的时候,foo还没有定义,所以为空。
尽量减少使用递归展开赋值,建议使用直展开赋值
如何定义一个空格:
nullstring :=
space := $(nullstring) #end of line
space输出的是一个空格。nullstring是一个empty变量,在space中引用$(nullstring)表示变量值的开始,
通过#表示变量值的结束。在$(nullstring)和#之间存在一个空格。
错误用法:
foo := /home/ #some thing
以上这个例子的值是/home/后面跟着若干个空格,这个肯定是不希望的。因此在makefile中,尽量注释和变量赋值不要在一行中。
?=
判断变量有没有定义,已经定义则不重新赋值。如果没定义则赋值。和ifeq ($(origin foo), undefined) 功能相似。
foo ?= 1010
等价于:
ifeq ($(origin foo), undefined)
foo := 1010
endif
变量的替换:
将变量foo中的*.o替换成*.c
foo := a.o b.o c.o
bar := $(foo:.o=.c)
bar := $(foo:%.o=%.c)
bar := $(patsubst %.o, %.c,$(foo))
变量的嵌套:
不建议使用变量嵌套
x = y
y = z
a := $($(x))
a的结果为z。执行顺序:$(x)被y替换,成为$(y),$(y)被z替换,赋值给a。所以$(a)的值为z。
变量取值:
1:在make 命令行指定的变量会替换makefile中通过 = := += ?= define定义的变量。在makefile中通过override使得makefile中的变量生效。
override指示符的目的是修改make 命令设置的参数。
make CFLAGS = -O2
Makefile:
CFLAGS += -Wall
最后生效的CFLAGS的值还是-O2
============================
make CFLAGS = -O2
Makefile:
override CFLAGS += -Wall
最后生效的CFLAGS的值是 -O2 -Wall
=====================
override 使用:
override a = 100
override a := 100
override a += 100
override define foo
bar
end
目标指定变量 :
foo: CFLAGS += O2
bar: CFLAGS += -g
在编译foo的时候,使用O2优化,在编译bar的时候,使用-g选项。
模式指定变量:
%.o: CFLAGS += -g
在编译目标.o的时候,都使用-g选项。
Makefile的条件执行:
ifeq...else...endif
ifeq ($(foo), aaa)
echo "haha"
else
echo "hehe"
endif
==============================
ifneq...else...endif
==============================
ifdef ...else...endif
define foo
bar
endef
ifdef foo
echo "haha"
else
echo "hehe"
endef
=======================
ifndef ...else ...endif
=======================
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch test.a
+echo "haha"
else
echo "hehe"
endif
判断MAKEFLAGS是否带参数t,如果存在,则进入第一个分支,+号表示,即使make参数带-t,+号后的命令也会执行。
如果不存在则实行第二个分支。
阅读(2003) | 评论(0) | 转发(0) |