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針對系統環境傳入變量。

相關文章
相關標籤/搜索