1. 程式人生 > >makefile(02)_變量

makefile(02)_變量

makefile 自動變量 模式替換

4.變量與賦值

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)_變量