makefile文件的條件語句

makefile文件的條件語句

一個條件語句可以導致根據變量的值執行或忽略makefile文件中一部分腳本。條件語句可以將一個變量與其它變量的值相比較,或將一個變量與一字符串常量相比較。條件語句用於控制make實際看見的makefile文件部分,不能用於在執行時控制shell命令。

條件語句的例子

下述的條件語句的例子告訴make如果變量CC的值是‘gcc’時使用一個數據庫,如不是則使用其它數據庫。它通過控制選擇兩命令行之一作爲該規則的命令來工作。‘CC=gcc’作爲make改變的參數的結果不僅用於決定使用哪一個編譯器,而且決定連接哪一個數據庫。
libs_for_gcc = -lgnu
normal_libs =
 
foo: $(objects)
ifeq ($(CC),gcc)
        $(CC) -o foo $(objects) $(libs_for_gcc)
else
        $(CC) -o foo $(objects) $(normal_libs)
endif
該條件語句使用三個指令:ifeq、else和endif。
Ifeq指令是條件語句的開始,並指明條件。它包含兩個參數,它們被逗號分開,並被擴在圓括號內。運行時首先對兩個參數變量替換,然後進行比較。在makefile中跟在ifeq後面的行是符合條件時執行的命令;否則,它們將被忽略。
如果前面的條件失敗,else指令將導致跟在其後面的命令執行。在上述例子中,意味着當第一個選項不執行時,和第二個選項連在一起的命令將執行。在條件語句中,else指令是可選擇使用的。
Endif指令結束條件語句。任何條件語句必須以endif指令結束,後跟makefile文件中的正常內容。
上例表明條件語句工作在原文水平:條件語句的行根據條件要麼被處理成makefile文件的一部分或要麼被忽略。這是makefile文件重大的語法單位(例如規則)可以跨越條件語句的開始或結束的原因。
當變量CC的值是gcc,上例的效果爲:
foo: $(objects)
        $(CC) -o foo $(objects) $(libs_for_gcc)
當變量CC的值不是gcc而是其它值的時候,上例的效果爲:
foo: $(objects)
        $(CC) -o foo $(objects) $(normal_libs)
相同的結果也能使用另一種方法獲得:先將變量的賦值條件化,然後再使用變量:
libs_for_gcc = -lgnu
normal_libs =
 
ifeq ($(CC),gcc)
  libs=$(libs_for_gcc)
else
  libs=$(normal_libs)
endif
 
foo: $(objects)
        $(CC) -o foo $(objects) $(libs)

條件語句的語法

對於沒有else指令的條件語句的語法爲:
conditional-directive
text-if-true
endif
‘text-if-true’可以是任何文本行,在條件爲‘真’時它被認爲是makefile文件的一部分;如果條件爲‘假’,將被忽略。完整的條件語句的語法爲:
conditional-directive
text-if-true
else
text-if-false
endif
如果條件爲‘真’,使用‘text-if-true’;如果條件爲‘假’,使用‘text-if-false’。‘text-if-false’可以是任意多行的文本。
關於‘conditional-directive’的語法對於簡單條件語句和複雜條件語句完全一樣。有四種不同的指令用於測試不同的條件。下面是指令表:

ifeq (arg1arg2)

ifeq 'arg1' 'arg2'

ifeq "arg1" "arg2"

ifeq "arg1" 'arg2'

ifeq 'arg1' "arg2"

 擴展參數arg1、arg2中的所有變量引用,並且比較它們。如果它們完全一致,則使用‘text-if-true’,否則使用‘text-if-false’(如果存在的話)。您經常要測試一個變量是否有非空值,當經過複雜的變量和函數擴展得到一個值,對於您認爲是空值,實際上有可能由於包含空格而被認爲不是空值,由此可能造成混亂。對於此,您可以使用strip函數從而避免空格作爲非空值的干擾。例如:
ifeq ($(strip $(foo)),)
text-if-empty
endif
即使$(foo)中含有空格,也使用‘text-if-empty’。

ifneq (arg1arg2)

ifneq 'arg1' 'arg2'

ifneq "arg1" "arg2"

ifneq "arg1" 'arg2'

ifneq 'arg1' "arg2"

擴展參數arg1、arg2中的所有變量引用,並且比較它們。如果它們不同,則使用‘text-if-true’,否則使用‘text-if-false’(如果存在的話)。

ifdef variable-name

如果變量‘variable-name’是非空值,‘text-if-true’有效,否則,‘text-if-false’有效(如果存在的話)。變量從沒有被定義過則變量是空值。注意ifdef僅僅測試變量是否有值。它不能擴展到看變量是否有非空值。因而,使用ifdef測試所有定義過的變量都返回‘真’,但那些象‘foo=’情況除外。測試空值請使用ifeq($(foo),)。例如:
bar =
foo = $(bar)
ifdef foo
frobozz = yes
else
frobozz = no
endif

設置‘frobozz'的值爲‘yes', 而::

foo =
ifdef foo
frobozz = yes
else
frobozz = no
endif

設置‘frobozz' 爲‘no'。

ifndef variable-name

如果變量‘variable-name’是空值,‘text-if-true’有效,否則,‘text-if-false’有效(如果存在的話)。
在指令行前面允許有多餘的空格,它們在處理時被忽略,但是不允許有Tab(如果一行以Tab開始,那麼該行將被認爲是規則的命令行)。除此之外,空格和Tab可以插入到行的任何地方,當然指令名和參數中間除外。以‘#’開始的註釋可以在行的結尾。
在條件語句中另兩個有影響的指令是else和endif。這兩個指令以一個單詞的形式出現,沒有任何參數。在指令行前面允許有多餘的空格,空格和Tab可以插入到行的中間,以‘#’開始的註釋可以在行的結尾。
條件語句影響make使用的makefile文件。如果條件爲‘真’,make讀入‘text-if-true’包含的行;如果條件爲‘假’,make讀入‘text-if-false’包含的行(如果存在的話);makefile文件的語法單位,例如規則,可以跨越條件語句的開始或結束。
當讀入makefile文件時,Make計算條件的值。因而您不能在測試條件時使用自動變量,因爲他們是命令執行時才被定義(參閱自動變量)。
爲了避免不可忍受的混亂,在一個makefile文件中開始一個條件語句,而在另外一個makefile文件中結束這種情況是不允許的。然而如果您試圖引入包含的makefile文件不中斷條件語句,您可以在條件語句中編寫include指令。

測試標誌的條件語句

您可以使用變量MAKEFLAGS和findstring函數編寫一個條件語句,用它來測試例如‘-t’等的make命令標誌(參閱字符串替換和分析的函數)。這適用於僅使用touch標誌不能完全更改文件的時間戳的場合。
findstring函數檢查一個字符串是否爲另一個字符串的子字符串。如果您要測試‘-t’標誌,使用‘-t’作爲第一個字符串,將變量MAKEFLAGS的值作爲另一個字符串。例如下面的例子是安排使用‘ranlib –t’完成一個檔案文件的更新:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
        +touch archive.a
        +ranlib -t archive.a
else
        ranlib archive.a
endif
前綴‘+’表示這些命令行是遞歸調用行,即使是用‘-t’標誌它們一樣要執行。參閱遞歸調用make
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章