Makefile文件(五)_使用变量

参考原文http://blog.csdn.net/liang13664759/article/details/1771246/shell

Makefile中变量如C\C++中宏同样执行时候自动原模原样展开在使用的地方,与C/C++不一样得失,Makefile中能够改变其值。Makefile中变量可使用在“目标”,“依赖目标”,“命令”或其余部分。ide

变量名能够包含字符数字下划线(能够数字开头),可是不该该含有“:”、“#”、“=”或是空字符,区分大小写。函数

1、变量的基础

声明时须要给予初始值,使用时加上“$”符号,最好用“()”或者“{}”把变量包括起来。而使用真是的“$”须要“$$”表示。spa

变量能够用在许多地方,如规则中的目标、依赖、命令以及新的变量。.net

2、变量中的变量

①使用“=”,左侧是变量,右侧是变量的值,右侧变量的值能够定义在文件的任何一处,也就是说右侧变量不必定是一已定义好的值,也可使用后面定义的值。命令行

例如:blog

foo = $(bar)递归

bar = $(ugh)ip

ugh = huh?ci

all:

  echo $(foo)

执行make all会打印出变量$(foo)的值“Huh?”。因此,变量是能够用后面的变量来定义的。

注:这样可能会产生递归定义:

A= $(B)

B=$(A)

这会让make陷入无限的变量展开过程当中去,固然,make有检测这样的能力,并会报错。

若是变量中使用函数,这也会让make运行时很是慢。他会使用make的“wildcard”和“shell”发生不可预知的错误。

②“:=”,前面的变量不能使用后面的变量,只能使用已定义好的变量。

x:=foo

y:=$(x) bar

x:=later

等价于

y := foo bar

x := later

 

y := $(x) bar

x := foo

那么y的值是“bar”,而不是“foo, bar”

系统变量“MAKELEVEL”表示,若是make有一个嵌套执行的动做,则该变量会记录当前的Makefile调用层数.

(如下的我也还没懂,先标记)

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

nullstring是一个Empty变量,其中什么也没有,而咱们的space的值是一个空格。由于在操做符的右边是很难描述一个空格的,这里采用的技术很管用,先用一个Empty变量来标明变量的值开始了,然后面采用“#”注释符来表示变量定义的终止,这样,咱们能够定义出其值是一个空格的变量。请注意这里关于“#”的使用,注释符“#”的这种特性值得咱们注意,若是咱们这样定义一个变量:

dir := /foo/bar # directory to put the frobs in

dir这个变量的值是“/foo/bar”,后面还跟了4个空格,若是咱们这样使用这样变量来指定别的目录——“$(dir)/file”那么就完蛋了。

③、另外的赋值法,“?=”表示若是没有被定义过,则赋值。若是定义过,则什么也不作。

FOO ?= bar

等价于:

ifeq ($(origin FOO), undefined)

FOO = bar

endif

3、变量高级用法

①变量值的替换

替换变量中的共有部分,格式“$(var:a=b)”或是“${var:a=b}”,表示吧变量var中的全部以“a”结尾的“a”替换成“b”

例如:

foo := a.o b.o c.o

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

把“$(foo)”中的全部“.o”结尾所有替换为“.c”,因此“$(bar)”的值就是“a.c b.c c.c”。

另一种前面记录过得静态模式,

foo := a.o b.o c.o

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

②、“把变量的值在当成变量”

x = y

y = z

a:=$($(x))

例子中,$(x)=y, 因此$($(x))就是$(y),因而$(a)的值就是z

“函数”于“条件语句”一同使用的例子:

ifdef do_set

  func := sort

else

  func := strip

endif

bar := a b d g q c

foo := $($(func) $(bar))

示例中若是定义了"do_sort",foo:=$(sort a d b g q c),因而$(foo)就是“a b c d g q”。若是没有定义“do_sort”,则foo:=$(strip a d b g q c),调用strip函数。

“把变量的值当成变量”一样能够用在操做符的左边:

dir = foo

