makefile变量
在声明变量时需要初始化。通过在变量名前加上 $ 符号引用变量,最好用上小括号 () 或
大括号 {} 把变量括起来。变量是大小写敏感的。
如果需要用 $ 字符,那么需要用 $$ 来表示。 变量可以使用在规则中的“目标”、“依赖”、“命令”中及新的变量中。如:
CC = gcc
OBJS = program.o foo.o utils.o
program : $(OBJS)
$(CC) -o program $(OBJS)
$(OBJS) : defs.h
- 1
- 2
- 3
- 4
- 5
注:强烈建议在引用变量时,加下小括号或大括号,这样可以更安全地引用变量。
变量会在引用它的地方展开,如:
foo = c
prog.o : prog.$(foo)
$(foo)$(foo) -$(foo) prog.$(foo)
- 1
- 2
- 3
展开后得到:
prog.o : prog.c
cc -c prog.c
- 1
- 2
上面这个例子的用法,在实际生产,强烈不建议这么使用。
在 Makefile 中有两种方式来在用变量定义变量的值:
- 使用 = 号,右侧变量的值可以定义在文件的任何一处,即不需要定义在引用变量处之前,执行make时,会在引用的地方展开。
CC = gcc
- 1
- 使用 := 号
CC := gcc
- 1
第一种=号方式,因为引用它时,不用先定义(即可先引用后定义,或者反过来),这将导致递归定义,如:
CFLAGS = $(include_dirs) -o
include_dirs = -Ifoo -Ibar
CFLAGS = $(CFLAGS) -o
- 1
- 2
- 3
CFLAGS = $(CFLAGS) -o在命令中被展开时会形成递归定义,这会让 make 陷入无限的变量展开过程中去。虽然,make有能力检测出这样的定义,并会报错。如果在变量中使用函数的话,这种递归让make 运行得非常慢,甚至可能发生不可预知的错误。
使用:= 操作符可以解决这个问题。而且使用这个操作符的话,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。
如:
x := foo
y := $(x) bar
x := later
- 1
- 2
- 3
等价于:
y := foo bar
x := later
- 1
- 2
特别强调,如果是这样:
y := $(x) bar
x := foo
- 1
- 2
那么,y 的值是“bar”,而不是“foo bar”。
?=操作符
FOO ?= bar
- 1
含义:如果 FOO 没有被定义过,那么将“bar”赋给它。如果 FOO 先前被定义过,那么这条语将什么也不做。上面这条语句等价于:
ifeq ($(origin FOO), undefined)
FOO = bar
endif
- 1
- 2
- 3
变量高级用法
- 第一种是变量值的替换
可以替换变量中的公共部分,格式:$(var:a=b) 或 ${var:a=b} ,表示把变量“var”中所有以“a”结尾的“a”替换成“b”,如:
foo := a.o b.o c.o
bar := $(foo:.o=.c)
- 1
- 2
这个例子中,定义了变量foo。$(foo:.o=.c)就是把 $(foo) 中所有以 .o结
尾的.o全部替换成 .c ,所以$(bar) 的值是“a.c b.c c.c”。
另外一种变量替换的技术是以“静态模式”定义的,如:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c)
- 1
- 2
这依赖于被替换字符串中的有相同的模式,%是一个通配符,而且静态模式中必须包含一个 % 字符,这个例子同样让 $(bar) 变量的值变为“a.c b.c c.c”。
- 第二种是“把变量的值再当成变量”
x = y
y = z
a := $($(x))
- 1
- 2
- 3
在这个例子中,$(x) 的值是“y”,所以 $($(x)) 就是 $(y),于是 $(a) 的值就是“z”。还可以使用更多的层次,如:
x = y
y = z
z = u
a := $($($(x)))
- 1
- 2
- 3
- 4
这里的 $(a) 的值是“u”。
+= 操作符给变量追加值
如:
objects = main.o foo.o bar.o utils.o
objects += another.o
- 1
- 2
$(objects) 值变成:“main.o foo.o bar.o utils.o another.o”
使用 += 操作符也可以写成下面的样子:
objects = main.o foo.o bar.o utils.o
objects := $(objects) another.o
- 1
- 2
如果变量之前没有定义过,那么,+= 会自动变成 = ,如果前面有变量定义,那么 += 会继承于前
次操作的赋值符。如果前一次的是 := ,那么 += 会以 := 作为其赋值符,如:
variable := value
variable += more
- 1
- 2
等价于:
variable := value
variable := $(variable) more
- 1
- 2
但如果是:
variable = value
variable += more
- 1
- 2
由于前次的赋值符是 = ,所以 += 也会以 = 来做为赋值,那么就会发生变量的递归定义,很不好,幸好 make 会自动解决这个问题。
多行变量
使用 define 关键字设置变量值的方法。使用 define 关键字设置变量的值可以有换行,有利于定义一系列的命令。define 指示符后面跟的是变量的名字,然后重起一行定义变量的值,定义是以 endef 关键字结束。其工作方式和“=”操作符一样。变量的值可以包含函数、命令、文字,或是其它变量。因为命令需要以[Tab] 键开头,所以如果你用 define 定义的命令变量中没有以 Tab 键开头,那么 make 就不会把其认为是命令。
下面的这个示例展示了 define 的用法:
define two-lines
echo foo
echo $(bar)
endef
- 1
- 2
- 3
- 4
谢谢阅读
文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/weixin_40763897/article/details/103241807
- 点赞
- 收藏
- 关注作者
评论(0)