Makefile的條件執行

第七章:Makefile的條件執行

http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/make-07.html

--------------------------------------------------------------------------------條件語句可以根據一個變量的值來控制make執行或者忽略Makefile的特定部分。條件語句可以是兩個不同變量、或者變量和常量值的比較。要注意的是:條件語句只能用於控制make實際執行的makefile文件部分,它不能控制規則的shell命令執行過程。Makefile中使用條件控制可以做到處理的靈活性和高效性。7.1 一個例子首先我們來看一個使用條件判斷的Makefile例子;對變量“CC”進行判斷,其值如果是“gcc”那麼在程序連接時使用庫“libgnu.so”或者“libgnu.a”,否則不鏈接任何庫。Makefile中的條件判斷部分如下:……libs_for_gcc = -lgnunormal_libs = …… foo: $(objects) ifeq ($(CC),gcc)$(CC) -o foo $(objects) $(libs_for_gcc)else$(CC) -o foo $(objects) $(normal_libs)endif…… 例子中,條件語句中使用到了三個關鍵字:“ifeq”、“else”和“endif”。其中:1. “ifeq”表示條件語句的開始,並指定了一個比較條件(相等)。之後是用圓括號括包圍的、使用逗號“,”分割的兩個參數,和關鍵字“ifeq”用空格分開。參數中的變量引用在進行變量值比較時被展開。“ifeq”之後就是當條件滿足make需要執行的,條件不滿足時忽略。2. “else”之後就是當條件不滿足時的執行部分。不是所有的條件語句都需要此部分。3. “endif”表示一個條件語句的結束,任何一個條件表達式都必須以“endif”結束。通過上邊的例子我們可以瞭解到。Makefile中,條件表達式工作於文本級別(條件判斷處理爲文本級別的處理過程),條件的解析是由make來完成的。make是在讀取並解析Makefile時根據條件表達式忽略條件表達式中的某一個文本行,解析完成後保留的只有表達式滿足條件所需要執行的文本行。上例,make處理條件的過程:當變量“CC”的值爲“gcc”時,整個條件表達式等效於:foo: $(objects)$(CC) -o foo $(objects) $(libs_for_gcc) 當變量“CC”值不等於“gcc”時等效於:foo: $(objects)$(CC) -o foo $(objects) $(normal_libs) 上面的例子,一種更簡潔實現方式:libs_for_gcc = -lgnunormal_libs = ifeq ($(CC),gcc)libs=$(libs_for_gcc)elselibs=$(normal_libs)endif foo: $(objects)$(CC) -o foo $(objects) $(libs)7.2 條件判斷的基本語法一個簡單的不包含“else”分支的條件判斷語句的語法格式爲:CONDITIONAL-DIRECTIVETEXT-IF-TRUEendif表達式中“TEXT-IF-TRUE”可以是若幹任何文本行,當條件爲真時它就將被make作爲需要執行的一部分。當條件爲假時,不作爲需要執行的一部分。包含“else”的複雜一點的語法格式爲:CONDITIONAL-DIRECTIVETEXT-IF-TRUEelseTEXT-IF-FALSEendif 表示瞭如果條件爲真,則將“TEXT-IF-TRUE”作爲執行Makefile的一部分,否則將“TEXT-IF-FALSE”作爲執行的Makefile的一部分。和“TEXT-IF-TRUE”一樣,“TEXT-IF-FALSE”可以是若幹任何文本行。條件判斷語句中“CONDITIONAL-DIRECTIVE”對於上邊的兩種格式都是同樣的。可以是以下四種用於測試不同條件的關鍵字。7.2.1 關鍵字“ifeq”此關鍵字用來判斷參數是否相等,格式如下:`ifeq (ARG1, ARG2)'`ifeq 'ARG1' 'ARG2''`ifeq "ARG1" "ARG2"'`ifeq "ARG1" 'ARG2''`ifeq 'ARG1' "ARG2"' 替換展開“ARG1”和“ARG1”後,對它們的值進行比較。如果相同則(條件爲真)將“TEXT-IF-TRUE”作爲make要執行的一部分,否則將“TEXT-IF-FALSE”作爲make要執行的一部分(上邊的第二種格式)。通常我們會使用它來判斷一個變量的值是否爲空(不是任何字符)。參數值可能是通過引用變量或者函數得到的,因而在展開過程中可能造成參數值中包含空字符(空格等)。一般在這種情況時我們使用make的“strip”函數來對它變量的值進行處理,去掉其中的空字符。格式爲: ifeq ($(strip $(foo)),)TEXT-IF-EMPTYendif 這樣,即就是在“$(foo)”中存在若干前導和結尾空格,“TEXT-IF-EMPTY”也會被作爲Makefile需要執行的一部分。7.2.2 關鍵字“ifneq”此關鍵字是用來判斷參數是否不相等,格式爲:`ifneq (ARG1, ARG2)'`ifneq 'ARG1' 'ARG2''`ifneq "ARG1" "ARG2"'`ifneq "ARG1" 'ARG2''`ifneq 'ARG1' "ARG2"' 關鍵字“ifneq”實現的條件判斷語句和“ifeq”相反。首先替換並展開“ARG1”和“ARG1”,對它們的值進行比較。如果不相同(條件爲真)則將“TEXT-IF-TRUE”作爲make要執行的一部分,否則將“TEXT-IF-FALSE”作爲make要執行的一部分。7.2.3 關鍵字“ifdef”關鍵字“ifdef”用來判斷一個變量是否已經定義。格式爲:`ifdef VARIABLE-NAME' 如果變量“VAEIABLE_NAME”的值非空(在Makefile中沒有定義的變量的值爲空),那麼表達式爲真,將“TEXT-IF-TRUE”作爲make要執行的一部分。否則,表達式爲假,如果存在“TEXT-IF-FALSE”,就將它作爲make要執行一部分。當一個變量沒有被定義時,它的值爲空。“VARIABLE-NAME”可以是變量或者函數的引用。對於“ifdef”需要說明的是:ifdef只是測試一個變量是否有值,不會對變量進行替換展開來判斷變量的值是否爲空。對於變量“VARIABLE-NAME”,除了“VARIABLE-NAME=”這種情況以外,使用其它方式對它的定義都會使“ifdef”返回真。就是說,即使我們通過其它方式(比如,定義它的值引用了其它的變量)給它賦了一個空值,“ifdef”也會返回真。我們來看一個例子:例1:bar =foo = $(bar)ifdef foofrobozz = yeselsefrobozz = noendif 例2:foo =ifdef foofrobozz = yeselsefrobozz = noendif 例1中的結果是:“frobozz = yes”;而例2的結果是:“frobozz = no”。其原因就是在例1中,變量“foo”的定義是“foo = $(bar)”。雖然變量“bar”的值爲空,但是“ifdef”判斷的結果是真。因此當我們需要判斷一個變量的值是否爲空的情況時,需要使用“ifeq”(或者“ifneq”)而不是“ifdef”。可參考前兩個小節的內容。7.2.4 關鍵字“ifndef”關鍵字“ifndef”實現的功能和“ifdef”相反。格式爲:`ifdef VARIABLE-NAME'這個就不詳細討論了,它的功能就是實現了和“ifdef”相反的條件判斷。 在“CONDITIONAL-DIRECTIVE”這一行上,可以以若干個空格開始,make處理時會被忽略這些空格。但不能以[Tab]字符做爲開始(不然就被認爲是命令)。條件判斷語句中,在除關鍵字(包括“endif”)之前、條件表達式參數中之外的其他任何地方都可以使用多個空格或[Tab]字符,它不會影響條件判斷語句的功能。同樣行尾也可以使用註釋(“#”開始直到一行的結束)。“else”和“endif”也是條件判斷語句的一部分。在書寫時它們都是沒有任何參數的,可以以多個空格開始(同樣不能以[Tab]字符開始)多個空格或[Tab]字符結束。行尾同樣可以有註釋內容。在make讀取makefile文件時計算表達式的值,並根據表達式的值決定判斷語句中那一部分被作爲此Makefile所要執行的內容(選擇符合條件的語句)。因此在條件表達式中不能使用自動化變量,自動化變量在規則命令執行時纔有效。更不能將一個完整的條件判斷語句分寫在兩個不同的makefile文件中,在一個makefile文件使用指示符“include”包含另外一個makefile文件。7.3 標記測試的條件語句我們可以使用條件判斷語句、變量“MAKEFLAGS”和函數“findstring”,實現對make命令行選項的測試。看一個例子:archive.a: ...ifneq (,$(findstring t,$(MAKEFLAGS)))+touch archive.a+ranlib -t archive.aelseranlib archive.aendif 這個條件語句判斷make的命令行參數中是否包含“-t”(用來更新目標文件的時間戳)。根據命令行參數情況完成對“archive.a”執行不同的操作。命令行前的“+”的意思是告訴make,即使make使用了“-t”參數,“+”之後的命令都需要被執行。

發佈了2 篇原創文章 · 獲贊 0 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章