当前位置:网站首页>GUN make (5) makefile中的变量

GUN make (5) makefile中的变量

2022-06-25 23:57:00 Chen_Hulk

makefile中的变量具有以下特征:

  • makefile中变量和函数的展开是在make读取Makefile文件时进行的。
  • 变量名不包括 : # = 前置空白 尾空白 的任何字符串。
  • 变量名大小写敏感。

 

1.变量的引用

变量引用的展开方式是严格的文本替换过程,与C语言中的宏展开过程相同。


变量的引用方式:

$(VAR)
${VAR}
$X          //仅限于单字符

 

2.两种变量定义

2.1 递归展开方式

这类变量定义是通过 = 或者 define 定义,在定义是不会进行展开,在引用的地方进行展开同时,其所引用的变量一同被替换展开。

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

当执行make all的时候,输出hun?

 

优点:

这种类型变量在定义时,可以引用之前没有定义的变量。

CFLAGS=$(include_dir) -O
include_dir = -lfoo -lbar     //include_dir 定义在引用之后

缺点:

  • 由于存在定义可以在引用之后,所以会导致无限变量展开。
CFLAGS=$(CFLAGS) -O
  • 若用这种风格定义了函数,则包含在变量值中的函数总会在变量被引用的地方执行。

 

2.1 直接展开方式

这种风格变量使用  := 进行定义,在定义时即被展开。

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

等价于:
y:=foo bar
x:=later

缺点:
由于变量定义时即被展开,因此不能实现对其后定义变量的引用。

 

3. 定义一个空格

一般变量前导值中的前导空格字符在 变量引用 和 函数调用 时被丢弃。

使用直接扩展式变量我们可以将一个前导空格定义在变量值中。

nullstr:=
space:=$(nullstr) #end of line

 

但是对于尾部空格是不被忽略的:

dir:=/fool/bar  #end line
变量dir值为 “/foo/bar  ”

 

4. ?= 操作符

该操作符表示 此变量在之前没有赋值的情况下 才会对这个变量进行赋值。

FOO ?= bar

 

5. 变量的替换引用

替换引用是指将值中的后缀字符使用指定的字符进行替换。

方法1:

$(VAR:A=B)  或者 ${VAR:A=B})  表示将:

VAR变量中A字符结尾的字用B字符进行替换。

结尾含义是空格之前。

foo := a.o b.o c.o
bar := $(foo:.o=.c)
替换后bar值为a.c b.c c.c

方法2:

$(patsubst A,B $(VAR)) 其中,A,B需要包含模式字符%

$(patsubst %.o,%.c $(a.o b.o c.o))

 

6. 追加变量值

使用 += 来实现一个变量值的追加操作。

若追加值的变量之前没有定义,则 += 退化为 = 

objects = main.o foo.o
objects += another.o
追加后,objects变为 main.o foo.o another.o

 

直接/递归展开式变量的追加区别:

假设include 变量为空:

递归展开式:
CFLAGS = $(include)
CFLAGS += -pg
则CFLAGS在追加的时候,不立即展开,最终得到 $(include) -pg  


直接展开式:
CFLAGS := $(include)
CFLAGS += -pg
则CFLAGS在追加的时候,立即展开得到一个空,最终得到 -pg  

 

7. override指示符

在执行makefile时,如果通过命令行定义一个变量,则替代在Makefile中出现的同名变量定义。

如果不希望命令行指定的变量值替代在Makefile中的变量定义,那么我们需要在Makefile中使用指示override来对这个变量进行声明。

override VAR = VALUE
override VAR := VALUE
override VAR += VALUE  #变量定义时使用override,则追加时也需要override,否则不会追加有效。

 

8. 目标指定变量

目标指定变量是指 对于相同变量根据不同目标指定不同的值。

目标指定变量只在指定它的目标上下文中有效,对其他目标没有影响,具有局部性。

语法:

TARGET...:VAR-ASSIGN
TARGET...:override VAR-ASSIGN
其中,VAR-ASSIGN可以使用 = += := ?= 赋值方式。

使用:

foo:foo.c
foo:CFLAGS += -O2
bar:bar.c
bar:CFLAGS += -g
其上实现了在编译foo时,使用优化选项-O2,但不使用-g
在编译bar时采用了-g,但是没有-O2

 

9.模式指定变量

使用目标指定变量时,此变量被定义在某个具体目标和由它所引发的规则的目标上去。

模式指定变量定义是将一个变量值指定到所有符合此模式的目标上

PATTERN...:VAR-ASSIGN
PATTERN...:override VAR-ASSIGN
其中PATTERN表示一个或者多个模式目标,包含模式字符%

比如:

为所有.o文件指定变量CFLAGS值:

%.o:CFLAGS += -O

 

原网站

版权声明
本文为[Chen_Hulk]所创,转载请带上原文链接,感谢
https://blog.csdn.net/u010034085/article/details/104664017