一、变量赋值
- 直接展开式 :=
特点:在定义时立即展开应用的变量
示例:
value1 := 5
value2 := $(value1) #value2会立即被赋值成5
value1 :=6
var-test:
@echo "value2", $(value2)
输出:
make var-test
value2, 5
- 递归展开式 =
特点:定义变量时候其实相当于声明,只有在实际引用时才展开
示例:
value1 = 5
value2 = $(value1) #此处只是声明,不对value2赋值
value1 = 6
var-test:
#此处对value1赋值给value2,此时value1=6
@echo "value2", $(value2)
输出:
make var-test
value2, 6
- 直接展开式 ?=
特点:当变量为空时才赋值
示例:
value1 = 111
value1 ?= 000 #value1的值认为111
- 追加赋值 +=
特点:追加赋值,使用空格分隔
value1 = a.cpp
value1 += b.cpp #value1的值为a.cpp b.cpp
相当于
value1 := $(value1) b.cpp
只是更简洁了,需要注意追加赋值使用的立即展开,即:=,不是递归展开
- 综合示例
示例1:
VAR_A = abc
VAR_B = $(VAR_A) 222
#展开VAR_C的同时,引用了VAR_A,两个变量都被赋值成abc
VAR_C := $(VAR_A)
VAR_A = def
var-test:
@echo "VAR_A", $(VAR_A)
@echo "VAR_B", $(VAR_B)
@echo "VAR_C", $(VAR_C)
输出:
VAR_A, def
VAR_B, def 222
VAR_C, abc
示例2:
VAR_A = abc
VAR_B = $(VAR_A) 222
VAR_C := $(VAR_A) #直接展开VAR_C = abc
VAR_A = def
VAR_A:=$(VAR_B) 222 #直接展开,引用VAR_B,VAR_B展开成def 222
VAR_B=$(VAR_A)
var-test:
@echo "VAR_A", $(VAR_A)
@echo "VAR_B", $(VAR_B)
@echo "VAR_C", $(VAR_C)
输出:
VAR_A, def 222 222
VAR_B, def 222 222
VAR_C, abc
示例3:定义一个空格变量
nullstring :=
space := $(nullstring) #end of the line
dir := /foo/bar # directory to put the frobs in
因为在操作符的右边 是很难描述一个空格的,这里先定义一个空变量nullstring,先用空变量nullstring来标明变量的值开始,而后面用“#”注释符来表示变量定义的终止,这样可以定义出其值是一个空格的变量了。
注释符“#”的这种特性值得我们注意,例子中变量dir的值是“/foo/bar”,后面还跟了4个空格,如果我们使用这样变量来指定别的目录——“$(dir)/file”那么就出错了。
二、变量的高级用法
- 多行变量
使用define关键字可以定义多行变量,语法:
define 变量名
...
....
endef
示例:
define echo_va
echo v
echo a
endef
- 变量替换
语法:
$(var:a=b)
#或者
$(var:%a=%b)
变量var中包括多个字符串,这些字符串被空格或结束符分割,其中以a结尾的字符串,会被改成以b结尾。
示例:
foo = a.o.o b.c.o d.o.e
bar = $(foo:.o=.c)
$(info bar)
far = $(foo:%.o=%.c)
$(info far)
all:
@echo done
执行make all 输出
a.o.o b.c.o d.o.e
a.o.c b.c.c d.o.e
a.o.c b.c.c d.o.e
done
- 在make命令行中设置变量
语法:
make var=value
示例:
a_objects = a.o b.o c.o
1_objects = 1.o 2.o 3.o
#变量a1值决定编译不同脚本
source = $($(a1)_objects:%.o=%.c)
all:
@echo $(source)
执行make a1=1,输出
1.c 2.c 3.c
执行make a1=a,输出
a.c b.c c.c
- 把变量的值再当成变量
示例1:
a = b
b = c
#$(a)是b,这个值还是作为变量使用,所有d的值为c
d = $($(a))
示例2:
first_second = Hello a = first b = second all = $($a_$b) #all的值为“hello”
- 引用环境变量
在make开始运行时会将系统环境变量载入到运行环境中,所以可以在makfile脚本中引用环境变量, 这里定义一个测试用的系统环境变量:
export demoPath=/usr/local/demo
在makefile便可以通过$符号引用:
DEMOPATH = ${demoPath} # 也可以直接应用$(demoPath)
系统环境变量使用全部大写表示,区别普通的变量。如果makfile脚本中定义了该环境变量,系统环境变量将会被覆盖。
- 目标变量
作用:目标变量只在目标编译过程中有效,相当于c语言中局部变量
示例:
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
$(CC) $(CFLAGS) prog.o foo.o bar.o
prog.o : prog.c
$(CC) $(CFLAGS) prog.c
foo.o : foo.c
$(CC) $(CFLAGS) foo.c
bar.o : bar.c
$(CC) $(CFLAGS) bar.c
无论全局$(CFLAGS)是什么值,在prog目标及其引发的目标中都会被变成debug模式。
- 模式变量
作用:模式变量和目标变量类似,只不过目标是一个正则表达式。
示例:
%.o : CFLAGS= -o
二、常见的内置变量
CC = cc #c语言编译器的名称
CPP = $(cc) -E #c文件预处理器的名称
CFLAGS #C文件的编译选项
CPPFLAGS #C文件预处理的编译选项
CXXFLAGS #CPP文件的编译选项
LDFLAGS #连接的动态库
CURDIR := /home/zxy/... #当前路径
MAKEFLAGS = p #make命令选项
RM = rm -f
VPATH #文件的搜索路径
打印环境变量和内置变量方法:
make -p