Makefile學習心得

Makefile

1、 .PHONY
用法:

  all:
    mkdir hellos
 .PHONY: all

若target名和文件名重複,make命令在執行時會不知道target指向什麼。爲了避免衝突,makefile內的target使用.PHONY就在Makefile中。
2、=,:=,?=,+=的區別

  • =最基本的賦值,make會將整個Makefile展開後,再決定變量的值。隨文件的依賴關係會刷新變量的值。
  • :=覆蓋之前的值(變量的值取決於它在Makefile中的位置)
  • ?=如果沒有被賦值過就賦予等號後面得值;
  • +=添加等號後面的值

3、“$”

  • 調用定義好的變量
  • 實際使用“ $”表示

4、tab鍵表示空位

  • Makefile中的命令,必須以[Tab]鍵開始,故target後的命令必須是一個tab鍵的空位。

5、$@、$^、$<、$?、$%、$+、$*

  • $@ 表示目標文件
  • $^ 表示所有的依賴文件
  • $< 表示第一個依賴文件
  • $? 表示比目標還要新的依賴文件
  • $% 僅當目標是函數庫文件中,表示規則中的目標成員名。例如,如果一個目標是“foo.a(bar.o)”,那麼,“$%”就是“bar.o”,“$@”就是“foo.a”。如果目標不是函數庫文件(Unix下是[.a],Windows下是[.lib]),那麼,其值爲空。
  • $+ 很像“$^”,依賴所有依賴目標的集合,不去除重複的依賴目標
  • $* 這個變量表示目標模式中“%”及其之前的部分。如果目標是“dir/a.foo.b”,並且目標的模式是“a.%.b”,那麼,“$*”的值就是“dir/a.foo”。這個變量對於構造有關聯的文件名是比較有較。如果目標中沒有模式的定義,那麼“$*”也就不能被推導出,但是,如果目標文件的後綴是make所識別的,那麼“$*”就是除了後綴的那一部分。例如:如果目標是“foo.c”,因爲“.c”是make所能識別的後綴名,所以,“$*”的值就是“foo”。這個特性是GNU make的,很有可能不兼容於其它版本的make,所以,你應該儘量避免使用“$*“,除非是在隱含規則或是靜態模式中。如果目標中的後綴是make所不能識別的,那麼“$ * ”就是空值。

6、make參數

  • “-n”或“–just-print”,只是顯示命令,但不會執行命令,這個功能很有利於我們調試我們的Makefile,看看我們書寫的命令是執行起來是什麼樣子的或是什麼順序的。
  • “-s”或“–slient”是全面禁止命令的顯示。一個全局的辦法是,給make加上“-i”或是“–ignore-errors”參數,那麼,Makefile中所有命令都會忽略錯誤。而如果一個規則是以“.IGNORE”作爲目標的,那麼這個規則中的所有命令將會忽略錯誤。這些是不同級別的防止命令出錯的方法,你可以根據你的不同喜歡設置。
  • “-k”或是“–keep-going”,這個參數的意思是,如果某規則中的命令出錯了,那麼就終目該規則的執行,但繼續執行其它規則。

4.3 依賴的類型
在GNU make的規則中可以使用兩種不同類型的依賴:1.以前章節所提到的規則中使用的是常規依賴,這是書寫Makefile規則時最常用的一種。2.另外一種在我們書寫Makefile時不會經常使用,它比較特殊、稱之爲“order-only”依賴。一個規則的常規依賴(通常是多個依賴文件)表明了兩件事:首先,它決定了重建此規則目標所要執行規則(確切的說是執行命令)的順序;表明在更新這個規則的目標(執行此規則的命令行)之前需要按照什麼樣的順序、執行那些規則(命令)來重建這些依賴文件(對所有依賴文件的重建,使用明確或者隱含規則。就是說對於這樣的規則:A:B C,那麼在重建目標A之前,首先需要完成對它的依賴文件B和C的重建。重建B和C的過程就是執行Makefile中以文件B和C爲目標的規則)。其次,它確定了一個依存關係;規則中如果依賴文件的任何一個比目標文件新,則認爲規則的目標已經過期而需要重建目標文件。

通常,如果規則中依賴文件中的任何一個被更新,則規則的目標相應地也應該被更新。

有時,需要定義一個這樣的規則,在更新目標(目標文件已經存在)時只需要根據依賴文件中的部分來決定目標是否需要被重建,而不是在依賴文件的任何一個被修改後都重建目標。爲了實現這一目的,相應的就需要對規則的依賴進行分類,一類是在這些依賴文件被更新後,需要更新規則的目標;另一類是更新這些依賴的,可不需要更新規則的目標。我們把第二類稱爲:“order-only”依賴。書寫規則時,“order-only”依賴使用管道符號“|”開始,作爲目標的一個依賴文件。規則依賴列表中管道符號“|”左邊的是常規依賴,管道符號右邊的就是“order-only”依賴。這樣的規則書寫格式如下:

TARGETS : NORMAL-PREREQUISITES | ORDER-ONLY-PREREQUISITES

這樣的規則中常規依賴文件可以是空;同樣也可以對一個目標進行多次追加依賴。需要注意:規則依賴文件列表中如果一個文件同時出現在常規列表和“order-only”列表中,那麼此文件被作爲常規依賴處理(因爲常規依賴所實現的動作是“order-only”依賴所實現的動作的一個超集)。

“order-only”依賴的使用舉例:

LIBS = libtest.a

foo : foo.c | $(LIBS)

   $(CC) $(CFLAGS) $< -o $@ $(LIBS)

make在執行這個規則時,如果目標文件“foo”已經存在。當“foo.c”被修改以後,目標“foo”將會被重建,但是當“libtest.a”被修改以後。將不執行規則的命令來重建目標“foo”。

就是說,規則中依賴文件$(LIBS)只有在目標文件不存在的情況下,纔會參與規則的執行。當目標文件存在時此依賴不會參與規則的執行過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章