makefile :變數
變數在makefile中大量使用,使得makefile更加靈活功能更加強大。同時造成了讀makefile更加難讀。所以我們要發點時間學學變數。
變數基礎
變數分類
變數追加,條件賦值
目標變數
模式變數
自動變數
系統環境變數
變數傳遞
一般在makefile裡面的變數都是存的文字值,這不像c語言 int char 陣列,在makefile都可以看做乙個文字。
變數定義:cc = gcc
變數賦值 :
1,追加賦值 : +=
2,條件賦值: ?=
變數的引用
$(cc)$(cc) 這個非常重要引用變數 $() 或者${} 小括號大括號都可以的。
cc =gcc
後面的命令gcc 都可以用 $(cc) 替換掉了。它有乙個好處就是有時候我們換平台可以更換編譯器就可以了。
目標名也可以是變數如
bin =hello
$(bin): player.0 lcd.o 也可以替代。
同樣目標依賴也可以使用變數替代
bin =hello
objs=player.o lcd.o
$(bin) :$(objs)
$(cc) -o $(bin) $(objs)
就如上面的那樣變成了使用變數的方法。
變數的賦值可以直接等於賦值
str = hello
str2 =hello
str2 +=world!
all:
@echo "str = $(str)"
還有條件賦值,乙個變數沒有賦值就賦值為b test2 沒有賦值test2 被賦值為b。而test1 已經複製了就不再賦值為b了。
test1 =a
test1 ?=b
test 2 ?=b
b變數分類:
:= 立即展開變數 在解析時候賦值常量字串
= 延遲展開變數 在執行階段實際使用時候再求值。
:= 在編譯時候已經替換了類似於c語言的巨集。在改變量是沒有用的。所以使用延遲展開變數就好了。
這裡一定要搞明白,立即展開和延遲展開否者實際專案會出莫名的問題。
注意事項:一般在目標,目標依賴中使用立即展開變數,在命令中一般使用延遲展開變數。
為什麼大家可以想想,主要是解析和執行階段的思考一下。
一般變數:預設都是全域性的.
目標變數:有些變數針對某些目標有效的。有點區域性意思
使用目標變數的作用:可以做到檔案級的編譯選項,比如有些模組編譯為debug模式。
模式變數於目標變數很相似變數的。模式變數可以定義在符合某種模式的目標上。
%.o n=3 //只要符合*.o的規則的統一把n賦值為3. 萬用字元 範圍更廣。
自動變數:也是區域性變數
目標 $@
目標依賴 $^
第乙個依賴 $<
使用舉例:
gcc -o $@ $^
比如:原來是gcc -o $(bin) $(objs) 現在使用 gcc -o $@ $^ 就可以了。
最後說一下系統環境變數:make 在編譯的時候make裡面已經生成了了內建的變數,這些變數供我們使用,這些變數都是全域性。
作用範圍
1,變數在make開始執行時被載入到makefile中
2,對所有的makefile都有效
3,若makefile中定義了同名的變數,系統環境變數將被覆蓋
4,命令列中傳遞同名變數,系統環境變數將被覆蓋
常見的系統環境變數
cflags ://gcc 編譯的時候加一些引數,下面兩個也是常用的環境變數。
shell
make
如下面
.phony:all
all:
@echo "cflags = $(cflags)"
@echo "shell = $(shell)"
@echo "make = $(make)"
@echo "hostname = $(hostname)"
.phony:all 偽目標無條件執行這句話。輸出如下:
cflags =
shell = /bin/sh
make = make
hostname =
看到cflags = 空 hostname 等於空 這些都是預設的系統變數,如果你要修改定義同名的環境變數那麼系統的環境變數就會被替換。
.phony:all
cflags= -g
all:
@echo "cflags = $(cflags)"
@echo "shell = $(shell)"
@echo "make = $(make)"
@echo "hostname = $(hostname)"
執行結果預設就被替換了
cflags = -g
shell = /bin/sh
make = make
hostname =
可以看到系統環境變數被我們替換掉了。命令列也是一樣。
比如輸入 :make make=nmake 輸出如下
cflags = -g
shell = /bin/sh
make = nmake
hostname =
make的值變成了nmake了。
變數的傳遞:
makefile在多目錄下遞迴執行
$(make) -c subdir
cd subdir && $(make)
通過export 傳遞變數
通過命令列傳遞變數
就是實際專案中我們不可能把所有的檔案放在同乙個目錄下面,一般分為不同模組放在不同的資料夾下面,這時候怎麼編譯呢?
make在多個目錄下面進行乙個遞迴的乙個編譯。使用 make -c 編譯那個目錄就進去了 乙個目錄乙個目錄,還會進入下一級目錄。那麼變數還是需要傳遞的
make -c lcd 與 cd test && make n =$(n) //-c 與cd作用一樣,n是變數的傳遞。
就是說變數n只在本檔案有效如果想要在其他檔案有效就得 使用 make n=$(n)
不通過命令還可以通過另外一種方式.exprot n=3 變數宣告為全域性的,你發現其他下面也可以有了這個去全域性變數了。
這就是兩種變數傳遞的方式。強大靈活的。多目錄下編譯會經常碰到
make -c lcd 是遞迴下面的目錄lcd 去變數make執行。
MakeFile從入門到精通 2
程式的編譯與連線 軟體的底層構造系統 1,程式儲存與執行 2,程式編譯和連線 3,程式檔案的分類 4,動態庫與靜態庫 計算機基本都遵循馮諾伊曼結構,cpu 記憶體ram ddr記憶體條 固態硬碟 嵌入式就是flash nor nand 一般手機平板呼叫 pc 伺服器基本都遵循。主要是這三塊組成。一般...
MakeFile從入門到精通 6
庫的生成和使用 庫 其實就是目檔案的乙個歸檔,在前面我記得大致提過了乙個簡單介紹也記錄部落格了,可以返回去看看。目標檔案可以封裝成乙個庫。這裡我就學習如何使用命令把乙個原始檔封裝成乙個庫以及如何去使用。以及如何去編寫乙個makefile去生成庫和使用庫 先學習一下如何使用命令去生成乙個庫 編寫乙個h...
JAVA從入門到精通(4)
一 條件語句之if 語法 if 條件 解釋 需要先判斷條件,條件滿足後才執行後續的 注 如果if條件成立時的執行語句只有一條,是可以省略大括號的 但是執行語句有多條,那就不可以省略了。二 條件語句之if.else 語法 if 條件的布林表示式 else 解釋 條件成立時,則執行if部分的 塊 條件不...