首頁 >後端開發 >C#.Net教程 >makefile規則

makefile規則

黄舟
黄舟原創
2016-12-16 09:48:411773瀏覽

 目錄
1.簡介3
1.1.預備工作3
1.2.Makefile介紹3
1.3.規則簡介4
1.4.make工作原理4
1.5.使用變數5
1.6.風格6
1.8.清理7
2.Makefile 7
2.1.makefile名字7
2.2.包含8
2.3.'MAKEFILE'變數8
2.4.如何重新產生makefile 8
2.5.重載9
3.1.例子9
3.2.規則的語法9
3.3.通配符10
3.3.1.通配符的缺陷10
3.3.2.wildcard函數11
3.4.目錄搜尋11
3.3.2.wildcard函數11
3.4.目錄搜尋11
3.4.11.
3.4.2.選擇性搜尋12
3.4.3.使用自動變數12
3.4.4.目錄搜尋和隱含規則12
3.5.PHONY目標13
3.6.FORCE目標14
3.7.7. .內建的非凡目標14
3.9.一個規則多個目標15
3.10.一個目標多條規則15
3.11.靜態模式規則16
3.11.1.語法16
3.11.2.靜態模式規則和隱式規則17
3.12.雙冒號規則17
3.13.自動產生依靠關係17
4.編寫指令18
4.1.回顯18
4.2.執行19
4.3.並行執行19
4.4.195. 20
4.6.遞歸使用20
4.6.1.'MAKE'變數20
4.6.2.傳遞變數到子make 21
5.命令列參數21
6.參考25
6.1.25
指令25

6.3.自動變數27
6.4.非凡變數29
GNU Make使用
Make 程式最初設計是為了維護C程式檔案防止不必要的重新編譯。在使用命令列編譯器的時候,修改了一個工程中的頭文件,如何確保包含這個頭文件的所有文件都被編譯?現在10機的版本生成是使用批次程序,編譯那些文件依靠程序的維護者,在模組之間相互引用頭文件的情況下,要將所有需要重新編譯的文件找出來是一件痛苦的事情;在找到這些檔案之後,修改批次進行編譯。實際上這些工作可以讓make程式來自動完成,make工具對於維護一些具有相互依靠關係的檔案非凡有用,它對檔案和命令的聯繫(在檔案改變時調用來更新其它檔案的程式)提供一套編碼方法。 Make工具的基本概念類似PRoglog語言,你告訴make需要做什麼,提供一些規則,make來完成剩下的工作。
1.簡介
make工作自動決定工程的哪部分需要重新編譯,執行指令去編譯它們。雖然make多用於C程序,然而只要提供命令列的編譯器,你可以將其用於任何語言。實際上,make工具的應用範圍不僅於編程,你可以描述任和一些文件改變需要自動更新另一些文件的任務來使用它。
1.1.預備工作
假如要使用make,你必須寫一個叫做「makefile」的文件,這個文件描述工程中文件之間的關係,提供更新每個文件的命令。典型的工程是這樣的:可執行檔靠目標檔來更新,目標檔靠編譯原始檔來更新。
Makefile寫好之後,每次更改了原始檔後,只要執行make就足夠了,所有必要的重新編譯都會執行。 Make程式利用makefile中的資料庫和文件的最後修改時間來決定那個文件需要更新;對於需要更新的文件,make執行資料庫中記錄的指令。
可以提供命令列參數給make來控制那個檔案需要重新編譯。
1.2.Makefile介紹
Makefile檔案告訴make做什麼,多數情況是怎麼編譯和連結一個程式。
這裡有一個簡單的makefile,描述如何編譯連結由8個C檔案和3個頭檔組成的一個編輯器:
edit : main.o kbd.o command.o display.o 
insert.o serach.o files .o utils.o
cc –o edit main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc –c main.c
kdb.o : kbd.c defs.h command.h
cc –c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer. h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o
將長行用分開便於閱讀,這和使用一個長行的作用是一樣的。使用這個makefile建立可執行檔「edit」時執行make就可以了;如果要將可執行檔和目標檔刪除,執行make clean
make重新編譯這個編輯器時,每個更改的C檔必須重新編譯;假如頭檔更改了,每個包含頭檔的C檔必須重新編譯;每次編譯產生一個對應於原檔的目標檔。最終,目標檔案連結在一起產生新的可執行檔。
1.3.規則簡介
makefile中的規則是這樣的:
TARGET … : DEPENDENCIES …
COMMAND

目標(TARGET)程式產生的文件,如可執行檔和目標檔;目標也可以是要執行的動作,如「clean」。
依靠(DEPENDENCIES)是用來產生目標的輸入文件,一個目標通常依賴多個文件。

