makefile(02)_變量
4.1.變量
Makefile中支持程序設計語言中變量的概率,但沒有變量類型,只代表文本數據;
變量命名規則:變量可以包含字符、數字、下劃線,單不能包含”:”,”#”, “=”,” ”,變量名大小寫敏感。
變量的定義和使用:
4.2.賦值
Makefile中有4中變量賦值方式:
4.2.1.簡單賦值(:=)
程序設計語言中的通用賦值方式,只針對當前語句有效,等價於C語言中的賦值。建議無特殊要求時使用簡單賦值。
x := foo
y := $(x)b
x := new
test :
@echo "x => $(x)"
@echo "y => $(y)"
輸出結果:
4.2.2.遞歸賦值(=)
賦值操作可能影響多個其它變量,所有與目標變量相關的其他變量都會受到影響。
x = foo
y = $(x)b
x = new
test :
@echo "x => $(x)"
@echo "y => $(y)"
輸出結果:
註意:如果不是必要請盡可能不要使用遞歸賦值,這裏的賦值號完全不等價與C語言中的賦值號。
4.2.3.條件賦值(?=)
如果變量未定義,使用賦值符號中的值定義變量,如果已經定義,賦值無效。
x := foo y := $(x)b x ?= new test : @echo "x => $(x)" @echo "y => $(y)"
輸出結果:
4.2.4.追加賦值(+=)
原變量值後加一個新值,原變量與新值之間由空格隔開
x := foo
y := $(x)b
x += new
test :
@echo "x => $(x)"
@echo "y => $(y)"
輸出結果:
5.預定義變量的使用
在Makefile中存在一些預定義的變量,主要分為兩類:自動變量和特殊變量。
5.1.自動變量
$@ 當前規則中觸發命令被執行的目標
$^ 當前規則中的所有依賴
$< 當前規則中的第一個依賴
自動變量的使用:
.PHONY : all first second third all : first second third @echo "\$$@ => $@" @echo "$$^ => $^" @echo "$$< => $<" firtst: second: third:
輸出結果:
註意:
1.“$”符號在Makefile中有特殊含義,當打印其字面量時需要加上$進行轉義
2.“$@”則需要加上\$進行轉義
5.2.特殊變量
$(MAKE) 當前make解釋器的文件名
$(MAKECMDGOALS) 命令行中指定的目標名,(make的命令行參數)
$(MAKEFILE_LIST) make需要要處理的makefile文件列表,註意當前Makefile的文件名總是位於列表最後,文件名之間使用空格分隔。
$(MAKE_VERSION) 當前make解釋器的版本
$(CURDIR) 當前make解釋器的工作目標
$(.VARIABLES) 所有已經定義的變量名和列表(預定義變量和自定義變量)
$(RM) rm -f
通常我們會打印$(.VARIABLES) 查看當前操作系統所支持的自定變量,然後對照make 手冊(可從官網下載:http://www.gnu.org/software/make/manual/make.html),查看每個變量的意義。
.PHONY : all out first second third test
all out :
@echo "$(MAKE)"
@echo "$(MAKECMDGOALS)"
@echo "$(MAKEFILE_LIST)"
first :
@echo "first"
second :
@echo "second"
third :
@echo "third"
test :
@$(MAKE) first
@$(MAKE) second
@$(MAKE) third
輸出結果:
6.變量的高級主題-上
6.1.變量值的替換
6.1.1.後綴替換
使用指定字符串替換變量中的後綴:
語法規則: $(var:cc=o)或 ${src1:cc=o}
替換表達式中不能有任何的空格,make中支持使用${}對變量進行取值
src1 := a.cc b.cc c.cc
obj1 := $(src1:cc=o)
test1 :
@echo "obj1 => $(obj1)"
輸出結果:
6.1.2.模式替換
變量的模式替換,使用%保留變量值中的指定字符,替換其他字符
語法格式:$(var:a%b=x%y)或 ${src1:a%b=x%y}
src2 := a11b.c a22b.c a33b.c
obj2 := $(src2:a%b.c=x%y)
test2 :
@echo "obj2 => $(obj2)"
輸出結果:
6.1.3.規則中的模式替換
意義:
通過target-patten從targets中匹配子目標;再通過prereq-patten從子目標生成依賴;進而構成完成的規則。
src1 := a.cc b.cc c.cc
obj1 := $(src1:cc=o)
test1 :
@echo "obj1 => $(obj1)"
src2 := a11b.c a22b.c a33b.c
obj2 := $(src2:a%b.c=x%y)
test2 :
@echo "obj2 => $(obj2)"
輸出結果:
6.2.變量的嵌套引用
一個變量名之中可以包含對其他變量的引用,本質上是使用一個變量表示另一個變量。
6.3.命令行變量
運行make時,可以在命令行中定義變量,命令行變量默認覆蓋Makefile中定義的變量。
6.4.override關鍵字
用於指示Makefile中定義的變量不能被覆蓋,變量的定義和賦值都需要使用override關鍵字
6.5.define關鍵字
用於定義Makefile中的多行變量,多行變量的定義從變量名開始到endef結束,可以使用override關鍵字防止變量被覆蓋,define定義的變量等價於使用=定義的變量。
hm := hello makefile
override var := override-test
define foo
I‘m fool!
endef
override define cmd
@echo "run cmd ls ..."
@ls
endef
test :
@echo "hm => $(hm)"
@echo "var => $(var)"
@echo "foo => $(foo)"
${cmd}
直接運行makefile的結果:
命令行傳參的結果:
make makefile foo="i am cmd foomake -f makefile.3" var="cmd line var"
顯然我們改變了foo變量的值,因為foo變量沒有被override修飾,但不能改變var變量的值。
7.變量的高級主題-下
7.1.環境變量
Makefile中能夠使用環境變量的值,如果定義的普通變量和環境變量同名,環境變量將被覆蓋,運行make時指定-e選項,優先使用環境變量
優勢:環境變量可以在所有文件中使用;
劣勢:過多的環境變量會導致移植性降低
變量在不同Makefile之間傳遞的方式:
1.直接在外部定義環境變量進行傳遞
2.使用export定義變量進行傳遞(定義臨時環境變量)
3.使用make命令行變量進行傳遞(推薦)
PATH := path
export var := D.T.Software
new := TDelphi
test :
@echo "PATH => $(PATH)"
@echo "make another file ..."
@$(MAKE) -f makefile.2
@$(MAKE) -f makefile.2 new:=$(new)
makefile.2的內容:
test:
@echo "PATH => $(PATH)" #1.直接在外部定義環境變量進行傳遞
@echo "var => $(var)" #2.使用export定義變量進行傳遞(定義臨時環境變量)
@echo "new => $(new)" #3.使用make命令行變量進行傳遞(推薦)
輸出結果:
7.2.目標變量(局部變量)
作用域只在指定目標及連帶規則中。
target : name <assignment> value
target : voerride name <assignment > value
7.3.模式變量(局部變量)
模式變量是目標變量的擴展,作用域只在符合的目標及連帶規則中。
pattrn : name <assignment > value
pattrn : voerride name <assignment > value
var := D.T.Software
new := TDelphi
test : var := test-var # 目標變量
%e : override new := test-new # 模式變量
test : another
@echo "test :"
@echo "var => $(var)"
@echo "new => $(new)"
another :
@echo "another :"
@echo "var => $(var)"
@echo "new => $(new)"
rule :
@echo "rule :"
@echo "var => $(var)"
@echo "new => $(new)"
直接運行結果:
make rule運行結果:
makefile(02)_變量