Makefile的变量(五)

变量的基础

变量在声明时需要给初始值,在使用的时候要使用$(name)的方式,这里可以使小括号()也可以是{}。如果我们要使用真实的$,那么需要使用$$表示。

objects = program.o foo.o utils.o
program : $(objects)
        gcc -o $(objects)
$(objects):defs.h

变量会在使用它的地方,精确的展开,例如

foo = c
prog.o:prog.$(foo)
        g$(foo)$(foo) -$(foo) prog.$(foo)

展开后得到:

prog.o:prog.c
        gcc -c prog.c

变量中的变量

在定义变量的值是,我们可以使用其他变量来构造变量的值,在Makefile中有两种方式来用变量定义变量的值。
第一种:使用=号,如

foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
        echo $(foo)

当我们执行make all时将会打出变量$foo的值是Huh?,因此,变量是可以通过后面的变量来定义的
优点:我么可以变量的真实值推到后面去定义

CFLAGS = $(include_dirs) -o
include_dirs = -lfoo -lbar

缺点:如果出现递归定义,则报错

第二种:使用:=的操作符

x := foo
y := $(x) bar
x := later
#等价于
y := foo bar
x := later

这里我们前面的变量不能使用后面的变量,只能使用前面已经定义好的变量

y := $(x) bar
x := foo

那么y的值是bar,而不是foo bar.因为这里我们的x还没有定义
这个例子可能比较简单,来看一个比较难的
这里包括了make的函数,条件表达式和一个系统变量MAKELEVEL的使用

ifeq (0,${MAKELEVEL})
cur-dir := $(shell pwd)
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif

关于MAKELEVEL的意思是如果我们的make有一个嵌套执行的动作,那么这个变量会记录了我们当前的Makefile的调用层数
这是关于定义空格变量的例子

nullstring :=
space := $(nullstring) # ending of the line

nullstring 是一个Empty变量,其中什么也没有,而我们的space的值是一个空格,因为在操作符的邮编是很难描述一个空格,这里采用的技术很管用,先用一个Empty变量来表明变量值的开始,而后面采用#注释符来表示变量定义的终止,这样,我们可以定义出值是一个空格变量

变量的高级用法

变量值的替换

这里我们可以替换变量中,共有的部分,其格式是$(var:a=b)或者${var:a=b},意思是,把变量var中所有的a字符串结尾的a替换成b字符串,这里结尾的意思是空格或者结束符

foo:=a.o b.o
bar := $(foo:.o=.c)

这里的意思是将a.ob.o文件改成a.cb.c文件
静态模式

foo := a.o b.o c.o
bar := $(bar:%.o=%.c)

这里依赖于被替换的字符串有相同的模式,模式中必须包含一个%字符,同样是将所有的.o文件转换成.c文件

把变量的值在当做变量

x = y
y = z
a := $($(x))

所以a变量的值是z
使用函数

x := variable1
variable2 := hello
y = $(subst 1,2,$(x))
z := y
a := $($($(z)))

其中subst函数的意思是将$(x)中的1替换成2,所以最终的结果是hello
同样我们可以采用拼接的方式实现较长标量名称

first_second = hello
a := fist
b := second
x := $($a_$b)

将两种方式组合在一起,内容就比较丰富了

a_object := a.o b.o c.o
b_object := 1.o 2.o 3.o
a1 :=a
source := $($(a1)_object:.o=.c)

这里a1的值是a,所以,最终的结果是将a.o,b.o,c.o文件变成a.c,b.c,c.c文件
和函数结合

ifdef do_sort
func := sort
else
func := strip
endif
bar : a d b g q c
foo := $($(func) $(bar))

这里如果定义了do_sort函数,那么使用sort函数,将bar从新排序
这里需要注意,把变量的值在当做变量,同样可以在操作符的左边

dir := foo
$(dir)_sources := $(wildcard $(dir)/*.c)
define $(dir)_print
lpr $($(dir)_sources)
endef

这例子中定义了三个变量:dir,foo_source,foo_print

追加变量值

我们使用+=来追加

objects := main.o foo.o bar.o util.o
objects += another.o
#等价于
objects := main.o foo.o bar.o util.o
objects := $(objects) another.o

override指示符

如果变量是通过make的命令行参数设置的,那么Makefile中对这个变量的赋值将会被忽略。如果想要设置这个参数的值,需要使用override指示符

override define foo
bar
endef

猜你喜欢

转载自blog.csdn.net/weixin_42580207/article/details/81266002
今日推荐