指令(COMMAND)是make執行的動作,一個可以有多個指令,每個佔一行。注重:每個命令行的起始字元必須為TAB字元!
有依賴關係規則中的命令通常在依賴文件變化時負責產生target文件,make執行這些命令更新或產生target。規則可以沒有依賴關係,如包含target “clean”的規則。
規則解釋如何和何時重做該規則中的文件,make根據依靠關係執行產生或更新目標;規則也說明如何和何時執行動作。有的規則看起來很複雜,但都符合上述模式。
1.4.make工作原理
缺省make從第一個target開始(第一個非 ’.’ 開始的target),這稱為缺省目標。在上述的makefile中,預設目標是更新執行程序’edit’,將這個目標放在最前面。當執行make的時候,make程式從目前目錄讀入makefile開始處理第一個規則;在例子中,這個規則是重新連結'edit';在make處理這個規則之前,必須處理'edit'所依賴的那些文件的規則,例子中是目標文件。這些檔案按照自己的規則處理:透過編譯原始檔來更新每個’.o’檔案;當依靠關係中的原始檔案或頭檔比目標檔案新,或目標檔案不存在時,必須重新編譯。
其它的規則被處理是因為他們的target是目標的依靠,和目標沒有依靠關係的規則不會被處理,除非指定make處理(如make clean)。
在重新編譯目標檔案之前,make會試圖更新它的依靠:原始檔和頭檔。範例中的makefile對來源檔案和頭檔未指定任何操作:’.c’和’.h’檔案不是任何規則的目標。在確認所有的目標檔案都是最新的之後,make決定是否重新連結’edit’:假如’edit’不存在,或任何一個目標檔案都比它新,則連結工作將進行。
這樣,假如我們改變insert.c運行make,make會編譯這個檔案來更新'insert.o',然後連結'edit';假如修改了'command.h'執行make,'kbd.o','command .o','files.o'會重新生成,連結'edit'。
1.5.使用變數
在例子中,在規則'edit'中,目標檔案被列出來兩次:
edit : main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o
這樣的重複輕易出錯:假設工程中加入了一個新的目標檔案,可能只將其加入了一個列表中;透過使用變數可以消除這種風險:變數答應一個預先定義的字串在多個地方被替換。
在makefile中,可以寫這樣一行來定義'object'變數:
objects = main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o
於是在需要目標檔案名列表的地方,使用$(object) 來取代變數的值。以下是使用了變數以後的makefile:
objects = main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $ (objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command. defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.hcc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
1.6.簡化指令
為每個檔案寫出編譯指令不是必要的,因為make來做;以'.c'檔案更新'.o'檔案有一個隱含的規則,使用'cc -c'命令。 Make將利用’cc –c main.c –o main.o’來將main.c編譯為main.o,因此在產生目標檔案的規則中,可以省略指令。
當’.c’檔案以這樣的方式使用時,將自動加入到依靠關係中;由是在省略命令的前提下,可以將’.c’檔案從依靠關係中省略。以下是簡化的makefile:
objects = main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o edit : $(objects)
cc -o edit $(objects) main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer. h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
-rm edit(objectsobjects
1.7.另一種風格
假如makefile中的目標都是以隱含規則生成,可以將規則按照依靠關係分組:
objects = main.o kbd.o command.o display.o 
insert.o search.o files.o utils.o edit : $(objects)
cc -o edit $(objects) $(objects) : defs.h
kbd.o command.o files.o : command.h
kbd.o command.o files.o : command.h
kb display.o insert.o search.o files.o : buffer.h
這裡'defs.h'作為所有目標檔案的依靠。這種風格是好是壞取決於個人喜好,它非常緊湊,但是將每個目標的依靠訊息放在一起看起來更清楚一些。
1.8.清理
編寫規則不至於編譯程式。 Makefile通常描述如何做其它事情:例如刪除目錄中的目標檔案和可執行檔來清理目錄。例子中是這樣寫的:

clean:
rm edit $(objects)
實際情況是,我們需要處理一些意外事件:存在一個叫做'clean'的文件;假如rm出錯,並不希望make過程停止下來,修改過的版本如下:
.PHONY : clean
clean :
-rm edit $(objects)
這樣的規則當然不能放在makefile的開始,因為這並不是我們缺省要做的工作。由於’clean’並不是’edit’的依靠,在執行make時沒有參數時,這條規則不會執行;要執行這個規則,必須執行’make clean’。
2.Makefile
Makefile包含五種內容:明確規則,隱含規則,變數定義,指令(directive)和註解。
1.明確規則描述如何產生規則的目標,它列出了目標依靠的文件,指定了產生或更新目標的命令
2.隱式規則描述如何生成基於文件名的一類文件,說明目標可能依靠和其文件名類似的文件,指定了相應的命令。
3.指令類似與編譯器的偽指令,包含:
4.指示make讀入另一個makefile
5.決定是否忽略makefile中的一部分
6.定義一個變數
7.一行中'#'開始是註釋,直到行末,除非碰到續行符號。在’define’和指令中不能有註釋,其它情況下註釋可出現在任何地方。
2.1.makefile名字
缺省情況下,make以下列名字查找makefile:’GNUmakefile’,’makefile’和’Makefile’(註重大小寫)。通常你的makefile就該叫做’makefile’或’Makefile’。 ’GNUmakefile’不推薦,除非你的makefile是為GNU的make定制的,其它的make不認為該名字是一個makefile的名字。
假如你使用非標準命名的makefile,必須用指令開關’-f ’ 或 ’—file’。參數’ –f NAME’或’—file NAME’告訴make讀入NAME作為makefile。如果使用多個該開關,所有的文件將依序連接起來。如果使用該選項,標準的makefile名字不會自動偵測。
2.2.包含
‘include’指令告訴make暫停處理餘下的內容,讀入其它makefile。文法如下:
include FILENAMES …
這一行起始可以有空格,但TAB字元不答應。假如檔案名稱包含變數或函數,這些將被擴展。
2.3.‘MAKEFILE’變數
假如環境變數’MAKEFILE’已定義,make認為它的值是一系列空格隔開的檔名,這些檔案在處理其它makefile前被make程式讀入。這類似於include指令;這些文件中的目標不會影響缺省目標,而且假如文件未找到的話,make並不認為是錯誤。
這個變數的主要用途是遞歸引用make程式時通訊
2.4.如何重新產生makefile
有時候makefile是從其它檔案產生的,例如RCS或SCCS檔案。假如makefile是由其它檔案產生的,需要make讀入最新版本的makefile。
在讀入所有makefile之後,make認為每個makefile是一個目標,試圖去更新它;假如makefile中有一條如何更新它的規則,或者有適用的隱式規則,需要的更新會進行。所有的makefile檢查完之後,假如有的改變了,make重新開始再讀入(make會試著再做更新,但通常不會再改變了,因為已經是最新的了)。
假如一個文件使用雙冒號規則,提供了命令但沒有依靠關係,文件總是會被更新。在makefile的情況下,假如makefile雙冒號規則,提供了命令但沒有依靠關係,這樣makefile始終會重新生成,這會導致循環:make只是在不斷更新makefile,卻不干活。為避免這種情況,make不會重新產生那些只有指令沒有依賴關係的雙冒號規則的makefile。
假如沒有使用’-f’或’--file’選項,make會嘗試預設的makefile檔名。和指明’-f’或’--file’選項不同,make無法確定這些檔案是否應存在。然而,假如缺省makefile不存在但可以透過執行make規則生成,你可能希望這些規則被運行使得makefile可以使用。
因此,假如沒有缺省makefile,make試圖按照makefile名查找的順序生成它,直到成功或名字用完。注重假如make 無法找到或產生makefile,這並不是錯誤;makefile不總是必要的。 🎜當使用’-t’或’--toUCh’選項時,不希望使用過時的makefile來決定那個目標來touch。所以'-t'選項對makefile更新不起作用;類似'-q'(or '—question')和'-n'(or '—just-print')不會阻止makefile的更新,因為過時的makefile會產生錯誤的輸出。這樣’make –f mfile –n foo’會更新’mfile’,讀入它,列印出更新’foo’需要執行的指令但不執行這些指令。與’foo’有關的指令是更新過的’mfile’中的內容。
但是有時不希望更新makefile,可以將makefile作為命令列的目標,當makefile被明確指定為目標時,’-t’選項也適用於它們。
這樣’make –f mfile –n mfile foo’會讀入’mfile’,印出更新執行的指令,’foo’的指令是目前的’mfile’的內容。
2.5.重載makefile
可以使用’include’指令來包含其它makefile,增加目標的變數定義。然而,make不答應同一個目標有不同的命令,有其它的途徑可以達到目的。
假設有’makefile’ 和’mfile’,’makfile’要包含’mfile’,但都有目標’foo’的規則。這是可以在'makefile'中寫一條符合任意模式的規則,指明當make在'makefile'中找不到目標時,搜尋'mfile':
foo:
frobnicate > foo
%: force
@$(MAKE ) -f mfile $@
force: ;
當執行'make foo'時,make找到'makefile',執行指令' frobnicate > foo';執行'make bar'時,在'makefile'中找不到對應的規則,這時模式規則適用,執行命令'make –f mfile bar','makefile'中未提及的其它目標也是類似的。
這種方法之所有工作是因為模式規則的模式是'%',可以匹配任何的目標;這條規則的依靠是'force',保證即使目標存在命令也會執行;'force'規則的命令為空防止'make'為其搜尋隱式規則-這樣會導致依靠循環。

3.規則
makefile中的規則描述如何產生特定的文件,即規則的目標。規則列出了目標的依賴文件,指定產生或更新目標的命令。
規則的次序是不重要的,除非是確定缺省目標:缺省目標是第一個makefile中的第一個規則;假如第一個規則有多個目標,第一個目標是缺省的。有兩個例外:以’.’開頭的目標不是預設目標;模式規則對預設目標沒有影響。
通常我們所寫的地一個規則是編譯整個或makefile中指定的所有程式。
3.1.例
foo.o : foo.c defs.h # module for twiddling the frobs
cc -c -g foo.c
它的目標是'foo.o',依靠於'foo.c'和' defs.h',有一個指令'cc –c –g foo.c'。命令列以TAB字元開始標識它是一個命令。
這條規則說明兩件事:
8.如何決定’foo.o’是舊的:假如它不存在,或者’foo.c’或’defs.h’比它新。
9.如何更新’foo.o’檔案:透過執行’cc’程式。命令未提及’defs.h’,擔可以猜想’foo.c’包含了它,這是’defs.h’被置於依靠關係中的理由。
3.2.規則的語法
語法如下:
TARGETS : DEPENDENCIES
COMMAND
...

TARGETS : DEPENDENCIES ; COMMAND
COMMAND
TARGETS : DEPENDENCIES ; COMMAND
COMMAND
TARGETS : DEPENDENCIES ; COMMAND
COMMAND
。通常一個規則只有一個目標,偶然也有多個。
命令列以TAB鍵開始。第一條指令可在依靠關係的下一行;或在同一行,在分號後面;兩種方式效果相同。
因為’$’符號被用來做變數引用,假如要在規則中使用’$’符號,必須寫兩個:’$$’。可以用’’符號來分割一個長行,這不是必須的,因為make對行的長度沒有限制。
3.3.通配符
規則中的檔案名稱可以包含統配符,如’*’,’?’。
檔案名稱前的字元’~’有非凡的意義。單獨使用,或跟隨一​​個'/',代表使用者的home目錄,例如'~/bin'擴展為/home/you/bin';假如'~'跟隨一個單詞,表示單字指示的那個使用者的home目錄,如'~john/bin'擴展為'/home/john/bin'。
通配符在目標,依靠關係,命令中自動擴展,其它情況下,統配符的擴展除非明確使用’wildcard’函數。通配符的非凡意義可以使用’’符號關閉。
範例:
clean:
rm -f *.o

print: *.c
lpr -p $?
touch print
通配符定義變數時並不擴展,例如:
objects = *..o
通配符在定義變數時並不擴展,例如:🎜objects = *..o🎜 objects的值是字串'*.o';但是假如你將objects用於目標,依靠或命令中,擴展會進行。要將objects設定成擴充的內容,使用:🎜objects := $(wildcard *.o)🎜3.3.1.通配符的缺陷🎜這是一個使用通配符的例子,但結果不是你所期望的。假設可執行檔'foo'是從目前目錄中的所有'.o'檔案產生的:
objects = *.o foo : $(objects)
cc -o foo $(CFLAGS) $(objects)
objects變數的值是字串'*.o'。通配符擴展在規則’foo’中進行,於是所有存在的’.o’檔案成為’foo’的依靠而且在需要時重新編譯。
但如果刪除了所有的’.o’檔案呢?當通配符不匹配任何文件時,一切都保持原樣:則'foo'依靠於一個叫做'*.o'的文件;由於這個文件不大可能存在,'make'程序會報告一個無法生成'*.o '文件的錯誤,這不是期待的結果。
實際上可以用通配符獲得期望結果,但是需要複雜的技術,包括’wildcard’函數和字串替換函數。
3.3.2.wildcard函數
通配符會自動在規則中進行。但是在變數賦值的和函數的參數中通配符不會擴展,假如在這些情況下需要通配符擴展,必須使用’wildcard’函數。語法如下:
$(wildcard PATTERN...)
這個在makefile任何地方出現的字串,會被匹配任何一個文件名格式的以空格隔開的現有文件列表替換。假如沒有任何檔案符合一個模式,這個模式從’wildcard’的輸出中忽略,注重,這和上述的通配符的處理是不一樣的。
'wildcard'函數的一個功能是找出目錄中所有的'.c'檔案:
$(wildcard *.c)
可以透過替換後綴'.c'為'.o'從C檔案清單得到目標文件的列表:
$(patsubst %.c,%.o,$(wildcard *.c))
這樣,上節中的makefile改寫為:
objects := $(patsubst %.c,%.o,$ (wildcard *.c)) foo : $(objects)
cc -o foo $(objects)
這個makefile利用了編譯C程式的隱含規則,所以不需要對編譯寫出明確的規則。 (’:=’是’=’的變體)
注重:’PATTERN’是大小寫敏感的。
3.4.目錄搜尋
對於大的系統,通常將來源檔案和目標檔案放在不同的目錄中。目錄搜尋功能可以讓make自動在多個目錄中搜尋依靠文件,當你將文件重新分佈是,不需要改變規則,更改搜尋路徑即可。
3.4.1.‘VPATH’
make變數’VPATH’列出make應當搜尋的目錄清單。很多情況下,目前目錄不包含依賴文件,’VPATH’描述一個對所有文件的搜尋列表,包含那些是規則的目標的文件。
假如一個目標或依靠檔案在目前目錄中沒找到的話,’make’在’VPATH’中列出的目錄中尋找同名的檔案。如果找到的話,那個檔案變成依靠檔案;規則可以像這些檔案在當前目錄中一樣來使用他們。
在’VPATH’變數中,目錄名稱以冒號或空格隔開;目錄列出的順序決定make查找的順序。 (註:在pSOSystem 2.5移植到Win32的GNU make目錄名必須使用分號隔開,以下均簡稱Win32 GNU make)。舉例說明: VPATH = src:../headers 則規則
foo.o : foo.c 
被解釋為
foo.o : src/foo.c
假設'foo.c'在當前目錄中不存在,在' src'目錄中可以找到。
3.4.2.選擇性搜尋
與’VPATH’變數相似但更具選擇性的是’vpath’指令(注重是小寫),可以指定對於符合特定模式檔案的查找路徑。這樣可以為不同類型的檔案指定不同的搜尋路徑。
'vpath'指令共有三中形式:
10.'vpath PATTERN DirectorIES'

為符合PATTERN的檔案名稱指定搜尋路徑DIRECTORIES,目錄的分隔和'VPATH'的相同
11.'vpath PATTERN'
清除為符合PATTERN的檔案名稱指定的搜尋路徑
12.'vpath'
清除所有先前用'vpath'指定的搜尋路徑
'vpath'的模式是包含'%'的字串:這個字串必須符合需要搜尋的依靠檔案名,'%'字元匹配0個或多個任意字元。例如:’%.h’符合任何以’.h’結尾的檔案(假如沒有%,則PATTERN必須和依靠檔案完全一致,這種用法不太多)。
噹噹前目錄中不存在依賴文件時,假如’vpath’中的PATTERN匹配依靠文件名,則指令中DIRECTORIES列出的目錄和’VPATH’中同樣處理。舉例:
vpath %.h ../headers
告訴make在目前目錄中未找到的’.h’檔案在../headers目錄中尋找。
假如多個’vapth’的模式匹配依靠檔案名,make將逐一處理,在所有指定的目錄中搜尋。 Make依照’vapth’在makefile中的次序;來處理它們,多個相同模式的’vapth’是互相獨立的。
vpath %.c foo
vpath % blish
vpath %.c bar
將按照’foo’,‘blish’,’bar’的次序查找’.c’檔。而
vpath %.c foo:bar
vpath % blish
按照’foo’,’bar’,’blish’的順序搜尋。
3.4.3.使用自動變數
目錄搜尋的結果並不會改變規則中的命令:命令按原樣被執行。因此,必須寫出與目錄搜尋功相適應的指令。這可以透過使用’$^’這樣的自動變數來完成。 ’$^’表示規則中的所有依賴文件,包含它們所在的目錄名(參見目錄搜尋);’$@’表示目標。例如:
foo.o : foo.c
cc -c $(CFLAGS) $^ -o $@
通常情況下,依靠文件也包含頭文件,但命令中並不提及這些文件:變量'$VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc –c $(CFLAGS) $3.4.4.目錄搜尋和隱含規則
使用'VPATH'和'vpath'指定目錄搜尋也會影響隱含規則。例如:檔案'foo.o'沒有明確規則,make會考慮隱式規則:假如'foo.c'存在則編譯它;假如這個檔案不存在,則在對應的目錄中尋找;假如'foo.c '在任一的目錄中存在,則C編譯的隱式規則被應用。
隱式規則的命令使用自動變數通常是必要的,這樣無需其它努力即可以使用目錄搜尋得到的檔案名稱。
3.5.PHONY目標
Phony目標並非實際的檔案名稱:只是在明確要求時執行命令的名字。有兩種理由需要使用phony目標:避免和同名檔案衝突,改善效能。
假如編寫一個規則,並不產生目標文件,則其命令在每次make該目標時都執行。例如:
clean:
rm *.o temp
因為’rm’指令並不產生’clean’文件,則每次執行’make clean’的時候,該指令都會執行。假如目錄中出現了’clean’文件,則規則失效了:沒有依靠文件,文件’clean’始終是最新的,命令永遠不會執行;為避免這個問題,可使用’.PHONY’指明該目標。如:
.PHONY : clean
這樣執行’make clean’會無視’clean’文件存在與否。
已知phony目標並非是由其它文件產生的實際文件,make會跳過隱含規則搜尋。這就是聲明phony目標會改善效能的原因,即使你並不擔心實際檔案存在與否。完整的例子如下:
.PHONY : clean
clean :
rm *.o temp
phony目標不應是真正目標檔案的依賴。假如這樣,每次make在更新此檔案時,指令都會執行。只要phony目標不是真正目標的依靠,規則的命令只有在指定此目標時才執行。
Phony目標可以有依靠關係。當一個目錄中有多個程式是,將其放在一個makefile中會更方便。因為缺省目標是makefile中的第一個目標,通常將這個phony目標叫做'all',其依靠文件為各個程序:
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2 : prog2.o
cc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
cc -o prog3 prog3.o sort. o
這樣,使用'make'將可以將三個程式都生成了。
當一個phony目標是另一個的依靠,其作用相當於子程序,例如:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :rm *.oo. diff
3.6.FORCE目標
當規則沒有依靠關係也沒有命令,而且其目標不是存在的檔名,make認為此規則運行時這個目標總是被更新。這意味著假如規則依靠於此目標,其命令總是被執行。
clean: FORCE
rm $(objects)
FORCE:
例中目標’FORCE’滿足這種非凡條件,這樣依靠於它的目標’clean’被強制執行其命令。名字’FORCE’沒有非凡意義,只不過通常這樣用而已。這種方式使用’FORCE’和’.PHONY : clean’效果相同。使用’.PHONY’更明確高效,擔不是所有的’make’都支援;這樣許多makefile中使用了’FORCE’。
3.7.空目標
空目標(empty target)是phony目標的變種:用來執行明確請求的一個動作。和phony目標不同的是:這個目標文件可以真實存在,擔文件的內容無關緊要,通常是空的。空目標檔案的目的是利用其最後修改時間來記錄命令最近一次執行的時間,這是透過使用’touch’命令更新目標檔案來達到的。
print: foo.c bar.c
lpr -p $?
touch print
利用這條規則,執行'make print'時假如自上次'make print'之後任一文件改變了,'lpr'命令會執行。自動變數’$?’是為了只印出那些變化了的檔案。
3.8.內建的非凡目標
某些名字作為目標存在時有非凡意義。
13..PHONY 該目標的依靠被認為是phony目標,處理這些目標時,命令無條件被執行,不管文件名是否存在及其最後修改時間

14..SUFFIXES 該目標的依靠被認為是一個後綴列表,在檢查後綴規則時使用
15..DEFAULT 此目標的規則被使用在沒有規則(明確的或隱含的)的目標上。假如'DEFAULT'命令定義了,則對所有不是規則目標的依靠文件都會執行該組命令
16..PRECIOUS 該目標的依靠文件會受到非凡對待:假如make被kill或命令的執行被中止,這些目標並不刪除;而且假如該目標是中間文件,在不需要時不會被刪除。可以將隱含規則的目標模式(如%.o)做為’.PRECIOUS’的依賴文件,這樣可以保存這些規則產生的中間文件。
17..INTERMEDIATE 該目標的依靠文件被當作中間文件;假如該目標沒有依靠文件,則makefile中所有的目標文件均被認為是中間文件。
18..IGNORE 在執行該目標的依靠規則的命令時,make會忽略錯誤,此規則本身的命令沒有意義。假如該規則沒有依靠關係,表示忽略所有命令執行的錯誤,這種用法只是為了向後兼容;由於會影響到所有的命令,所以不是非凡有用,推薦使用其它更有選擇性忽略錯誤的方法。
19..SILENT 在執行該目標的依靠規則的命令時,make並不打印命令本身。該規則的命令沒有意義。在’.SILIENT’沒有依靠關係時,表示執行makefile中的所有指令都不會列印,該規則只是為了向後相容提供的。
20..EXPORT_ALL_VARIABLES 只是作為一個目標存在,指示make將所有變數輸出到子程序中。
定義的隱含規則的後綴作為目標時,也認為它是非凡目標;兩個後綴的連接也是一樣,例如’.c.o’。這些目標是後綴規則,一中定義隱式規則的過時方法(但仍廣泛使用)。字尾通常以’.’開始,所以非凡目標也以’.’開始。
3.9.一個規則多個目標
一條有多個目標的規則和寫多條規則,每條一個目標作用是等同的。同樣的命令應用於所有目標,但其效用會因將實際目標以’$@’代替而不同。規則中所有目標的依靠關係都是一樣的。
這在兩種情況下有用:
★只有依靠關係,不需要命令。例如:
kbd.o command.o files.o: command.h
21.所有的目標相同的命令。指令不需要完全相同,因為在指令中可以使用'$@':
bigoutput littleoutput : text.g
generate text.g -$(subst output,,$@) > $@

bigoutput : text.g
generate text.g -big > bigoutput
littleoutput : text.g
generate text.g -little > littleoutput
等同。這裡假設程式’generate’產生兩種輸出:一種使用’-big’選項,一種使用’-little’選項。假如想像使用’$@’變化指令那樣來變化依靠關係,不能透過多目標的普通規則實現,但是可以透過模式規則來實現。
3.10.一個目標多條規則
一個文件可以是多條規則的目標,所有規則的依靠關係被合併。假如目標比任一個依靠文件舊,命令被執行。
一個檔案只能有一組指令執行。假如多個規則對於同一個文件都給出了命令,make使用最後一組並打印錯誤信息(非凡情況:假如文件名以'.'開始,並不打印錯誤信息,這一點是為了和其它make兼容)。沒有任何理由需要將makefile寫成這樣,這是make給出錯誤訊息的理由。
一條只有依靠關係的附加規則可以一次給出許多文件的附加依靠文件。例如'objects'變數表示系統中編譯器的所有輸出.,說明當'config.h'更改時所有檔案必須重做的簡單方法如下:
objects = foo.o bar.o
foo.o : defs. h
bar.o : defs.h test.h
$(objects) : config.h
不用改變實際目標檔案產生的規則,這條規則可以在需要增刪附加的依靠關係時插入或提出。另一個訣竅是附加的依賴關係可以用變數表示,在make執行時,可以給變數賦值:
extradeps=
$(objects) : $(extradeps)
當指令`make extradeps=foo.h'執行時會認為'foo.h'是每個目標文件的依靠文件,但簡單的'make'命令不是這樣。
3.11.靜態模式規則
靜態模式規則(static pattern rules)可以指定多個目標,並且使用目標名字來建議依靠文件的名字;比普通多目標規則更通用因為不需要依靠關係是相同的:依靠關係必須類似但不需要相同。
3.11.1.語法
TARGETS ...: TARGET-PATTERN: DEP-PATTERNS ...
COMMANDS
...
TARGETS清單指出規則應用的目標,可以包含通配符,於普通規則的目標相同。 TARGET-PATTERN和DEP-PATTERNS來顯示目標的依靠關係如何計算:匹配TARGET-PATTERN的目標從名字中抽出一部分,叫做詞幹(stem),詞幹被替換到DEP-PATTERNS來形成依靠文件名。
每個模式通常包含一個’%’字元。當TARGET-PATTERN符合一個目標時,’%’字元可以符合目標名中的任何部分;這部分即是詞幹,模式的其餘部分必須完全匹配。例如’foo.o’匹配’%.o’,’foo’是詞幹;目標’foo.c’和’foo.out’並不符合這個模式。
目標的依靠檔案名稱透過將DEP-PATTERNS中的’%’替換為詞幹形成:假如依靠模式為’%.c’,在替換詞幹’foo’可以得到’foo.c’。依靠模式中不包含’%’也是合法的,此依靠文件對所有的目標均有效。
假如需要在模式規則中使用'%'字符,必須在其前面加''字符,假如'%'前的''字符是有實際意義的,必須在其前面加'',其它的''不必如此處理。如’the%weird%pattern’在有效的’%’前是’the%weird’,其後是’pattern’。最後的’’保持原樣是因為其並不影響’%’字符。
以下範例從對應的'.c'檔編譯'foo.o'和'bar.o':
objects = foo.o bar.o
$(objects): %.o: %.c
$(CC ) -c $(CFLAGS) $每個目標必須符合目標模式,對於不符合的目標會給予警告。假如列表中只有部分檔案匹配模式,可以使用filter函數移去不匹配的檔案名稱:

files = foo.elc bar.o lose.o $(filter %.o,$(files)): %.o : %.c
$(CC) -c $(CFLAGS) $$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte- compile $範例 `$(filter %.o,$(files))' 結果是 `bar.o lose.o';`$(filter %.elc,$(files))' 的結果是`foo .elc'。以下範例說明'$*'的使用:
bigoutput littleoutput : %output : text.g
generate text.g -$* > $@
命令`generate'執行時,'$*'擴展為詞幹'big'或'little'。
3.11.2.靜態模式規則和隱式規則
靜態模式規則和隱式規則在作為模式規則是具有很多共同點,都有目標模式和構造依靠文件名的模式,不同之處在於make決定何時應用規則的方法。
隱式規則可應用於符合其模式的任何目標,但僅限於沒有指定命令的目標,假如有多條可應用的隱式規則,只有一條被使用,取決於規則的順序。
反之,靜態模式規則適用於規則中明確目標列表,不適用於其它目標且總是適用於指定的每個目標。假如有兩條衝突的規則,而且都有命令,這是一個錯誤。
靜態模式規則比隱式規則優越之處如下:
22.可為一些不能按句法分類,但可以明確列出的文件重載隱式規則
23.不能判定目錄中的精確內容,一些無關的檔案可能導致make適用錯誤的隱式規則;最終結果可能依靠隱式規則的次序。適用靜態模式規則時,這種不確定性是不存在的:規則適用於明確指定的目標。
3.12.雙冒號規則
雙冒號規則(Double-colon rules)的目標後是’::’而不是’:’,當一個目標出現在多條規則中時,其處理和普通規則的處理不同。
當一個目標出現在多個規則中時,所有規則必須是相同類型的:都是普通的或都是雙冒號的。假如是雙冒號,規則之間相互獨立;假如目標需要更新,則規則的命令被執行;結果可能是沒有執行,或者執行了其中一些,或者所有的規則都執行了。
同一目標的雙冒號規則事實是完全孤立的,每條規則被單獨處理,就像不同目標的規則一樣;規則按照在makefile中出現的次序被處理,此類規則真正有意義的是那些於命令執行次序無關的。
這種規則有時比較晦澀不是非凡有用;它提供了一種機制:透過不同依靠文件的更新來對目標進行不同的處理,這種情況很罕見。每個這種規則應提供命令,假如沒有,適用的隱式規則將使用。
3.13.自動產生依靠關係
在makefile中,許多規則都是一些目標檔案依靠於一些頭檔。例如:’main.c’ 透過’#include’使用’defs.h’,這樣規則:
main.o: defs.h
告訴make在’defs.h’變化時更新’main.o’。在程式比較大時,需要寫許多這樣的規則;而且當每次增刪’#include’時,必須小心的更新makefile。許多現代的編譯器可以幫你寫這些規則,通常這是透過編譯器的'-M'選項,例如命令:
cc –M main.c
輸出以下內容:
main.o : main.c defs. h
這樣就不必寫這些規則,有編譯器代勞了。
注重這樣的依靠關係中提及’main.o’,不會被隱式規則認為是中間文件,這意味著這make在使用過它之後不會將其刪除。使用舊的'make'程式時,習慣做法是使用'make depend'命令利用編譯器的功能產生依靠關係,該命令會產生一個'depend'檔案包含所有自動產生的依靠關係,然後在makefile中使用' include'將其讀入。
使用GNU的make時,重新產生makefile的功能使得這種做法變得過時:從不需要明確請求更新依靠關係,因為它總是重新產生任何過時的makefile。
自動依靠關係產生建議的做法是對每個原始檔做一個makefile。對每個源文件'NAME.c',有一個makefile 'NAME.d',其中列出了目標文件'NAME.o'依靠的所有文件,這樣在源文件更新時,需要掃描來產生新的依靠關係。例子是一個從'NAME.c'產生依賴關係文件'NAME.d'的模式規則:
%.d: %.c
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $sed '''s/($*).o[ :]*/1 $@/g''' > $@'
-e選項是當$(CC)指令失敗時(exit狀態非0), shell馬上退出。通常shell的回傳值是管道中最後一條指令(sed)的回傳值,這樣make不會專注到編譯器出錯。
使用GNU的C編譯器時(gcc),可以用’-MM’選項來取代’-M’選項,這樣省略系統頭檔的依賴關係。 'sed'指令的目的是將
main.o : main.c defs.h
轉換為
main.o main.d : main.c defs.h
這樣使得每個'.d'文件依靠於'. o'文件對應原始檔和頭文件,make則可以在原文間或頭檔變化時更新依賴關係檔。
假如定義了產生'.d'檔案的規則,可以使用'include'指令來讀入所有的檔案:
sources = foo.c bar.c
include $(sources:.c=.d)
例中使用替換變數來將來源檔案清單' foo.c bar.c'轉換為依賴關係檔案的清單。因為’.d’檔案和其它檔案一樣,不需要更多工作,make會在需要時重新產生它們。
4.寫指令
規則的指令是由一一執行的shell指令組成。除了以分號隔開寫在依靠關係後的命令,每個命令行必須以tab字元開始空白行和註解行可以出現在命令列中,處理時被忽略(注重:以tab字元開始的空行不是'空'行,是一條空命令)。
可以在命令中使用任何程序,但這些程序是由$(SHELL)來執行的。
4.1.回顯
通常make印出要執行的命令,稱之為回顯,這和親自敲命令的現像是一樣的。當行之前有’@’字元時,指令不再回顯,字元’@’在傳遞給shell前丟棄。典型的用法是只對列印指令有效,例如'echo'指令:
@echo About to make distribution files
當make使用'-n'或'—just-print'選項時,顯示要發生的一切,但不執行命令。只有在這種情況下,即使命令以’@’開始,命令列仍然顯示出來。這個選項對查看make實際要執行的動作很有用。
‘-s’或’—silent’選項阻止make所有回顯,就像所有命令以’@’開始一樣;一條沒有依靠關係的’.SILENT’規則有相同的作用,但是’@’更加靈活。

4.2.執行
在需要執行指令更新目標時,make為每一行建立一個子shell來執行。這意味著諸如為進程設定局部變數的shell命令’cd’(改變進程的當前目錄)不會影響以後的命令。假如需要'cd'影響下一個指令,將它們放在一行上用分號隔開,這樣make認為是一條指令傳遞給shell程式(注重:這需要shell支援):
foo : bar/lose
cd bar ; gobble lose > ../foo
另一個形式使用續行符:
foo : bar/lose
cd bar; 
gobble lose > ../foo
shell程式的名字是透過'SHELL'變數來取得的。
(*UNIX)不像大多數變量,'SHELL'變量不是透過環境來設定的(即需要在makefile中設定),因為'SHELL'環境是個人選擇的,假如不同人的選擇會影響makefile的功能的話,這樣很糟糕。
4.3.並行執行
GNU make可以一次執行幾個指令。通常make一次執行一條指令,等待其返回,再執行下一則。使用’-j’或’—jobs’可以同時執行多個指令。假如’-j’後梗一個正數,表示一次可以執行的指令條數;假如’-j’之後沒有參數,則不限制可執行的指令數。缺省的數量是一。
一個討厭的問題是假如同時執行多個命令,它們的輸出會混在一起;另一個問題是兩個進程不能從同一個設備獲得輸入。
4.4.錯誤
每條shell指令回傳時,make會檢查其回傳狀態。如果指令執行成功,則下一條指令被執行,最後一條指令執行完後,規則執行結束。
如果有錯誤(返回非0狀態),make放棄目前規則,也可能是所有規則。
有時候命令執行錯誤並不是問題,例如使用’mkdir’指令確保目錄存在:假如目錄一存在,則’mkdir’會報告錯誤,但仍希望make繼續。
要忽略命令的錯誤,在命令之前使用'-'字符,'-'字符在傳遞給shell之前被丟棄:
clean:
-rm -f *.o
假如使用'-i'或'—ignore -errors'選項,make會忽略所有指令產生的錯誤;一條沒有依賴關係的'.IGNORE'規則有相同的作用,但'-'更靈活。
在忽略錯誤時,make將錯誤也認為是成功,只是通知你指令的退出狀態和和錯誤被忽略。假如make並未告知忽略錯誤,在錯誤發生時,表明該目標不能成功更新,直接或間接依靠於此的目標當然也不能成功;這些目標的命令不會被執行,因為其先決條件不滿足。
通常make會立即以非0狀態退出。然而,如果給定’-k’或’—keep-going’選項,make在退出前會處理其它的依靠關係,進行必要的更新。例如,在編譯一個目標檔案碰到錯誤,’make -k’會繼續編譯其它的目標檔。
通常認為你的目的是更新指定的目標,當make知道這是不可能時,會立即報告失敗;'-k'選項指示真正目的是測試更新程式的更多可能性:在編譯之前找出更多不相關的問題。
假如指令失敗了,假設它更新的目標文件,這個文件是不完整的不能使用-至少不是完全更新的。但檔案的最後修改時間顯示停已經是最新的,下一次make運行時,不會再更新這個檔案。這種情況和命令被kill相同;則通常情況下在命令失敗時將目標刪除是正確的;當’.DELETE_ON_ERROR’是目標時make幫你做這件事。雖然你總是希望make這麼做,但這不是過去的習慣;所以必須明確要求make這樣做(其它的make自動這樣做)。
4.5.中斷make
假如make執行指令時碰到錯誤,可能會刪除指令更新的目標檔: make檢查檔的修改時間是否改變。刪除目標的目的是確保make下次執行時重新產生它。為什麼要這樣做?假設在編譯器執行時按了’Ctrl-c’,此時編譯器寫入會產生目標檔’foo.o’。 'Ctrl-c' kill了編譯器,留下一個不完整的文件,但它的修改時間比源文件'foo.c'新;此時make也受到'Ctrl-c'信號刪除這個不完整的文件,如果make不這樣做,下次make運行時認為'foo.o'不需要更新,會在連結時出現希奇的錯誤。
可以使用’.PRECIOUS’規則來防止目標檔案被刪除。在make更新目標時,會偵測其是否為’.PRECIOUS’的依靠,決定在指令出錯或中斷時是否刪除該目標。假如你希望目標的更新是原子操作,或是用來記錄修改時間,或必須一直存在防止其它類型的錯誤,這些理由使得你必須這樣做。
4.6.遞歸使用
遞歸使用make就是在makefile中使用make指令。這個技巧在你將一個大系統分解為幾個子系統,為每個自系統提供一個makefile時有用處。例如有一個子目錄'subdir'中有自己的makefile,希望make在自目錄中運行,可以這樣做:
subsystem:
cd subdir; $(MAKE)

subsystem:
$(MAKE) -C subdir
可以照抄這個;例子來遞歸使用make
4.6.1.'MAKE'變數
遞歸的make必須使用'MAKE'變量,不是顯式的make指令:
subsystem:
cd subdir; $(MAKE)
該該變數的值是被呼叫的make的名字。在命令中使用'MAKE'有非凡的功能:它改變了`-t' (`--touch'), `-n' (`--just-print')和`-q' (`--question ')選項的意思。使用上例來考慮'make –t'命令('-t'選項將目標標記為最新但不運行命令),更加'-t'選項的功能,該命令將創建一個'subsystem'文件,實際希望的操作是運行'cd subdir; make –t';但這會執行指令,與'-t'的原意不符。
這個非凡功能做了期望的工作。當命令列包含變數’MAKE’時,選項’-t’,’-n’和’-q’並不適用。不管這些導致不會執行指令的標誌,包含’MAKE’變數的指令總是會執行。正常的’MAKEFLAGS’機制將這些標誌傳遞到子make,這樣列印指令的請求被傳播到子系統中。
4.6.2.傳遞變數到子make
上級(top-level)make中的變數可以明確地透過環境傳遞到子make。在子make中,這些變數被缺省定義,但不會重載子makefile中的定義除非使用’-e’選項。
為向下傳遞,或輸出變量,make在執行命令時將其加入環境變數;子make,可以使用環境變數來初始化變數表。除非明確要求,make只輸出初始環境中或命令列設定的變數且變數名只由字母,數字和底線組成。有些shell不能處理有其它字元的環境變數。
非凡變數’SHELL’,’MAKEFLAGS’總是輸出,假如’MAKEFILE’變數有值,也會輸出。 Make自動透過’MAKEFLAGS’來輸出命令列定義的變數。
假如想要輸出特定變量,使用'export'指令:
export VARIABLE ...
假如要阻止輸出一個變量,使用'unexport'指令:

unexport VARIABLE ...
為方便起見,可以在定義變量時輸出它:
export VARIABLE = value

VARIABLE = value
export VARIABLE
作用相同。
假如要輸出所有的變量,使用’export’指令本身就可以了。
變數'MAKELEVEL'在一級一級傳遞時會改變,這個變數的值是表示嵌套層數的字串,頂級'make'是,變數的值為'0';子make的值為'1 ';子子make的值為'2',依此類推。
‘MAKELEVEL’的用途是在條件指令中測試它,這樣寫出在遞歸運行時和直接運行時表現不同的makefile。
以下內容拷貝自GNU Make Manual
5.命令列參數
`-b'
`-m'
These options are ignored for compatibility with other versions of
`make'. `-C DIR'rectory--`. =DIR'
Change to directory DIR before reading the makefiles. If multiple
`-C' options are specified, each is interpreted relative to the
previous one: `-C / -C etc to is equivalent/cf-C valent/cc to valp '. This is
typically used with recursive invocations of `make' (*note
Recursive Use of `make': Recursion.). `-d'
`--debug'
Print debugging information in addition to mal process
debugging information says which files are being considered for
remaking, which file-times are being compared and with what
results, which files actually need to be remade,what
results, which files actually need to be remade,what
results, which files actually need to be remade,what
res how `make' decides what to do. `-e'
`--environment-overrides'
Give variables taken from the environment precedence over
variables from makefiles. *Note Variables from the Environment precedence:variables from makefiles. *Note Variables from the pviariables `fronment.
`--file=FILE'
`--makefile=FILE'
Read the file named FILE as a makefile. `-h'
`--help'
Remind you of the options that `make'--help'
Remind you of the options that `make' underunder .
`-i'
`--ignore-errors'
Ignore all errors in commands executed to remake files. `-I DIR'
`--include-dir=DIR'
Specifies a directory Dmed search forfilepake in . If several `-I' options are
used to specify several directories, the directories are searched
in the order specified. `-j [JOBS]'
`--jobs=[JOBS]'
. commands) to run simultaneously.
With no argument, `make' runs as many jobs simultaneously as
possible. If there is more than one `-j' option, the last last. -keep-going'
Continue as much as possible after an error. While the target that
failed, and those that depend on it, cannot be remade, the other
de dencies of the pendencies 是 s​​an scan socess . [LOAD]'
`--load-average[=LOAD]'
`--max-load[=LOAD]'
Specifies that no new jobs (commands) should be started if there
are other jobs running and the load average is at least LOAD (a
floating-point number). With no argument, removes a previous load
limit. *Note Parallel Execution: Parallel. `-n'
`--just-print'
`--dry-`--dry- run'
`--recon'
Print the commands that would be executed, but do not execute them.
`-o FILE'
`--old-file=FILE'
`--assume-old=FILE'
Do not remake the file FILE even if it is older than its
dependencies, and do not remake anything on account of changes in

FILE. Essentially the file is treated as very old and 洛`--print-data-base'
Print the data base (rules and variable values) that results from
reading the makefiles; then execute as usual or as otherwise
specified. This also prints the version information 單詞 `. v' switch (see below). To print the data base without trying to
remake any files, use `make -p -f /dev/null'. `-q'
`--question'
"Question mode". Do not run any commands, or print anything; just
return an exit status that is zero if the specified targets are
already up to date, one if any remaking is required, oralready up to date, one if any remaking is required, oralready an en .
`--no-builtin-rules'
消除使用內建隱式規則。您仍然可以透過編寫
模式規則來定義自己的規則。 `-r' 選項也會清除後綴規則的預設字尾清單
。但是您仍然可以使用 `.SUFFIXES' 的
規則定義自己的後綴,然後定義自己的後綴規則。 `-s'
`--靜音'
`--安靜'
靜音操作;執行時不列印指令。
`-S'
`--no-keep-going'
`--stop'
取消 `-k' 選項的效果。這從來沒有必要
除非在遞歸`make'中,其中`-k'可能透過`MAKEFLAGS'從頂級`make'繼承,或者如果您在
環境中的`MAKEFLAGS'中設定了`-k'。 `-t'
`--touch'
觸摸檔案(將它們標記為最新,而不真正更改它們)
而不是運行它們的命令。這用於假裝
命令已完成,以欺騙未來對
`make'的調用。 `-v'
`--version'
列印 `make' 程式的版本以及版權、作者清單
以及無保證的通知;然後退出。
`-w'
`--print-directory'
在執行 makefile 之前和之後列印一條包含工作目錄的訊息。這對於追蹤遞歸“make”命令的複雜巢狀中的錯誤可能很有用。 `--no-print-directory'
在`-w'下停用工作目錄的列印。當“-w”自動開啟但您不想看到額外的訊息時,此選項
很有用。 `-W FILE'
`--what-if=FILE'
`--new-file=FILE'
`--assume-new=FILE'
假裝目標 FILE 剛剛被修改。當與“-n”標誌一起使用時,這會向您顯示如果您修改該檔案會發生什麼。如果沒有`-n',它幾乎與
在運行`make'之前在給定文件上運行`touch'命令相同,
除了修改時間僅在`make'的
想像中改變。 `--warn-undefined-variables'
每當 `make' 看到對
未定義變數的引用時發出警告訊息。當您嘗試偵錯以複雜方式使用變數的 makefile 時,這會很有幫助。 6.參考
6.1.指令
`define VARIABLE'
`endef'
定義多行遞歸擴充變數。

*注意序列::. `ifdef 變數'
`ifndef 變數'
`ifeq (A,B)'
`ifeq "A" "B"'
`ifeq 'A' 'B''
`ifneq ( A,B)'
`ifneq "A" "B"'
`ifneq 'A' 'B''
`else'
`endif'
有條件地評估makefile 的一部份。 `include FILE'
包含另一個 makefile。 `override VARIABLE = VALUE'
`override VARIABLE := VALUE'
`override VARIABLE += VALUE'
`override Define VARIABLE'
`endef'

`export'
告訴`make'預設將所有變數匯出到子進程。 `export VARIABLE'
`export VARIABLE = VALUE'
`export VARIABLE := VALUE'
`export VARIABLE += VALUE'
`unexport VARIABLE'
告訴 `make' 是否將特定變數匯出到子

`vpath PATTERN PATH'
指定符合`%'模式的檔案的搜尋路徑。
*注意`vpath'指令:選擇性搜尋。 `vpath PATTERN'
刪除先前為 PATTERN 指定的所有搜尋路徑。 `vpath'
刪除先前在任何 `vpath'
指令中指定的所有搜尋路徑。
6.2.函數
`$(subst FROM,TO,TEXT)'
將 TEXT 中的 FROM 替換為 TO。 `$(patsubst PATTERN,REPLACMENT,TEXT)'
將文字中與 PATTERN 相符的單字替換為 REPLACMENT。 `$(strip STRING)'
從 STRING 中刪除多餘的空白字元。 `$(findstring FIND,TEXT)'
在 TEXT 定位 FIND。 `$(filter PATTERN...,TEXT)'
選擇 TEXT 中與 PATTERN 單字之一相符的單字。 `$(filter-out PATTERN...,TEXT)'
選擇 TEXT 中*不*符合任何 PATTERN 單字的單字。 `$(sort LIST)'
依字典順序對 LIST 中的單字進行排序,刪除重複。 `$(dir NAMES...)'
提取每個檔案名稱的目錄部分。 `$(notdir NAMES...)'
提取每個檔案名稱的非目錄部分。 `$(suffix NAMES...)'
提取每個
檔案名稱的後綴(最後一個`.'及其後面的字元)。 `$(basename NAMES...)'
提取每個檔案名稱的基本名稱(不含後綴的名稱)。 `$(addsuffix SUFFIX,NAMES...)'
將 SUFFIX 附加到 NAMES 中的每個單字。 `$(addprefix PREFIX,NAMES...)'
在 NAMES 中的每個單字前面加上 PREFIX。 `$(join LIST1,LIST2)'
連接兩個並行的單字清單。 `$(單字 N,TEXT)'
提取 TEXT 的第 N 個單字(單源)。 `$(words TEXT)'
計算 TEXT 中的單字數。 `$(firstword NAMES...)'
提取 NAMES 的第一個字。 `$(wildcard PATTERN...)'
尋找與 shell 檔案名稱模式相符的檔案名稱(*不是*`%'
模式)。 `$(shell COMMAND)'
執行 shell 指令並傳回其輸出。 `$(origin VARIABLE)'
回傳一個字串,描述如何定義 `make' 變數 VARIABLE
。 `$(foreach VAR,WORDS,TEXT)'
使用綁定到 WORDS 中每個單字的 VAR 計算 TEXT,並

連接結果。
6.3.自動變數
`$@'
目標的檔案名稱。 `$%'
當目標是歸檔成員時,目標成員名稱。 `$第一個依賴項的名稱。 `$?'
比目標更新的所有依賴項的名稱,
它們之間有空格。對於存檔
成員的依賴項,僅使用命名的成員
,並且它們之間有空格。對於歸檔
成員的依賴項,僅使用名為的成員
`$^'
`$+'
所有依賴項的名稱,它們之間有空格。對於作為存檔成員的
依賴項,僅使用指定的成員
。 `$^' 的值忽略重複的依賴關係,而 `$+' 保留它們並保留它們的順序。 `$*'
隱式規則符合`$(@D)'的詞幹
`$(@F)'
`$@'的目錄部分和目錄內檔案部分。 `$(*D)'
`$(*F)'
`$*'的目錄部分和目錄內檔案部分。 `$(%D)'
`$(%F)'
`$%'的目錄部分和目錄內檔案部分`$(`$( `$`$(^F)'
`$^'的目錄部分和目錄內文件部分`$(+D)'
`$(+F)'
目錄`$+' 的目錄部分和目錄內檔案部分`$(?D)'
`$(?F)'
`$?' 的目錄部分和目錄內檔案部分
6.4.非凡變數
`MAKEFILES'
每次呼叫`make'時都會讀取Makefiles。 `VPATH'
目前目錄中找不到的檔案的目錄搜尋路徑。 `SHELL'
系統預設指令解釋器的名稱,通常是
`/bin/sh'。您可以在 makefile 中設定 `SHELL' 來變更用於執行指令的
shell。 
`MAKE'
呼叫 `make' 的名稱。在
指令中使用此變數具有特殊意義。 `MAKELEVEL'
遞歸級數(子`make's)。 `MAKEFLAGS'
賦予`make'的標誌。您可以在環境或 makefile 中設定它來設定標誌。 `SUFFIXES'
`make' 讀取任何 makefile 之前的預設後綴清單。 

以上就是makefile規則的內容,更多相關文章請關注PHP中文網(www.php.cn)!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn