【三】makefile中的變數
阿新 • • 發佈:2018-11-10
一、變數賦值
- 直接展開式 :=
特點:在定義時立即展開應用的變數
示例:
value1 := 5
value2 := $(value1) #value2會立即被賦值成5
value1 :=6
var-test:
@echo "value2", $(value2)
輸出:
make var-test
value2, 5
- 遞迴展開式 =
特點:定義變數時候其實相當於宣告,只有在實際引用時才展開
示例:
value1 = 5 value2 = $(value1) #此處只是宣告,不對value2賦值 value1 = 6 var-test: #此處對value1賦值給value2,此時value1=6 @echo "value2", $(value2)
輸出:
make var-test
value2, 6
- 直接展開式 ?=
特點:當變數為空時才賦值
示例:
value1 = 111
value1 ?= 000 #value1的值認為111
- 追加賦值 +=
特點:追加賦值,使用空格分隔
value1 = a.cpp
value1 += b.cpp #value1的值為a.cpp b.cpp
相當於
value1 := $(value1) b.cpp
只是更簡潔了,需要注意追加賦值使用的立即展開,即:=,不是遞迴展開
- 綜合示例
示例1:
VAR_A = abc VAR_B = $(VAR_A) 222 #展開VAR_C的同時,引用了VAR_A,兩個變數都被賦值成abc VAR_C := $(VAR_A) VAR_A = def var-test: @echo "VAR_A", $(VAR_A) @echo "VAR_B", $(VAR_B) @echo "VAR_C", $(VAR_C)
輸出:
VAR_A, def
VAR_B, def 222
VAR_C, abc
示例2:
VAR_A = abc
VAR_B = $(VAR_A) 222
VAR_C := $(VAR_A) #直接展開VAR_C = abc
VAR_A = def
VAR_A:=$(VAR_B) 222 #直接展開,引用VAR_B,VAR_B展開成def 222
VAR_B=$(VAR_A)
var-test:
@echo "VAR_A", $(VAR_A)
@echo "VAR_B", $(VAR_B)
@echo "VAR_C", $(VAR_C)
輸出:
VAR_A, def 222 222
VAR_B, def 222 222
VAR_C, abc
示例3:定義一個空格變數
nullstring :=
space := $(nullstring) #end of the line
dir := /foo/bar # directory to put the frobs in
因為在操作符的右邊 是很難描述一個空格的,這裡先定義一個空變數nullstring,先用空變數nullstring來標明變數的值開始,而後面用“#”註釋符來表示變數定義的終止,這樣可以定義出其值是一個空格的變量了。
註釋符“#”的這種特性值得我們注意,例子中變數dir的值是“/foo/bar”,後面還跟了4個空格,如果我們使用這樣變數來指定別的目錄——“$(dir)/file”那麼就出錯了。
二、變數的高階用法
- 多行變數
使用define關鍵字可以定義多行變數,語法:
define 變數名
...
....
endef
示例:
define echo_va
echo v
echo a
endef
- 變數替換
語法:
$(var:a=b)
#或者
$(var:%a=%b)
變數var中包括多個字串,這些字串被空格或結束符分割,其中以a結尾的字串,會被改成以b結尾。
示例:
foo = a.o.o b.c.o d.o.e
bar = $(foo:.o=.c)
$(info bar)
far = $(foo:%.o=%.c)
$(info far)
all:
@echo done
執行make all 輸出
a.o.o b.c.o d.o.e
a.o.c b.c.c d.o.e
a.o.c b.c.c d.o.e
done
- 在make命令列中設定變數
語法:
make var=value
示例:
a_objects = a.o b.o c.o
1_objects = 1.o 2.o 3.o
#變數a1值決定編譯不同指令碼
source = $($(a1)_objects:%.o=%.c)
all:
@echo $(source)
執行make a1=1,輸出
1.c 2.c 3.c
執行make a1=a,輸出
a.c b.c c.c
- 把變數的值再當成變數
示例1:
a = b
b = c
#$(a)是b,這個值還是作為變數使用,所有d的值為c
d = $($(a))
示例2:
first_second = Hello a = first b = second all = $($a_$b) #all的值為“hello”
- 引用環境變數
在make開始執行時會將系統環境變數載入到執行環境中,所以可以在makfile指令碼中引用環境變數, 這裡定義一個測試用的系統環境變數:
export demoPath=/usr/local/demo
在makefile便可以通過$符號引用:
DEMOPATH = ${demoPath} # 也可以直接應用$(demoPath)
系統環境變數使用全部大寫表示,區別普通的變數。如果makfile指令碼中定義了該環境變數,系統環境變數將會被覆蓋。
- 目標變數
作用:目標變數只在目標編譯過程中有效,相當於c語言中區域性變數
示例:
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目標及其引發的目標中都會被變成debug模式。
- 模式變數
作用:模式變數和目標變數類似,只不過目標是一個正則表示式。
示例:
%.o : CFLAGS= -o
二、常見的內建變數
CC = cc #c語言編譯器的名稱
CPP = $(cc) -E #c檔案前處理器的名稱
CFLAGS #C檔案的編譯選項
CPPFLAGS #C檔案預處理的編譯選項
CXXFLAGS #CPP檔案的編譯選項
LDFLAGS #連線的動態庫
CURDIR := /home/zxy/... #當前路徑
MAKEFLAGS = p #make命令選項
RM = rm -f
VPATH #檔案的搜尋路徑
列印環境變數和內建變數方法:
make -p