Makefile中的foreach函數
摘自《GNU+Makefile中文手冊》整理翻譯:徐海兵
概述
函數“ foreach”不同於其它函數。它是一個循環函數。類似於 Linux 的 shell 中的 for 語句。
語法:
$(foreach VAR,LIST,TEXT)
函數功能:
這個函數的工作過程是這樣的:
如果需要(存在變量或者函數的引用),首先展開變量“ VAR”和“ LIST”的引用;而表達式“ TEXT”中的變量引用不展開。
執行時把“ LIST”中使用空格分割的單詞依次取出賦值給變量“ VAR”,然後執行“ TEXT”表達式。重複直到“ LIST”的最後一個單詞(爲空時結束)。
“ TEXT”中的變量或者函數引用在執行時才被展開,因此如果在“ TEXT”中存在對“ VAR”的引用,那麼“ VAR”的值在每一次展開式將會到的不同的值。
返回值:
空格分割的多次表達式“ TEXT”的計算的結果。
例子:
我們來看一個例子,定義變量“ files”,它的值爲四個目錄(變量“ dirs”代表的 a、b、 c、 d 四個目錄)下的文件列表:
dirs := a b c d
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
例子中,“ TEXT”的表達式爲“
files := $(wildcard a/* b/* c/* d/*)
當函數的“ TEXT”表達式過於複雜時,我們可以通過定義一箇中間變量,此變量代表表達式的一部分。並在函數的“ TEXT”中引用這個變量。上邊的例子也可以這樣來實現:
find_files = $(wildcard $(dir)/*)
dirs := a b c d
files := $(foreach dir,$(dirs),$(find_files))
在這裏我們定義了一個變量(也可以稱之爲表達式),需要注意,在這裏定義的是“遞歸展開”時的變量“ find_files”。保證了定義時變量值中的引用不展開,而是在表達式被函數處理時才展開(如果這裏使用直接展開式的定義將是無效的表達式)。可參考 6.2兩種變量定義 一節。
函數說明:
函數中參數“ VAR”是一個局部的臨時變量,它只在“ foreach”函數的上下文中有效,它的定義不會影響其它部分定義的同名“ VAR”變量的值。在函數的執行過程中它是一個“直接展開”式變量。在使用函數“ foreach”時,需要注意: 變量“ VAR”的名字。我們建議使用一個單詞、最好能夠表達其含義的名字,不要使用一個奇怪的字符串作爲變量名。雖然執行是不會發生錯誤,但是會讓人很費解。沒有人會喜歡這種方式,儘管可能它可以正常工作:
files := $(foreach Esta escrito en espanol!,b c ch,$(find_files))