←手機掃碼閱讀
火星人
@ 2014-03-23 ,
變數的作用方式: 1.變數為一個文本字串; 2.Makefile執行時變數會自動原模原樣地展開在使用地方; 3.變數可以使用在:「目標」,「依賴目標」,「命令」或是 Makefile的其它部分中; 變數命名規則: 1.包含字元、數字,下劃線(可以是數字開頭),字元大小寫敏感; 2.不應該含有「:」、「#」、「=」或是空字元(空 格、回車等); 3.Makefile中存在自動化變數,例如:「$<」、「$@」等; 一、變數的基礎 1.聲明時給予初值; 2.使用時在變數名前加「$」; 注意:最好用小括弧「()」或是大括弧「{}」把變數給包括起來。 3.使用「$」字元時用「$$」來表示。 示例一: foo = c prog.o : prog.$(foo) $(foo)$(foo) -$(foo) prog.$(foo) 展開后: prog.o : prog.c cc -c prog.c 二、變數中的變數 變數定義變數值的兩種方式: 1.變數1 = $(變數2); 注意: 1.變數2可以定義在文件的任何一處; 2.變數2不一定是已定義好的 示例一: foo = $(bar) bar = $(ugh) ugh = Huh? all: echo $(foo) 結果:執行「make all」將會打出變數$(foo)的值是「Huh?」 說明: 1.優點: 變數的真實值推到後面來定義 例如 : CFLAGS = $(include_dirs) -O include_dirs = -Ifoo -Ibar 結果: 展開是CFLAGS = -Ifoo -Ibar -O。 2.缺點: 該種形式能引起遞歸定義 例如: CFLAGS = $(CFLAGS) -O或: A = $(B) B = $(A) 結果:make陷入無限的變數展開過程中;不過make有能力檢測這樣的定義,並會報錯; 3.變數中使用函數時,make運行非常慢,make調用自身的函數「wildcard」和「shell」發生不可預知的錯誤。 這是可以使用第2種定義變數的方式。 2.變數1 := [$(變數2)] 變數值 示例一: x := foo y := $(x) bar x := later 結果: 執行時其等價於: y := foo bar x := later 說明: 1.優點:前面的變數不能使用後面的變數,只能使用前面已定義好了的變數 例如: y := $(x) bar x := foo 結果: y = bar; 示例二:其中包括了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 說明: 1.系統變數「MAKELEVEL」,這個變數會記錄了當前Makefile的調用層數。 示例三:定義一個其值是一個空格的變數 nullstring := space := $(nullstring) # end of the line 說明: 1.nullstring 是一個Empty變數,用一個 Empty變數來標明變數的值開始 2.採用「#」註釋符表示變數定義終止,這樣就定義出其值是一個空格的變數。 示例四: dir := /foo/bar # directory to put the frobs in 說明: 1.dir的值是「/foo/bar」,後面跟了4個空格; 2.$(dir)/file= /foo/bar /file,這樣是錯誤的 3.特殊操作符是「?=」 示例一: FOO ?= bar 說明: 1.如果FOO沒有被定義過,那麼變數FOO的值就是「bar」; 2.如果FOO先前被定義過,那麼這條語將什麼也不做; 3.等價於語句為: ifeq ($(origin FOO), undefined) FOO = bar endif 三、變數高級用法 兩種變數的高級使用方法 1.變數值替換 概述:將變數中的共有部分替換成其他部分 語法:「$(var:a=b)」或「${var:a=b}」 解釋:將變數「var」中所有以「a」字串「結尾」的「a」替換成「b」字串。 說明:「結尾」意思是「空格」或是「結束符」。 示例一: foo := a.o b.o c.o bar := $(foo:.o=.c) 說明: 1.第一行定義一個「$(foo)」變數; 2.第二行把「$(foo)」中所有「.o」字串全部替換成「.c」; 3.最終的結果為:$(bar)=「a.c b.c c.c」; 4.另外一種變數替換的技術「靜態模式」: foo := a.o b.o c.o bar := $(foo:%.o=%.c) 說明:被替換字串有相同模式,上面foo中必須包含一個「%」(任意一個字元)字元,這個例子同樣讓$(bar)變數的值為「a.c b.c c.c」。 2.把變數的值再當成變數 示例一 x = y y = z a := $($(x)) 說明: 1.$(x)的值是「y」; 2.$($(x))就是$(y); 3.$(a)的值就是「z」; 示例二: x = $(y) y = z z = Hello a := 說明: 0.$(a) = $($(x)) 1.$(x) = $(y) 2.$($(x)) = $($(y)) 3.$($(y)) = $(z) 4.$(z) = hello 5.$(a) = hello 示例三: x = variable1 variable2 := Hello y = $(subst 1,2,$(x)) z = y a := $($($(z))) 說明: 1.(subst str1,str2,varb)函數將varb中的str1替換成str2 2.y = variable2 3.a := $($($(z))) 4.$(z) = y 5.a := $($(y)) 6.$(y) = variable2 7.a := $(variable2) 8.a := "Hello" 示例四:用多個變數來組成一個變數的名字,然後再取其值 first_second = Hello a = first b = second all = $($a_$b) 說明: 1.「$a_$b」組成了「first_second」; 2.$(all)的值就是「Hello」。 示例五: a_objects := a.o b.o c.o 1_objects := 1.o 2.o 3.o sources := $($(a1)_objects:.o=.c) 說明: 1.如果$(a1)是「a」,那麼$(sources)為「a.c b.c c.c」; 2.如果$(a1)是「1」,那麼$(sources)為「1.c 2.c 3.c」 示例六:變數替換,函數和條件語句一同使用 ifdef do_sort func := sort else func := strip endif bar := a d b g q c foo := $($(func) $(bar)) 說明: 1.如果定義了"do_sort",那麼foo := $(sort a d b g q c),於是$(foo)的值就是「a b c d g q」; 2.如果沒定義"do_sort",那麼foo := $(strip a d b g q c) 3. 示例六:把"變數的值再當成變數"技術應用在操作符的左邊 dir = foo $(dir)_sources := $(wildcard $(dir)/*.c) define $(dir)_print lpr $($(dir)_sources) endef 說明: 1.該例子定義了三個變數:「dir」,「foo_sources」和「foo_print」。 四、追加變數值 追加變數:使用「+=」操作符 示例一: objects = main.o foo.o bar.o utils.o objects += another.o 說明: 1.$(objects) =「main.o foo.o bar.o utils.o another.o」 2.還可以向下面一樣使用; objects = main.o foo.o bar.o utils.o objects := $(objects) another.o 3."+="相對 ":="更為簡潔; 4.如果變數之前沒有定義過,「+=」會自動變成「=」; 5.如果變數之前有變數定義,「+=」會繼承於前次操作的賦值符。 6.如果前一次的是「:=」, 「+=」會以「:=」作為其賦值符,如: variable := value variable += more 等價於: variable := value variable := $(variable) more 7.如果前一次的是「=」, 「+=」會以「=」作為其賦值符,如: variable = value variable += more 等價於: variable = value variable = $(variable) more (注意) 說明:make會自動解決上面的遞歸定義問題。 五、override 指示符 make可以通過命令行參數設置變數,Makefile中忽略對這個變數的賦值。 如果想在Makefile中設置這類參數值可以使用「override」指示符。 語法: override = override := override += 定義多行變數,使用define指示符; 在define指示符前可以使用ovveride指示符 如: override define foo bar endef 六、多行變數 利用define關鍵字設置變數值可以有換行,這有利於定義一系列的命令(前面講過「命令包」的技術就是利用這個關鍵字)。 說明: 1.define指示符後面是變數名字; 2.重起一行為變數值; 3.定義以endef關鍵字結束; 4.其工作方式和「=」操作符一樣; 5.變數的值可以包含函數、命令、文 字,或是其它變數; 6.define定義的命令變數必須以[Tab]鍵開頭,否則make不會認為其是命令。 示例一: define two-lines echo foo echo $(bar) endef 七、環境變數 說明: 1.同一變數在系統中定義的系統環境變數優先順序低於在Makefile中定義的。 2.make 使用"-e"參數使系統中的變數替換Makefile中相同的變數。 3.make嵌套調用時,上層Makefile中make定義的變數以系統變數方式傳輸到子Makefile中。 4.make嵌套調用時,上層Makefile中定義的變數以使用export將變數傳輸到子Makefile中。 5.注意變數定義在系統環境中,可能會帶來一些麻煩。 八、目標變數 目標變數定義: 作用範圍為某條規則以及連帶規則,其值只在規則以及連帶規則內有效,不會影響規則鏈以外的同名全局變數的變數稱為目標變數。 全局變數定義: Makefile中定義的變數稱為「全局變數」,在作用於整個文件。 自動化變數定義: 變數的值依賴於規則的目標和依賴目標而定義的變數。如「$<」 說明: 1.目標局部變數稱為「Target-specific Variable」,它可以和「全局變數」同名; 2.改變數不會影響到同名的全局變數; 目標變數定義語法格式: : : overide 語法格式說明; 1.可以是前面講過的各種賦值表達式,如「=」、「:=」、「+=」或是「?=」; 2.第二個語法是針對於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 說明: 1.無論全局的$(CFLAGS)值是什麼,在prog目標,以及其所引發的所有規則中(prog.o foo.o bar.o的規則),$(CFLAGS)的值都是「-g」 九、模式變數 模式變數定義:把變數定義在符合這種模式的所有目標上的變數。 模式變數又稱Pattern-specific Variable 示例一:給所有以[.o]結尾的目標定義目標變數: %.o : CFLAGS = -O 說明: 1.make的「模式」一般是至少含有一個「%」。 語法: : : override 說明: override同樣是針對於系統環境傳入的變數,或是make命令行指定的變數。
[火星人
]
linux編程跟我學之Makefile之使用變數 已經有3129 次圍觀
本文地址: http://coctec.com/docs/linux/show-post-108866.html