在前面的文章徹底掌握Makefile(一)和徹底掌握Makefile(二)當中,我們簡要的介紹了一些常見的makefile使用方法,在本篇文章當中我們將繼續介紹一些makefile當中的常見用法。
file = ./files/a.c
fdir = $(dir $(file))
nfdir = $(notdir $(file))
main: demo.c
echo $(fdir)
echo $(nfdir)
dir函數主要書獲取檔案路徑當中的目錄部分,而notdir函數主要是獲取檔案路徑當中檔名的部分,執行上面的makefile結果如下所示:
這個函數主要是用於獲取檔案的字尾名。
file = ./files/a.c
fdir = $(dir $(file))
nfdir = $(notdir $(file))
name = $(suffix $(file))
main: demo.c
echo $(fdir)
echo $(nfdir)
echo $(name)
上面的makefile執行結果如下下圖 所示:
這個函數用於獲取檔案路徑當中除去字尾名的部分。
file = ./files/a.c
base = $(basename $(file))
main: demo.c
echo $(base)
這個函數主要是給檔案加上字尾的。
file = ./files/a.c
base = $(addsuffix .c, $(file))
main: demo.c
echo $(base)
上面的程式碼執行結果如下:
上面的結果就表示在檔案的末尾加上了對應的字尾名。
這個函數的主要作用就是在字串的前面加上一串字元。
file = files/a.c
base = $(addprefix ./src/main/, $(file))
main: demo.c
echo $(base)
上面的makefile執行結果如下圖所示:
foreach
函數的主要使用規則為:
$(foreach <var>,<list>,<text>)
我們直接使用一個例子來說明這個情況:
files = a.c b.c c.c d.c
new_files = $(foreach n, $(files), $(n)pp)
main: demo.c
echo $(new_files)
上面的makefile輸出結果如下圖所示:
foreach
函數會將files當中的字串先按照空格、tab鍵、回車換行符進行分割,然後將分割後的值一個一個的放入變數n
當中,然後會產生一個字串$(n)pp,最終將這些字串通過空格拼接起來並且賦值給new_files,這才會有最終的結果。
上面的過程對應一個python程式碼如下所示:
call函數在makefile當中可以用於呼叫我們自定義的一個表示式,他的語法個數如下面所示:
$(call <expression>,<parm1>,<parm2>,...,<parmn>)
$(n)
進行參照。我們現在有一個需求就是將兩個字元中間加上多個橫槓,比如下面的makefile。
a=a.c
b=b.c
c=$(a)-------$(b)
main: demo.c
echo $(c)
上面的makefile執行結果如下圖所示:
但是如果我們想要重複實現這個功能的話,我們就不需要每次都去寫這樣一個表示式,而是我們應該寫一個表示式然後進行呼叫。
a=a.c
b=b.c
c=$(1)-------$(2) # 定義表示式c $(1) 表示使用第一個引數 $(2) 表示使用第二個引數
main: demo.c
echo $(call c, $(a), $(b)) # c 就是定義好的表示式 這裡呼叫表示式c
上面的makefile輸出結果和上面一樣:
我們在makefile的表示式當中可以使用shell的函數。
比如現在我們有一個檔案叫做test.txt
,檔案的內容如下所示:
a.c b.c c.c d.c
我們的makefile內容如下:
content=$(shell cat test.txt) # 將shell命令的輸出內容賦給content
main: demo.c
echo $(content) # 輸出content
上面的makefile執行結果如下圖所示:
origin這個函數主要是返回變數的定義方式,使用格式如下:
$(origin <variable>) # 其中 variable 是變數名字 這裡不需要使用 $ 符號去參照
這個函數的輸出結果又下面這些值:
如果 <variable>
從來沒有定義過,origin函數返回這個值 undefined
如果 <variable>
是一個預設的定義,比如「CC」這個變數。
GNU make預設變數:
variable是一個環境變數。
如果 <variable>
這個變數被定義在Makefile中。
如果 <variable>
這個變數是被命令列定義的。
如果 <variable>
是被override指示符重新定義的,關於override的使用,請檢視本文彩蛋部分。
現在我們舉一個例子,去看看上面這些值對應的例子:
override var = aaaa
file=file
main: demo.c
echo $(origin file) # makefile 內部定義的
echo $(origin data) # 命令列定義的
@echo $(origin var) # override 重寫
@echo $(origin JAVA_HOME) # JAVA_HOME 是一個環境變數
@echo $(origin CXX) # 預設定義的變數
我們現在使用make命令測試一下上面的makefile輸出結果:
在makefile當中我們可以使用error函數讓makefie停止執行。當我們有需求:讓在某種條件下讓makefile停止編譯
data=data
ifeq ($(data), data)
$(error "data == data")
endif
main: main.c
gcc main.c
現在我們執行makefile,輸出結果如下:
還有一個函數warning
使用方法和上面一樣用於產生警告。
有時候在makefile當中我們不想輸出某些命令(如果不進行設定makefile會輸出每一條我們執行過的命令),比如下面的makefile。
main: demo.c
echo hello world
上面的makefile輸出結果為:
現在我們不想輸出echo hello world
這條命令,我們可以使用@進行修飾,在makefile當中如果一條命令使用@進行了修飾,那麼這條命令就不會輸出。
main: demo.c
@echo hello world
上面的makefile輸出結果如下:
在使用make命令的時候可以進行變數的設定,這個變數我們可以在makefile檔案當中使用:
main: demo.c
@echo $(var) # 使用變數 var
我們現在輸入make命令並且指定引數然後檢視結果:
可以看到我們指定的變數在makefile當中可以使用了。
但是如果在我們的makefile當中也有一個變數叫做var
那麼makefile當中的var
就會被覆蓋。比如像下面這個例子一樣:
如果我們想讓我們自己的變數起作用的話我們可以使用override:
在本篇文章當中主要給大家介紹了Makefile當中一些常用的函數的使用,整體比較簡單,大家可以對照著makefile和結果自己實現一遍。
以上就是本篇文章的所有內容了,我是LeHung,我們下期再見!!!更多精彩內容合集可存取專案:https://github.com/Chang-LeHung/CSCore
關注公眾號:一無是處的研究僧,瞭解更多計算機(Java、Python、計算機系統基礎、演演算法與資料結構)知識。