$(dir)_sources := $(wildcard $(dir)/*.c)

define $(die)_print

  lpr $($(dir)_sources)#该命令表示把文件发送给打印机

endef

4、追加变量

使用“+=”给变量追加值,如:

objects = main.o foo.o bar.o utils.o

objects += another.o

因而,$(objects)值就变成:“main.o foo.o bar.o utils.o another.o"

等价于:

objects = main.p foo.o bar.o utils.o 

objects := $(objects) another.o

但“+=”更为简洁,且若是前面没有定义过该变量。“+=”自动变成“=”,若是 有定义过,“+=”聚集成前次操做的赋值符。若是前一次的是“:=”,那么“+=”会以“:=”为其赋值符,如:

variable := value

variable += more

等价于:

variable := value

variable := $(variable) more

可是“=”状况却不同,例如:

variable = value

variable += more

因为前次的赋值符是“=”,因此“+=”也会以“=”做为赋值,那么岂不会发生变量的递补归定义,这是很很差的,因此make会自动为咱们解决这个问题,咱们没必要担忧这个问题。(没懂)

5、override指示符

若是有变量是一般的make命令行参数设置,那么Makefile中对这个变量的赋值会被忽略。若是想在Makefile中设置这类参数的值,可以使用“override”指示符。

override <variable>=<value>

override <variable>:=<value>

还能够追加

override <variable>+=<more text>

对于多行的变量定义,可使用define指示符,而define指示符前,也一样可使用override,如:

override define foo

bar

endef

定义变量foo bar

6、多行变量

使用define关键字设置变量的值能够有换行,有利于一系列的命令。(命令包就是利用该关键字)

define指示符后面跟变量的名字,重起一行定义变量的值,定义以关键字endef结束。工做方式和“=”操做符同样。变量的值能够包含函数、命令、文字或是其余变量。define定义的命令变量中一样要以【Tab】键开头

define two-lines

  echo foo

  echo $(bar)

endef

7、环境变量

make运行时的系统环境变量能够在make开始运行时被载入到Makefile文件中,可是若是Makefile中定义了这个变量,或是这个变量由make命令行带入,那么系统的环境变量的值将被覆盖(若是make指定了“-e”参数,那么系统环境变量将覆盖Makefile中定义的变量,-e, --environment-overrides环境变量覆盖Makefile文件)

所以,若是咱们在环境变量中设置了“CFLAGS”环境变量,那么咱们就能够在全部的Makefile中使用这个变量。这对于使用统一的编译参数很方便。若是Makefile中定义了CFLAGS,那么会使用Makefile中的这个变量,若是没有定义则使用系统的环境变量。

当make嵌套调用时,上层Makefile中定义的变量会以系统环境变量的方式传递到下层的Makefile中。默认状况下,只有经过命令行设置的变量会被传递。定义在文件中的变量传递须要export。

不推荐许多的变量定义在系统环境中,这样执行不用的Makefile拥有同一套系统变量,可能会有麻烦。

8、目标变量

前面所述的Makefile中定义的变量都是“全局变量”,整个文件中均可以访问这些变量。固然“自动化变量”除外("$<"、“$@”、“$^”)属于“规则型变量”,这种变量的值依赖于规则的目标和依赖目标的定义。

 固然,也能够为某个目标设置局部变量,成为“Target-specific Variable”,它能够和“全局变量”同名,由于他的做用范围只在这条规则以及连带规则中,其值也只在做用范围内有效,不会影响规则链之外的全局变量的值。以下:

<target...>:<variable-assignment>

<target...>:overide<vatiable-assignment>

<vatiable-assignment>能够是前面的各类赋值表达式。“=”、“:=”、“+=”、“?=”。第二条是make命令行带入的变量或是系统环境变量。

示例:

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以及所引起的全部规则中(prog.o foo.o bar.o),$(CFLAGS)的值都是“-g”

9、模式变量

在GNU的make中,还支持模式变量(Pattern-speific Variable),经过前面,变量能够定义在某个目标上,模式变量的好处就是能够给定一种“模式”,能够把变量定义在符合这种模式的全部目标上。

示例:%.o:CFLAGS=-o

<pattern...>:<variable-assignment>

<pattern...>:override<variable-assignment>

make命令行指定变量override针对系统环境传入变量。

相关文章
相关标签/搜索