Linux中的自動化變量

模式規則中,規則的目標和依賴文件名錶明瞭一類文件名;規則的命令是對全部這一類文件重建過程的描述,顯然,在命令中不能出現具體的文件名,不然模式規則失去意義。那麼在模式規則的命令行中該如何表示文件,將是本小節的討論的重點。 函數

假如你須要書寫一個將.c文件編譯到.o文件的模式規則,那麼你該如何爲gcc書寫正確的源文件名?固然了,不能使用任何具體的文件名,由於在每一次執行模式規則時源文件名都是不同的。爲了解決這個問題,就須要使用「自動環變量」,自動化變量的取值是根據具體所執行的規則來決定的,取決於所執行規則的目標和依賴文件名。 spa

下面對全部的自動化變量進行說明: 命令行

$@ 文檔

表示規則的目標文件名。若是目標是一個文檔文件(Linux中,通常稱.a文件爲文檔文件,也稱爲靜態庫文件),那麼它表明這個文檔的文件名。在多目標模式規則中,它表明的是哪一個觸發規則被執行的目標文件名。 自動化

$% 編譯

當規則的目標文件是一個靜態庫文件時,表明靜態庫的一個成員名。例如,規則的目標是「foo.a(bar.o)」,那麼,「$%」的值就爲「bar.o」,「$@」的值爲「foo.a」。若是目標不是靜態庫文件,其值爲空。 變量

$< gcc

規則的第一個依賴文件名。若是是一個目標文件使用隱含規則來重建,則它表明由隱含規則加入的第一個依賴文件。 file

$? 引用

全部比目標文件更新的依賴文件列表,空格分割。若是目標是靜態庫文件名,表明的是庫成員(.o文件)。

$^

規則的全部依賴文件列表,使用空格分隔。若是目標是靜態庫文件,它所表明的只能是全部庫成員(.o文件)名。一個文件可重複的出如今目標的依賴中,變量「$^」只記錄它的一次引用狀況。就是說變量「$^」會去掉重複的依賴文件。

$+

相似「$^」,可是它保留了依賴文件中重複出現的文件。主要用在程序連接時庫的交叉引用場合。

$*

在模式規則和靜態模式規則中,表明「莖」。「莖」是目標模式中「%」所表明的部分(當文件名中存在目錄時,「莖」也包含目錄(斜槓以前)部分)。例如:文件「dir/a.foo.b」,當目標的模式爲「a.%.b」時,「$*」的值爲「dir/a.foo」。「莖」對於構造相關文件名很是有用。

自動化變量「$*」須要兩點說明:

1    對於一個明確指定的規則來講不存在「莖」,這種狀況下「$*」的含義發生改變。此時,若是目標文件名帶有一個可識別的後綴,那麼「$*」表示文件中除後綴之外的部分。例如:「foo.c」則「$*」的值爲:「foo」,由於.c是一個可識別的文件後綴名。GUN make對明確規則的這種奇怪的處理行爲是爲了和其它版本的make兼容。一般,在除靜態規則和模式規則之外,明確指定目標文件的規則中應該避免使用這個變量。

2      當明確指定文件名的規則中目標文件名包含不可識別的後綴時,此變量爲空。

自動化變量「$?」在顯式規則中也是很是有用的,使用它規則能夠指定只對更新之後的依賴文件進行操做。例如,靜態庫文件「libN.a」,它由一些.o文件組成。這個規則實現了只將更新後的.o文件加入到庫中:

 

     lib: foo.o bar.o lose.o win.o

             ar r lib $?

 

以上羅列的自動化變量中。其中有四個在規則中表明文件名($@$<$%$*)。而其它三個的在規則中表明一個文件名列表。GUN make中,還能夠經過這七個自動化變量來獲取一個完整文件名中的目錄部分和具體文件名部分。在這些變量中加入「D」或者「F」字符就造成了一系列變種的自動環變量。這些變量會出如今之前版本的make中,在當前版本的make中,可使用「dir」或者「notdir」函數來實現一樣的功能。

$(@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 makeGNU make對規則依賴的處理也不盡相同。Sysv make對規則的依賴進行兩次替換展開,而GUN make對依賴列表的處理只有一次,對其中的變量和函數引用直接進行展開。

自動化變量的這個古怪的特性徹底是爲了兼容Sysv 版本的makefile文件。在使用GNU make時能夠不考慮這個,也能夠在Makefile中使用僞目標「.POSIX」來禁止這一特性。

相關文章
相關標籤/搜索