makefile $@ $^ $%

makefile中的自動化變量$@,$%,$
 
自動化變量 
模式規則中,規則的目標和依賴文件名代表了一類文件名;規則的命令是對所有這
一類文件重建過程的描述,顯然,在命令中不能出現具體的文件名,否則模式規則失去
意義。那麼在模式規則的命令行中該如何表示文件,將是本小節的討論的重點。 
假如你需要書寫一個將.c 文件編譯到.o 文件的模式規則,那麼你該如何爲gcc 書寫
正確的源文件名?當然了,不能使用任何具體的文件名,因爲在每一次執行模式規則時
源文件名都是不一樣的。爲了解決這個問題,就需要使用“自動環變量”,自動化變量
的取值是根據具體所執行的規則來決定的,取決於所執行規則的目標和依賴文件名。 
下面對所有的自動化變量進行說明:   www.2cto.com  
$@ 
表示規則的目標文件名。如果目標是一個文檔文件(Linux中,一般稱.a 文件爲
文檔文件,也稱爲靜態庫文件),那麼它代表這個文檔的文件名。在多目標模式
規則中,它代表的是哪個觸發規則被執行的目標文件名。 
$% 
當規則的目標文件是一個靜態庫文件時,代表靜態庫的一個成員名。例如,規則
的目標是“foo.a(bar.o)”,那麼,“ $%”的值就爲“bar.o”,“ $@ ”的值爲“foo.a”。
如果目標不是靜態庫文件,其值爲空。 
$< 
規則的第一個依賴文件名。如果是一個目標文件使用隱含規則來重建,則它代表
由隱含規則加入的第一個依賴文件。 
$? 
所有比目標文件更新的依賴文件列表,空格分割。如果目標是靜態庫文件名,代
表的是庫成員(.o 文件)。   www.2cto.com  
$^ 
規則的所有依賴文件列表,使用空格分隔。如果目標是靜態庫文件,它所代表的
只能是所有庫成員(.o 文件)名。一個文件可重複的出現在目標的依賴中,變量
“$^”只記錄它的一次引用情況。就是說變量“$^”會去掉重複的依賴文件。 
$+ 
類似“$^”,但是它保留了依賴文件中重複出現的文件。主要用在程序鏈接時庫
的交叉引用場合。 
$* 
在模式規則和靜態模式規則中,代表“莖”。“莖”是目標模式中“% ”所代表的
部分(當文件名中存在目錄時,“莖”也包含目錄(斜槓之前)部分,可參考  10.5.4 
模式的匹配  一小節)。例如:文件“dir/a.foo.b”,當目標的模式爲“a.%.b ”時,
“$* ”的值爲“dir/a.foo ”。“莖”對於構造相關文件名非常有用。 
自動化變量“$* ”需要兩點說明: 
?   對於一個明確指定的規則來說不存在“莖”,這種情況下“$* ”的含義發
生改變。此時,如果目標文件名帶有一個可識別的後綴(參考  10.7 後
綴規則  一節),那麼“$* ”表示文件中除後綴以外的部分。例如:“foo.c”
則“$* ”的值爲:“foo ”,因爲.c 是一個可識別的文件後綴名。GUN make
對明確規則的這種奇怪的處理行爲是爲了和其它版本的make兼容。通
常,在除靜態規則和模式規則以外,明確指定目標文件的規則中應該避
免使用這個變量。 
?   當明確指定文件名的規則中目標文件名包含不可識別的後綴時,此變量
爲空。 
自動化變量“$?”在顯式規則中也是非常有用的,使用它規則可以指定只對更新
以後的依賴文件進行操作。例如,靜態庫文件“libN.a ”,它由一些.o 文件組成。這個規
則實現了只將更新後的.o 文件加入到庫中: 
 
     lib: foo.o bar.o lose.o win.o 
             ar r lib $? 
 
以上羅列的自動量變量中。其中有四個在規則中代表文件名($@ 、$<、$%、$* )。
而其它三個的在規則中代表一個文件名列表。GUN make 中,還可以通過這七個自動化
變量來獲取一個完整文件名中的目錄部分和具體文件名部分。在這些變量中加入“D”
或者“F”字符就形成了一系列變種的自動環變量。這些變量會出現在以前版本的make
中,在當前版本的make中,可以使用“dir”或者“notdir”函數來實現同樣的功能(可
參考  8.3  文件名處理函數  一節)。 
 
$(@D) 
表示目標文件的目錄部分(不包括斜槓)。如果“$@ ”是“dir/foo.o ”,那麼“$(@D) ”
的值爲“dir”。如果“$@ ”不存在斜槓,其值就是“. ”(當前目錄)。注意它和 函
數“dir”的區別! 
$(@F) 
目標文件的完整文件名中除目錄以外的部分(實際文件名)。如果“$@ ”爲
“dir/foo.o ”,那麼“$(@F) ”只就是“foo.o”。“$(@F) ”等價於函數“$(notdir 
$@) ”。 
$(*D) 
$(*F) 
分別代表目標“莖”中的目錄部分和文件名部分。 
$(%D) 
$(%F) 
當以如“archive(member) ”形式靜態庫爲目標時,分別表示庫文件成員
“member”名中的目錄部分和文件名部分。它僅對這種形式的規則目標有效。 
$(<D) 
$(<F) 
分別表示規則中第一個依賴文件的目錄部分和文件名部分。 
$(^D) 
$(^F) 
分別表示所有依賴文件的目錄部分和文件部分(不存在同一文件)。 
$(+D) 
$(+F) 
分別表示所有依賴文件的目錄部分和文件部分(可存在重複文件)。 
$(?D) 
$(?F) 
分別表示被更新的依賴文件的目錄部分和文件名部分
在討論自動化變量時,爲了和普通變量(如:“CFLAGS ”)區別,我們直接使用了
“$<”的形式。這種形式僅僅是爲了和普通變量進行區別,沒有別的目的。其實對於
自動環變量和普通變量一樣,代表規則第一個依賴文件名的變量名實際上是“< ”,我
們完全可以使用“$(<) ”來替代“$<”。但是在引用自動化變量時通常的做法是“$<”,
因爲自動化變量本身是一個特殊字符。 
GUN make同時支持“Sysv”特性,允許在規則的依賴列表中使用特殊的變量引
用(一般的自動化變量只能在規則的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”
(注意:要使用“$$”),它們分別代表了“目標的完整文件名”、“目標文件名中的目
錄部分”和“目標的實際文件名部分”。這三個特殊的變量只能用在明確指定目標文件
名的規則中或者是靜態模式規則中,不用於隱含規則中。另外Sysv make 和GNU make
對規則依賴的處理也不盡相同。Sysv make對規則的依賴進行兩次替換展開,而GUN 
make對依賴列表的處理只有一次,對其中的變量和函數引用直接進行展開。 
自動化變量的這個古怪的特性完全是爲了兼容Sysv  版本的makefile文件。在使用
GNU make 時可以不考慮這個,也可以在Makefile中使用僞目標“.POSIX ”來禁止這一
特性
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章