GNU Make User Manual

GNU Make 使用手冊
Version 3.79
繁體版更新日期 2006/08/30
校稿 ChanningLan
目錄
1 make概述
1.1 怎樣閱讀本手冊
1.2 問題和BUG
2.1 規則的格式
2.2一個簡單的Makefile檔案
2.3mke處理Makefile檔案的過程
2.4使用變數簡化Makefile檔案
2.5讓make推斷命令
2.6另一種風格的Makefile檔案
2.7在目錄中刪除檔案的規則
3编寫Makefile文件
3.1Makefile檔案的內容
3.2Makefile檔案的命名
3.3引入(include)其它的Makefile檔案
3.4變數MAKEFILES
3.5Makefile檔案重新生成的過程
3.6重載其它Makefile檔案
3.7make讀取Makefile檔案的過程
4 編寫規則
4.1規則的語法
4.2在檔案名中使用萬用字元
4.2.1萬用字元例子
4.2.2使用萬用字元的常見錯誤
4.2.3函數wildcard
4.3在目錄中搜尋先決條件
4.3.1VPATH:所有先決條件的搜尋路俓(stem)
4.3.2vpath指令
4.3.3目錄搜尋過程
4.3.4編寫搜尋目錄的shell命令
4.3.5目錄搜尋和隱含規則
4.3.6連接庫(Link Libraries)的搜尋目錄
4.4假想(phony)目標
4.5沒有命令或先決條件的規則
4.6使用空目錄檔案記錄事件
4.7內建的特殊目標名
4.8具有多個目標的規則
4.9具有多條規則的目標
4.10靜態樣式規則
4.10.1靜態樣式規則的語法
4.10.2靜態樣式規則和隱含規則
4.11雙冒號規則(::)
4.12自動生成先決條件
5 在規則中使用命令
5.1命令回顯
5.2執行命令
5.3並行執行
5.4命令錯誤
5.5中斷或關閉make
5.6遞迴make
5.6.1變數MAKE的工作模式
5.6.2與子make通訊的變數
5.6.3與子make通訊的選項
5.6.4`--print-directory'選項
5.7定義固定次序命令
5.8使用空命令
6
使用變數
6.1變數引用基礎
6.2變數的兩個特色
6.3變數進階引用技術
6.3.1替換引用
6.3.2巢狀變數引用
6.4變數取值
6.5設定變數
6.6為變數值附加文字(text)
6.7撤銷(override)指令
6.8定義多行變數
6.9環境變數
6.10特定目標變數的值
6.11特定樣式變數的值
7 Makefile檔案的條件語句
7.1條件語句的例子
7.2條件語句的語法
7.3測試標誌的條件語句
8 文字(text)轉換函數
8.1函數呼叫語法
8.2字元串替換和分析函數
8.3檔案名函數
8.4函數foreach
8.5函數if
8.6函數call
8.7函數origin
8.8函數shell
8.9控制Make的函數
9
執行
make
9.1指定Makefile檔案的參數
9.2指定最終目標的參數
9.3代替執行命令
9.4避免重新編譯檔案
9.5變數重載
9.6測試編譯程式
9.7選項概要
10 使用隱含規則
10.1使用隱含規則
10.2隱含規則目錄
10.3隱含規則使用的變數
10.4隱含規則鏈
10.5定義與重新定義樣式規則
10.5.1樣式規則簡介
10.5.2樣式規則的例子
10.5.3自動變數
10.5.4樣式匹配
10.5.5萬用規則
10.5.6刪除隱含規則
10.6定義最新類型的預設規則
10.7舊式的後置規則(suffix rule)
10.8隱含規則搜尋算法
11 使用make更新資料庫檔案
11.1資料庫成目標
11.2資料庫成目標的隱含規則
11.2.1更新資料庫成
11.3使用檔案的危險
11.4資料庫檔案的後置規則(suffix rule)
12 GNU make的特
13 不相失去的特
14 Makefile檔案
14.1makefile檔案的通用
14.2makefile檔案的工具
14.3指定命令的變數
14.4安裝路俓(stem)變數
14.5用目標
14.6安裝命令分類
15快速
16make生的錯誤
17複雜的Makefile檔案例子 附錄 名詞翻對照表
1 Make 概述
Make 自動決定一個程式中哪些檔案要重新編譯發布重新編譯它的命令。本版本GNU Make使用手冊 Richard M. Stallman and Roland McGrath編著,是從Paul D. Smith寫的V3.76版本發展 GNU Make符合IEEE Standard 1003.2-1992 (POSIX.2) 6.2章節的規定
為C語程式更具有代表性,以我們的例子基C語程式,但Make並不是僅僅能夠處理C語程式可以處理 那些編譯器能夠在Shell命令執行的的種語的程式實上,GNU Make不僅僅限於程式可以適於任何如果 檔案變化導致檔案必須更新的任務。 如果要使用Make,必須先寫一個為Makefile的檔案,該檔案述程式中個檔案之間相互係,且提供每一個
檔案的更新命令在一個程式中,可執行程式檔案的更新依靠OBJ檔案,而OBJ檔案是由源檔案編譯得來旦合適的Makefile檔案,每次更些源檔案在shell命令簡單的 make
就能執行所有的要的重新編譯任務。Make程式根據Makefile檔案中的數個檔案更時間戳決定哪些檔案
要更新。對於這些需要更新的檔案Make基Makefile檔案發布命令進行更新進行更新的模式由提供的命令行參數
控制具體請看執行Make章節。
1.1怎樣閱讀本手冊
如果您現下對Make一者您僅需了解對make 的介紹,請查前幾章內容,略過後章節。前幾 章節是普通介紹內容章節是具體的專業、技術內容。 如果您對其它Make程式熟悉,請參閱GNU Make的特不相失去的特點部GNU Make的特點這章列 出了GNU Makemake程式的展開,不相容和失去的特章解釋了其它Make程式有的特徵而GNU Make缺乏原因。 對於快速瀏覽者,請參閱選項概要、快速和內建的特殊目標名
1.2問題和BUG
如果您有關GNU Make的問題或者您認您發現了一個BUG,請向開發者報告;我們不能許諾我們能幹什麼,但 我們會盡力修正報告BUG之前,請確您是否真正發現了BUG,仔細研究文檔後確認是否真按您的指令執
。如果文檔不能清楚告訴您么做,也報告,這是文檔的一個BUG您報告己親修正BUG之前,請把它分離出來,即在使問題暴露前提下儘可能縮小Makefile檔案。然 個Makefile檔案和Make給出精確結果發給我們。同時請說明您希望得到什麼,這可以幫助我們確定問題是否出在文 檔上。
旦您找到一個精確的問題,請給我們發E-mail,我們的E-mail位址是︰ bug-make@gnu.org
件中引入(include)使用的GNU Make的版本號。您可以利用命令‘make—version’得到版本號。同時希望您提 供您機器型號和作業系統類型,如可能話,希望同時提供config.h檔案(該檔案有配置過程)。
2 Makefile檔案介紹
Make程式要一個所的Makefile檔案來告訴干什麼。在多數情況下,Makefile檔案告訴Make怎樣編譯和連接成 一個程式
章我們將討論一個簡單的Makefile檔案,該檔案述怎樣8個C程式檔案和3個檔案編譯和連接成為一個文 字(text)編輯器。Makefile檔案可以同時告訴Make怎樣執行所要的雜亂無章的命令如,清刪除特定的檔案
)。如果詳細、複雜的Makefile檔案例子,請參閱複雜的Makefile檔案例子一章。
make重新編譯個編輯器時,所有動的C語言源檔案必須重新編譯。如果一個檔案,每一個引入(include) 該頭檔案的C語言源檔案必須重新編譯,這才能保證生成的編輯器是所有檔案更新後的編輯器。每一個C語言源
案編譯後生一個對應OBJ檔案,如果一個檔案重新編譯所有的OBJ檔案無論是剛剛編譯得到的或原來編譯得到必須從新連接,形成一個新的執行檔案
2.1 規則的格式
一個簡單的Makefile檔案引入(include)一系列規則”,其樣式如下︰
目標(target): 先決條件(prerequiries)
<tab>命令(command)
目標(target)通常生的檔案的名稱,如;目標可以是執行檔案或OBJ檔案目標也可是一個執行的動作名稱, 諸如‘clean’(詳細內容參閱假想(phony)目標一節)。
先決條件來輸從而產生目標的檔案一個目標常有個先決條件 命令Make執行的動作一個規則可以含有個命令,每個命令一行注意︰每個命令行前面必須是一個Tab
符,即命令行一個字符是Tab這是不小心容易出錯的地方。
通常,如果一個先決條件生變化要規則呼叫命令對相應先決條件和服務進行處理從而更新或建目標。但是 指定命令更新目標的規則並不都需要先決條件如,引入(include)和目標clern’相聯繫的刪除命令的規則沒有 先決條件
規則一般是於解釋怎樣和何時重建特定檔案的,這些特定檔案是這詳盡規則的目標Make需首先呼叫命令先決 條件進行處理而才能或更新目標。當然,一個規則也可以是於解釋怎樣和何時執行一個動作,詳見編寫規 則一章。
一個Makefile檔案可以引入(include)規則以外的其它文字(text),但一個簡單的Makefile檔案僅僅需要引入(include)規則 。雖然真正的規則比這裡展示的例子複雜,但格式卻是完全一樣
2.2一個簡單的Makefile檔案
一個簡單的Makefile檔案,該檔案一個為文字(text)編輯器(edit執行檔案生成,該檔案依靠8個 OBJ檔案.o檔案),依靠8個C程式檔案和3個檔案個例子中所有的C語言源檔案引入(include)defs.h 檔案,但僅僅定義編命令的檔案引入 (include)command.h’頭檔案,僅僅改變編輯器緩沖區低層檔案引入(include)buffer.h’頭檔案
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
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.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 使用Makefile檔案目錄中刪除執行檔案和目標,鍵make clean 在個Makefile檔案例子中目標包括執行檔案editOBJ檔案main.okdb.o’。先決條件C語言源檔案和 C語言頭檔案如‘main.cdef.h實上,每一個OBJ檔案即是目標也是先決條件命令行包括cc -c main.ccc -c kbd.c’。
目標一個檔案時,如果它的一個先決條件生變化目標必須重新編譯和連接。任何命令行的一個 字符必須是‘Tab符,這可以把Makefile檔案中的命令行與其它行分開來。(一定要Make並不知命令 是如何工作的僅僅能向您提供保證目標的合適更新的命令Make的全部工作是當目標要更新時,按照您定的 具體規則執行命令。)
目標clean’不是一個檔案,僅僅是一個動作的名稱。正情況下,在規則中clean’這個動作並執行 目標clean’也不需任何先決條件般情況下,意告訴make執行clean命令,否clean命令永遠
執行。注意這樣的規則不需任何先決條件們存在的目的僅僅是執行一特殊的命令像這些不需要先決條件 僅表動作的目標為假想(phony)目標。詳細內容參見假想(phony)目標參閱命令錯誤可以了解rm或其它命令怎樣 導致make錯誤的
2. make處理makefile檔案的過程
預設情況下,make於第一個目標假想(phony)目標的名稱前.’)。這個目標稱為預設最終目標(即 make最終更新的目標具體內容請看指定最終目標的參數一節)。上節的簡單例子中預設最終目標更新執行檔案edit’,以我們將該規則設為一規則。這旦您給出 命令 make make就會當前目錄的makefile檔案處理一條規則。在本例中,第一條規則連接生成edit’,但在make 全部完成本規則工作之前,必須先處理edit依靠OBJ檔案。這些OBJ檔案按照各自的規則處理更新,每OBJ 檔案的更新規則編譯其檔案重新編譯根據依靠檔案或檔案是否比現存OBJ檔案更’,者OBJ檔 案是否存
其它規則的處理根據的目標是否和預設最終目標的先決條件聯來。如果規則和預設最終目 標無任何這些規則不會執行告訴Make強製執行(如輸入執行make clean命令)。
OBJ檔案重新編譯之前,Make它的先決條件C語言源檔案和C語言頭檔案是否需要更新。如果這些 C語言源檔案和C語言頭檔案不是任何規則的目標make將不會對們做任何情。Make也可以自動生C語言源程式 ,這需要特定的規則,如可以根據Bison或Yacc生C語言源程式
OBJ檔案重新編譯(如果需要的話)之make決定是否重新連接生成edit執行檔案。如果edit可執行檔案
不存在或任何一個OBJ檔案比存在的edit執行檔案’,則make重新連接生成edit執行檔案
,如果我們修改了‘insert.c檔案,然後執行makemake將會編譯insert.c檔案更新insert.o檔案 ,然後重新連接生成edit執行檔案。如果我們修改了‘command.h檔案,然後執行makemake將會重新編譯kbd.ocommand.o檔案,然後重新連接生成edit執行檔案
2.4使用變數簡化makefile檔案
我們的例子中,我們edit的生成規則中所有的OBJ檔案兩次,這裡
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
樣的兩次錯的可能,系統中加入一個新的OBJ檔案,我們可能在一個地方加入了, 而在另一個地方卻了。我們使用變數可以簡化makefile檔案並錯的可能。變數是定義一個字元串一次 ,而能在多處替代字元串使用具體內容閱讀使用變數一節)。
在makefile檔案中使用名為objects, OBJECTS, objs, OBJS, obj, 或 OBJ的變數代所有OBJ檔案已約定成俗個 makefile檔案我們定義名為objects的變數其定義格式如下︰
objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o
一個OBJ檔案的地方,我們使用寫為`$(objects)'式的變數代替具體內容閱讀使用變數一節)。 下面是使用變數後的的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.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 $(objects)
2.5 讓make推斷命令
編譯單的C語言源程式並不需要寫命令,因為make可以把它推斷出來︰make有一個使用CC c命令的C語 程式編譯更新為相同檔案名的OBJ檔案的隱含規則make可以自動使用cc -c main.c -o main.o命令把‘main.c 編譯 main.o’。因,我們可以略OBJ檔案的更新規則。詳細內容請看使用隱含規則一節。
如果C語言源程式能夠這樣自動編譯則它能夠自動加入先決條件中以我們可在先決條件中C語言源程 式而可以命令。下面是使用隱含規則和變數objects的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 $(objects) 這是我們實際編寫makefile檔案的例子。(和目標clean’聯繫複雜情況具體參見假想(phony)目標命令 錯誤兩內容。)因為隱含規則便常重要在makefile檔案中常使用它們。
2.6 另一種風格的makefile檔案
當時在makefile檔案中使用隱含規則建立OBJ檔案時,用另一種風格的makefile檔案也是可行的種風格的 makefile檔案中,可以依據先決條件分代替依據目標分。下面是種風格的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 display.o insert.o search.o files.o : buffer.h 這裡的defs.h所有OBJ檔案的的一個先決條件command.h和bufffer.h具體列出OBJ檔案的先決條件 雖然種風格編寫makefile檔案更具風makefile檔案更加小,但把每一個目標的訊息放而不喜歡這種風格
2.7 在目錄中刪除檔案的規則
編譯程式並不是編寫make規則的一事情。Makefile檔案可以告訴make去完成編譯程式以外的其它任務,如,怎樣刪 除OBJ檔案和執行檔案以保目錄的乾淨。下面是刪除用make規則編輯器的例子 clean: rm edit $(objects) 在用中,應該編寫複雜的規則不能預料的情況發更接用的規則樣式如下︰
.PHONY : clean clean :
-rm edit $(objects) 可以防止make在名為clean的檔案而發亂,且導致它在執行rm命令時發生錯誤具體參見假想 (phony)目標命令錯誤兩內容)。 諸如這樣的規則不能放在makefile檔案的,因我們不希望它變為預設最終目標。應該我們的makefile檔案例子一 樣,把edit的規則前面,從而把編譯更新edit執行程式定為預設最終目標
3 編寫makefile檔案
make編譯系統依據的訊來源於稱為makefile檔案的資料庫
3.1 makefile檔案的內容
makefile檔案含5種內容具體規則隱含規則定義變數指令和釋。規則變數和指令在後章節介紹 具體規則用什么時間或怎樣重新生成為規則目標的一個或多個文件的目標所依靠
檔案,這些檔案目標的先決條件。具體規則可能同時提供了或更新目標的命令。詳細內容參閱編 寫規則一章。
隱含規則用於述什么時間或怎樣重新生成一文件名的一系列文件的它描述的目標是根據和它名字
相同的檔案進行建或更新的,同時提供了或更新目標的命令。詳細內容參閱使用隱含規則一節。
定義變數是為一個變數一個固定的字符串值,從而後的文件中能夠使用變數代替個字
注意在makefile檔案中定義變數的makefile檔案例子中我們定義所有OBJ檔案的變 數objects(詳細內容參閱使用變數簡化makefile檔案一節)。
指令make根據makefile文件執行一定任務的命令這些包括如下幾方面: 讀取其它makefile文件(詳細內容參見
引入(include)其它的makefile文件
)。
(根據變數的值)是否使用或略makefile文件的分內容(詳細內容參閱
makefile文件的條件
語句
節)。
定義多行變數,即定義變數值可以引入(include)多行字的變數(詳細內容參見
定義多行變數
)。
以‘#’開的行是注釋行在處理時將make略,如果一個行在行是‘\表示下一行繼續,這釋可以持續多行除在define指令內部外,註釋可以出現下makefile檔案的任何地方,甚至在命令內部(
這裡shell決定什麼是內容)。
3.2 makfile檔案的命名
預 設 情 況 下 , 當 make 尋 makefile 檔 案 時 , 它 試 搜 尋 具 有 如 下 的 名 字 的 檔 案 , 按 GNUmakefile’ 、‘makefileMakefile’。
通常情況下您應該把您的makefile檔案命名為makefileMakefile’。(我們使用Makefile’,因為它基本出現 目錄單的前面,其它重要的檔案如‘README)。雖然首先搜尋GNUmakefile’,但我們 使用的makefile檔案特為GNU make編寫的在其它make版本上不能執行,您才應該使用GNUmakefile作 為的makefile的檔案名
如果make不能發現具有上面所述名字的檔案將不使用任何makefile檔案。這您必須使用命令參數定目標make 試用內建的隱含規則如何重建目標。詳細內容參見使用隱含規則一節。 如果您使用名字makefile檔案,您可以使用-f--file參數指定的makefile檔案參數-f name-­file=name’能夠告訴make讀名字為name的檔案作為makefile檔案。如果您使用 -f--file參數多一個,意
著您指定多個makefile檔案所有的makefile檔案具體的序發生作用旦您使用了‘-f--file參數,將自動查是否存在名為GNUmakefile’、‘makefileMakefile的makefile檔案
3.3 引入(include)其它的makefile檔案
include指令告訴make暫停讀取當前的makefile檔案先讀include指令指定的makefile檔案後再繼續指令在makefile檔案 一行其格式如下︰
include filenames...
filenames可以含shell檔案名的格式
在include指令行處的多的空格,但make處理略這些空格,注意該行不能以Tab字符開(因為 ,以Tab字符開始的行make命令行)。include和檔案名之間以空格開,兩個檔案名之間也以空格開, 的空格make處理略,行的部可以上以‘#起始釋。檔案名可以引入(include)變數函數呼叫 在處理時由make進行展開(具體內容參閱使用變數一節)。
如,.mk檔案︰‘a.mk’、‘b.mkc.mk’,變數$(bar)展開為bish bash下面是︰
include foo *.mk $(bar) 和include foo a.mk b.mk c.mk bish bash’相同。
make見include指令時, make暫停讀取當前的makefile檔案,依次讀取的makefile檔案完之make 繼續讀取當前makefile檔案中include指令後的內容 使用include指令的一種情況是幾個程式分有單的makefile檔案,但們需要一系列的變數定義(詳細內容參閱 設定變數),系列的樣式規則(詳細內容參閱定義與重新定義樣式規則)。
另一種使用include指令情況是需要自動從源檔案為目標生先決條件的情況,時,先決條件在makefile檔案引入 (include)的檔案中。這種模式比其它版本的make把先決條件附加在makefile檔案後部的統模式更顯得簡。具體內容 參閱自動生先決條件 如果makefile檔案名不以‘/’開頭,當前目錄下也不能找到,搜尋另的目錄。首搜尋以‘-|-­include-dir參數指定的目錄 ,然次 搜尋下 面 的 目錄 (如果們存在的 話)︰‘ prefix/include' ( 通常為
/usr/local/include') /usr/gnu/include', /usr/local/include', /usr/include'
如果指定引入(include)的makefile檔案在述所有的目錄都不能找到,make將產生一個,注意這不是致命的錯 處理完include指令引入(include)的makefile檔案繼續處理當前的makefile檔案一旦完成makefile檔案的讀取make或更新舊式的或不存在的makefile檔案。詳細內容參閱makefile檔案重新生成的過程有在所有make 求丟失的makefile檔案的努力失make才能斷定丟失的makefile檔案一個命的錯誤。 如果您希望對不存且不能重新建的makefile檔案進行略,且不產生錯誤訊則使用-include指令代替include指
格式如下︰
-include filenames...
種指令的作用就是對於任何不存在的makefile檔案都不會產生錯誤(即使也不會產)。如果希望保持和其 它版本的make使用sinclude指令代替-include指令
3.4 變數MAKEFILES
make 讀取數個 makefile 時(包括根據環境變數 MAKEFILES 讀取的 makefile命令指定的預設的、使用 include 指 定的),這些makefile的名字自動的加進變數 MAKEFILE_LIST 。這些檔案名稱會在開始被 make 解析之前就 加進變數 MAKEFILE_LIST 也就是說,如果在一個 makefile 中一件事就是查這個變數的最後一個字,這個字就該是前這個 makefile 的 檔名的 makefile 使用指令 include ,這個變數的最後一個字就會變成 include 進的 makefile 的檔名 一個名為 Makefile 的 makefile 含有以下內容
name1 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) include inc.mk name2 := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
all:
@echo name1 = $(name1) @echo name2 = $(name2)
那麼,可以預料到會看到以下輸出
name1 = Makefile name2 = inc.mk
其它的特殊環境變數 GNU make 支援一個特殊變數,任何給該變數的值都會被忽略;回它的特殊值
一個特殊變數 .VARIABLES 。當展開此變數時,會引入(include)一在所有的 makefile 中所定義的 變數名表。這裡頭引入(include)了值為空的變數(如內建變數,參考 示性規則所使用的變數 ),但不包括只在 個指定標的的內容中定義的變數
3.5 makefile檔案重新生成的過程
makefile檔案可以由其它檔案重新生成,如從RCS或SCCS檔案生成。如果一個makefile檔案可以從其它檔案重 新生成一定注意讓make更新makefile檔案讀取makefile檔案
成讀取所有的makefile檔案make查每一個目標並試更新它。如果對於一個makefile檔案有說明它怎樣 更新的規則(無論當前的makefile檔案中或其它makefile檔案中),者存在一條隱含規則說明它怎樣更新具體內 容參見使用隱含規則),則在要的makefile檔案將會自動更新。在所有的makefile檔案查之,如果發現任何 一個makefile檔案生變化make就會清空所有記錄並重新讀入所有makefile檔案。(然後次試更新這些makefile檔,正情況下,因這些makefile檔案已被更新make將不會們。)
如果您知的一個或多個makefile檔案不能重新建立,也許由於執行效率緣故,您不希望make按照隱含規則搜尋 或重建它們,您應使用常的阻止按照隱含規則們。如,您可以寫一個具體的規則,把這些makefile檔案 作目標,但不提供任何命令(詳細內容參閱使用空命令)。
如果在makefile檔案中指定依據雙冒號規則(::)使用命令重建一個檔案,但沒有提供先決條件則一make執行 重建檔案(詳細內容參見雙冒號規則(::))。同,如果在makefile檔案中指定依據雙冒號規則(::)使用命令重建的一 個makefile檔案且不提供先決條件則一make執行就會重建makefile檔案,然後重新讀入所有makefile檔案,然重建makefile檔案重新讀入所有makefile檔案,如此往無限,致使make不能任務。 如果要避免情況一定注意不依據雙冒號規則(::)使用命令並且不提供先決條件重建任何makefile檔案
如果您沒有使用-f--file指定makefile檔案make將會使用預設的makefile檔案名(詳細內容參見3.2內容 )。不像使用-f--file選項指定具體的makefile檔案,這時make不能確定makefile檔案是否存。如果預設的 makefile檔案不存,但可以由執行的make依據規則建立,您需要執行這些規則要使用的makefile檔案
如果預設的makefile檔案不存make將會按照搜尋的次序立,到將makefile檔案成或 make所有的檔案名試過來。注意make不能找到或建立makefile檔案不是錯誤,makefile檔案並不是執行make必須的。
使使用-t指定,‘-t--touch選項更新makefile檔案不產任何影響 makefile檔案 更新以當您使用-t--touch選項時,您不要使用舊式的makefile檔案決定touch’哪個目標具體含 義參閱代替執行命令)。同,因-q' (或 --question') 和 -n' (或 --just-print')也能不阻止更新makefile檔案 舊式的makefile檔案其它的目標將產生錯誤的輸出結果。如,‘make -f mfile -n foo命令將這樣執行更新
mfile’,然後讀入輸出更新foo的命令和先決條件,但執行更新foo’,注意,所有回顯的更新foo的命令在更新後的mfile中指定的
使用過程中,您一定確實希望阻止更新makefile檔案的情況。如果這樣,您可以在makefile檔案命令行將需要更新的makefile檔案指定為目標,如阻止更新makefile檔案。一makefile檔案名明確指定為一個目標 選項-t將會對生作用。如這樣設定,‘make -f mfile -n foo命令將這樣執行讀入mfile’,輸出更新 foo的命令和先決條件,但執行更新foo’。回顯的更新foo的命令引入(include)在現存mfile
3.6 重載其它makefile檔案
一個makefile檔案和另一個makefile檔案也是有用的。您可以使用include指令更多的makefile檔案引入 (include)進來,如加入更多的目標和定義的變數。然而如果兩個makefile檔案對相同的目標給出了不同的命令,make 就會產生錯誤makefile檔案要引入(include)其它makefile檔案的,您可以使用萬用字元樣式規則說明有在依靠當前 makefile檔案中的訊不能重新建目標時,make搜尋其它的makefile檔案,詳細內容參見定義與重新定義樣式規則如︰如果您有一個說明怎樣建目標foo’(和其它目標的makefile檔案Makefile’,您可以編寫另一個 GNUmakefile的makefile檔案引入(include)以下語句
foo:
frobnicate > foo %: force @$(MAKE) -f Makefile $@ force: ;
如果鍵make foo’,make就會找到‘GNUmakefile’,讀入,然後執行frobnicate > foo’。如果鍵make bar’,make發現無根據‘GNUmakefile立‘bar’,使用樣式規則提供的命令︰‘make f Makefile bar’。如 Makefile提供了‘bar更新的規則make就會使用規則。對其它GNUmakefile’不提供怎樣更新的目標 make也會同樣處理。這種工作的模式是使用了樣式規則中的樣式匹配符‘%’,它可以和任何目標匹配。該規則指定了 一個先決條件force’,來保證命令一定要執行,無論目標檔案是否存。我們給出的目標‘force’時使用了空命令 ,這防止make按照隱含規則搜尋和建,否make將把同樣的匹配規則目標force,從而陷入先決條件的環中
3.7 make讀取makefile檔案的過程
GNU make它的工作顯的分為兩個階。在一階make讀取makefile檔案包括makefile檔案本、內置變數、隱含規則和具體規則構造所有目標的依靠表和它們的先決條件。在make使用這些內置的組織決定
要重新構造的目標使用要的規則進行工作。 了解make兩階的工作模式分重要,因為它影響變數函數展開模式;而這也是編寫makefile檔案時導致 誤的來源之。下面我們將對makefile檔案中不同架構展開模式進行結。我們稱在make工作一階生的展開 是立即展開︰情況下,makemakefile檔案進行語法分析時把變數和函數展開架構單元的一。我們把 不能立即執行的展開稱(deferred)展開。延時(deferred)展開架構直到已出現下上下架構中或make進入到了第 工作階時才執行展開。 您可能對這分內容不熟悉。您可以看完面幾章對這些知熟悉內容
變數
變數的定義語法如下︰
immediate = deferred immediate ?
= deferred
immediate := immediate immediate += deferred or immediate
define immediate deferred endef 對於附加符‘+=’,右邊變數如果前面使用:=定義為簡單展開變數則是立即變數其它(deferred) 變數
條件語句
,條件語句都按語法立即分析常用的有ifdefifeq、ifndef和inneq。
定義規則
規則不論如何,都按相同的模式展開。
immediate : immediate ; deferred
deferred 目標和先決條件都立即展開,構造目標的命令通常都是(deferred)展開。這個通用的規對具體規則、樣式 規則後置規則(suffix rule)靜態樣式規則和簡單先決條件定義都適
4編寫規則
makefile檔案中的規則來說明何時以怎樣重建特定檔案的,這些特定的檔案規則的目標通常情況下
,每個規則有一個目標)。在規則中列的其它檔案稱為目標的先決條件,同時規則還給出了目標建立、更新的命令般情況下規則的次序,但決定預設最終目標時卻是外。預設最終目標是您沒有另指定最終目標時,
make定的最終目標。預設最終目標makefile檔案中的一條規則的目標。如果第一條規則有多個目標,只有第一個目預設最終目標有兩種例情況︰以點(‘.’)開的目標不是預設最終目標(如果該目標引入 (include)一個或多個斜線(/) ‘/’,目標也可能是預設最終目標);另一種情況是樣式規則定義的目標不是預設最 終目標參閱定義與重新定義樣式規則)。
以,我們編寫makefile檔案時,通常將第一個規則的目標定為編譯全部程式或是由makefile檔案述的所有程式(經 常設定一個all的目標)。參閱指定最終目標的參數。
4.1規則的語法
通常一條規則如下︰
targets : prerequisites
command ...
targets : prerequisites ; command
command ...
目標target)是檔案的名稱,間由空格開。萬用字元可以在檔案名中使用參閱在檔案名中使用萬用字元),
am)’形式的檔案名表示m在檔案a中參閱資料庫成目標)。般情況下,一條規則只有一個目標,但偶 爾由於其它原因一條規則有多個目標參閱具有多個目標的規則)。
命令行Tab字符開,第一個命令可以和先決條件在一行命令和先決條件之間用分號開,也可以在先決條件 一行,以Tab字為行的。這兩種方法的果一樣,參閱在規則中使用命令。
用為變數引用的符,如果您真希望在規則中使用,您必須連寫兩次,‘$$參閱使 用變數)。您可以把一行在中間插入\’使其分為兩行,也就是說,一行的部是’\’的話,表示下一行是本行的
繼續。但這不是必須make沒有makefile檔案中行的長度進行一條規則可以告訴make兩件事情︰何時目標時,以怎樣在更新它們。
斷目標舊式的則和先決條件關密切先決條件也由檔案名檔案名之間由空格開,萬用字元和
資料庫成員也在先決條件中出現。一個目標如果不存在或它其中一個先決條件的修改時間目標已經 時。該來源於目標是根據先決條件的訊息計得來,因旦任何一個先決條件生變化目標檔案也就不
目標的更新模式命令決定命令shell解釋執行,但也有一的特點。參閱在規則中使用命令
4.2 在檔案名中使用萬用字元
一個簡單的檔案名可以過使用萬用字元代表許多檔案Make中的萬用字元和Bourne shell中的萬用字元一樣
是‘*’、‘[]’。例如︰‘*.C指在當前目錄中所有以‘.C’結尾的檔案
符‘~在檔案名的前面也有特殊的含義如果字符‘~’單或後面跟一個斜線(/) ‘/’,則代表您的home目錄。如
~/bin’展開/home/bin’。如果符‘~一個字展開為home目錄下以該字為名字的目錄,如 ‘~John/bin’表示‘home/John/bin’。在一業系統(如ms-dosms-windows不存在home目錄,可以過設定環
境變數home比。
在目標、先決條件和命令中的萬用字元自動展開。在其它上下文中萬用字元有在您明確表明呼叫萬用字元函數時才
展開。
萬用字元另一個特點是如果萬用字元前面是反斜線(\)\’,萬用字元失去通配能力。如‘foo\*bar’表示一個特定 的檔案其名字由‘foo’、‘*bar
4.2.1萬用字元例子
萬用字元可以用在規則的命令中萬用字元shell展開。如,下面的規則刪除所有OBJ檔案
clean
rm -f *.o 萬用字元在規則的先決條件中有用下面的makefile規則中,‘make print’將列所有從上您列動的.c檔案
print: *.c lpr -p $? touch print
本規則使用ptint作為一個空目標檔案使用空目標檔案記錄事件);自動變數$?來列那些經修改 的檔案自動變數 當您定義一個變數萬用字元不會展開,如果您這樣寫 objects = *.o 變數objects的值就是字元串*.o’。然而,如果您在一個目標先決條件和命令中使用變數objects的值萬用字元 那時展開。使用下面的語句使萬用字元展開︰
objects=$(wildcard *.o) 詳細內容參閱函數wildcard
4.2.2使用萬用字元的常見錯誤
下面有一個幼稚使用萬用字元展開的例子,但實上該例子不能完希望完成的任務。假設執行檔案foo’由當前目錄的所有OBJ檔案建立,其規則如下︰
objects = *.o
foo : $(objects) cc -o foo $(CFLAGS) $(objects)
由於變數objects的值為字元串*.o’,萬用字元在目標foo的規則下展開,以每一個OBJ檔案都會變為目標foo的先決條件並在重新編譯自己。 但如果您刪除所有的OBJ檔案,情況怎樣呢?沒有和萬用字元匹配的檔案目標foo’就依靠了一個 奇怪名字的檔案*.o’。因為目錄中不存檔案make將發出不能立‘*.o的錯誤訊。這可不是所要執行的 任務。
上,使用萬用字元得正確結果是可能,但您必須使用稍微複雜的技術,該技術包括使用函數wildcard和
替代字元串。詳細內容節論 微軟的作業系統(MS-DOSMS-WINDOWS使用反斜線(\)分目錄路俓(stem),如︰ C:\foo\bar\bar.c
和Unix風格c:/foo/bar/bar.c’相同(‘c:’是驅動)。當make在這些系統上執行時,不但支援在路俓(stem)中反斜線(\)支援Unix風格的斜線(/)。但是這種對反斜線(\)的支援包括萬用字元展開,因為萬用字元展開時,反斜 (\)用作引用字符。以,這些合您必須使用Unix風格的斜線(/)
4.2.3函數wildcard(萬用字元)
萬用字元在規則中可以自動展開,但設定在變數中或在函數的參數中萬用字元一般不能正展開。如果您需 要在這些合展開萬用字元,您應該使用函數wildcard格式如下︰
$(wildcard pattern...)
可以在makefile檔案的任何地方使用字元串,應時該字元串在指定目錄下存在的並檔案名和給出的檔案名
的格式相符合的檔案所代替檔案名中間由空格開。如果沒有和指定格式一的檔案則函數wildcard的輸出將會 略。注意這和在規則中萬用字元展開的模式不同,在規則中使用展開模式,而不是模式參閱上節)。 使用函數wildcard得到指定目錄所有的C語言源程式檔案名的命令格式為
$(wildcard *.c)
我們可以把所獲的C語言源程式檔案名的字元串透將‘.c後置變為.o轉換為OBJ檔案名的字元串其格式為
$(patsubst %.c,%.o,$(wildcard *.c))
這裡我們使用一個函數patsubst,詳細內容參閱字元串替換和分析函數。 這一個編譯特定目錄所有C語言源程式並連接在一的makefile檔案可以寫成如下格式
objects := $(patsubst %.c,%.o,$(wildcard *.c))
foo : $(objects) cc -o foo $(objects)
這裡使用了編譯C語言源程式的隱含規則,因此沒有必要為每個檔案寫具體編譯規則。 ‘:=’是‘=’的變,對‘:= ’的解釋,參閱兩種風格的變數。
4.3在目錄中搜尋先決條件
對於大系統,把源檔案放在一個單的目錄中,而把二進制檔案在另一個目錄中是十分常見的Make 的目錄搜尋特使自動在個目錄搜尋先決條件分容易。當您個目錄中重新的檔案,您不必改動單的 規則,僅僅改動一搜尋路俓(stem)即可。
4.3.1 VPATH所有先決條件的搜尋路俓(stem)
make變數VPATH的值指定make搜尋的目錄。經常用是那些引入(include)先決條件的目錄不是當前 的目錄;但VPATH指定make所有檔案都適用的目錄搜尋序列,包括規則的目標所要的檔案 如果一個作為目標或先決條件的檔案在當前目錄中不存make就會在VPATH指定的目錄中搜尋檔案。如果這些 目錄中找到要尋的檔案這些檔案在當前目錄下存在一樣規則把這些檔案指定為先決條件參閱編寫搜尋 目錄的shell命令
在VPATH變數定義中目錄的名字冒號或空格分開。目錄列舉的次序也是make 搜尋的次序。在MS-DOS、MS-
WINDOWS系統VPATH變數定義中的目錄的名字分號分開,因為在這些系統冒號用為路俓(stem)名的一通常在面)。如︰
VPATH = src:../headers
指定兩個目錄,‘src‘…/headers’,make也按照這個次序進行搜尋使用VPATH的值,下面的規則
foo.o : foo.c
在執行時就如下寫法一樣中斷 foo.o : src/foo.c 後在src目錄搜尋foo.c
4.3.2 vpath指令
vpath指令(注意是小和VPATH變數類,但卻更具靈活性。vpath指令許對符合一定格式類型的檔案名指定 一個搜尋路俓(stem)。這樣您就可以對一種格式類型的檔案名指定一個搜尋路俓(stem),對另外格式類型的檔案名指定另 一個搜尋路俓(stem)總共三種式的vpath指令
vpath pattern directories
一定格式類型的檔案名指定一個搜尋路俓(stem)搜尋的路俓(stem)要搜尋的目錄目錄冒號在MS- DOSMS-WINDOWS系統中用分號或空格開,和VPATH變數定義要搜尋的路俓(stem)格式一樣
vpath pattern
除和一定類型格式相聯繫的搜尋路俓(stem)
vpath
除所有前面由vapth指令指定的搜尋路俓(stem)
一個vpath的格式pattern一個含一個%的字元串。該字元串必須搜尋的一個先決條件的檔案名匹配%
任何字元串匹配樣式規則參閱定義與重新定義樣式規則)。例如,%.h和任何檔案名以.h結的檔案匹配。 如果不使用%’,格式必須與先決條件精確匹配,這情況很少使用
在vpath指令格式中的字符‘%’可以透前面的反斜線(\)被引用引用其它字符‘%’的反斜線(\)也可以被更多的反斜 線(\)引用。引用字符‘%’和其它反斜線(\)的反斜線(\)在和檔案名比較之前和格式。如果反斜線(\)所引用的字符
%沒有錯誤反斜線(\)不會執行來任何危。 如果vpath指令格式和一個先決條件的檔案名匹配當前目錄中先決條件不存則vpath指令中指定的目錄和
VPATH變數中的目錄一樣可以搜尋如︰
vpath %.h ../headers
將告訴make如果當前目錄中以‘.h’結檔案不存則在../headers目錄搜尋任何以‘.h’結先決條件
如果個vpath指令格式和一個先決條件的檔案名匹配則make一個接一個的處理它們,搜尋所有在指令中指定的目 Make在makefile檔案中出現的次序控制多個vpath指令多個指令雖然相同的格式,但們是相互。 以下
vpath %.c foo vpath % blish vpath %.c bar
表示搜尋`.c'檔案先搜尋目錄`foo'、然後`blish'最後`bar';如果是如下
vpath %.c foo:bar vpath % blish
表示搜尋`.c'檔案先搜尋目錄foo'、然bar'最後blish'
4.3.3目錄搜尋過程
透過目錄搜尋找到一個檔案,該檔案有可能不是您在先決條件單中所列出的先決條件透過目錄搜尋找到的 路俓(stem)也可能被廢棄Make決定過目錄搜尋找到的路俓(stem)廢棄依據的算法如下︰
1如果一個目標檔案在makefile檔案所在的目錄下不存將會執行目錄搜尋 2如果目錄搜尋成則路俓(stem)和所得到的檔案作為目標檔案存。
3所有目標的先決條件用相同 4、把先決條件處理成後,該目標可能需要或不需要重新建立︰
1如果該目標不需要重建目錄搜尋得到的檔案的路俓(stem)用作目標所有先決條件的路俓(stem),同時
目標檔案而言之,如果make不必重建目標使用過目錄搜尋得到的路俓(stem) 2、如果該目標要重建目錄搜尋得到的檔案的路俓(stem)廢棄目標檔案在makefile檔案所在的目錄重 建而言之,如果make要重建目標,是在makefile檔案所在的目錄重建目標,而不是在目錄搜尋得到的檔 案的路俓(stem)
算法似乎複雜,但卻可十精確解釋實所要的東西 其它版本的make使用一種簡單的算法︰如果目標檔案在當前目錄下不存,而過目錄搜尋得到,不論該目標
是否需要重建終使用過目錄搜尋得到的路俓(stem)。 實上,如果在GNU make中使的一全部目錄具種行為,您可以使用GPATH變數指定這些目錄GPATH變數和VPATH變數具有相同的語法和格式。如果過目錄搜尋得到一個舊式的目標,而目標在的目錄又出現GPATH變數路俓(stem)將不廢棄目標路俓(stem)重建
4.3.4編寫目錄搜尋的shell命令
使過目錄搜尋在其它目錄下找到一個先決條件,不能改變規則的命令,這些命令按照原來編寫的模式執行。 因,您應該小心的編寫這些命令,以便們可以在make能夠發現先決條件的目錄中處理先決條件
助諸如‘$^’的自動變數的使用shell命令參閱自動變數)。例如,‘$^’的值代所有的先決條件
引入(include)尋先決條件的目錄;‘$@’的值目標
foo.o : foo.c
cc -c $(CFLAGS) $^ -o $@
變數CFLAGS可以方便您利用隱含規則指定編譯C語言源程式的。我們這裡使用它是為了保持編譯C語言源程式致性。參閱隱含規則使用的變數 先決條件通常情況下也引入(include)檔案,因自動變數$<’的值是第一個先決條件,因這些頭檔案您可以不必在 命令中
如︰
VPATH = src:../headers foo.o : foo.c defs.h hack.h cc -c $(CFLAGS) $< -o $@
4.3.5 目錄搜尋和隱含規則
搜尋的目錄是由變數VPATH或隱含規則引入的vpath指令指定的(詳細參閱使用隱含規則)。如,如果檔案foo.o 沒有具體的規則make則使用隱含規則︰如檔案foo.cmake使用內置的規則編譯它;如果檔案foo.c當前目錄 下,就搜尋適當的目錄,如的目錄下找到foo.cmake樣使用內置的規則編譯它 隱含規則的命令使用自動變數是必需隱含規則可以然地使用目錄搜尋得到的檔案
4.3.6 連接庫(Link Libraries)的搜尋目錄
對於連接庫(Link Libraries)檔案目錄搜尋用一種特的模式。這種特的模式於︰您寫一個先決條件它的名 字是‘-|name。(您可以這裡寫一特的字符,因為先決條件檔案名庫檔案名通常
‘libname.a’ 的形式,而不是‘-|name’ 的形式。) 當一個先決條件的名字是‘-|name’的形式時,make特地在當前目錄下、與vpath匹配的目錄下、VPATH指定的目錄下 以‘/lib’, ‘/usr/lib', 和 ‘prefix/lib'(正常情況為`/usr/local/lib',但是MS-DOS、MS-Windows版本的make的行為好像是 prefix定義為DJGPP安裝的根目錄的情況)目錄下搜尋名字為‘libname.so'的檔案然後處理它。如果沒有搜尋到 ‘libname.so'檔案,然後在前述的目錄下搜尋‘libname.a'檔案。
如,如果系統中有/usr/lib/libcurses.a'的庫檔案
foo : foo.c -lcurses cc $^ -o $@
如果‘foo’比‘foo.c更舊,將導致命令cc foo.c /usr/lib/libcurses.a -o foo'執行
預設情況下是搜尋libname.so' 和libname.a'檔案具體搜尋的檔案及其類型使用.LIBPATTERNS變數指定,這個變 數值中的一個字都是一個字元串格式。當尋找名為‘-|name’的先決條件時,make首先用name替代清單中第一個字中 的格式成要搜尋的庫檔案名,然後使用庫檔案名在述的目錄中搜尋。如果沒有發現庫檔案則使用單中 的一個字其餘此類推 .LIBPATTERNS變數預設的值是"‘lib%.so lib%.a'",該對前面描述的預設行為提供支援。您可以透將該值設為空值 從而徹底關閉連接庫(Link Libraries)的展開。
4.4假想(phony)目標
假想(phony)目標並不是一個真正的檔案名僅僅是您定的一個具體規則所執行的一命令的名稱。使用假想 (phony)目標有兩個原因︰避免和具有相同的檔案衝突性能。
如果您寫一個其命令目標檔案的規則旦由於重建而提目標規則的命令就會執行
這裡有一個例子
clean: rm *.o temp
為rm命令名為clean的檔案以不應有名為clean的檔案。因不論何時您發布`make clean'指令 rm命令就會執行
假想(phony)目標能夠任何在目錄名為clean的檔案工作。但如在目錄下存在檔案clean,因為該目標clean沒 有先決條件檔案clean會認經該更新,因它的命令不會執行避免情況,您應該使用 如下的.PHONY目標樣式將該目標具體的為一個假想(phony)目標
.PHONY : clean
旦這明,‘make clean命令無論目錄下是否存在名為clean的檔案,該目標的命令都會執行 為make道假想(phony)目標不是一個根據別的檔案重新建際檔案跳過隱含規則搜尋假想 (phony)目標的步驟(詳細內容參閱使用隱含規則)。這是把一個目標為假想(phony)目標可以提執行效率原因 ,因此使用假想(phony)目標您不在目錄下是否際檔案。這,對前面的例子可以用假想(phony)目標的 寫出,其格式如下︰
.PHONY: clean clean: rm *.o temp
一個使用假想(phony)目標的例子使用make的遞迴進行連接的情況︰時,makefile檔案常常引入(include)系列需要建的子目錄的變數。不用假想(phony)目標任務使用一條規則其命令一個在個子目 錄環的shell命令
如下面的例子
subdirs: for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir; \ done
使用述問題︰首,這個規則在建子目錄時產生的任何錯誤都不時發現,因,當一個子目錄 建立失時,該規則然會繼續剩餘的子目錄。雖然該問題可以添加監視錯誤產生並退出的shell命令來解決,但是如果make使用了‘-k選項,這個問題然會產。第,也許更重要的是您使用了該方法就失去使用make 並行處理的特點能力。
使用假想(phony)目標(如果子目錄經存,您必須這做,否,不存在的子目錄將不會立)可以避免 述問題
SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS): $(MAKE) -C $
foo: baz
時,如果子目錄baz’沒有建立完子目錄foo’將不會立;當使用並行建立時這種關其重 要
一個假想(phony)目標不應該是一個目標檔案的先決條件,如果這make次執行規則的命令目標檔案要 更新要假想(phony)目標不是一個真實目標的先決條件假想(phony)目標的命令有在假想(phony)目標作為特目 標時才會執行參閱指定最終目標的參數)。 假想(phony)目標也可以有先決條件。當一個目錄引入(include)多個程式時,使用假想(phony)目標可以方便的在一個 makefile檔案中述多個程式的更新。重建的最終目標預設情況下是makefile檔案的一個規則的目標,但將多個程式作 為假想(phony)目標的先決條件則可以輕鬆成在一個makefile檔案中述多個程式的更新。如下
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 utils.o
,您可以重建所有程式,也可以參數的式重建其中的一個或多個(如‘make prog1 prog3')。 當一個假想(phony)目標另一個假想(phony)目標的先決條件假想(phony)目標作為一個假想(phony)目標的子例
如,這裡‘make cleanall'用刪除OBJ檔案diff檔案和程式檔案
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff rm program
cleanobj : rm *.o
cleandiff : rm *.diff
4.5 沒有命令或先決條件的規則
如果一個規則沒有先決條件、也沒有命令,而且這個規則的目標也不是一個在的檔案則make規則執行 ,該目標已被更新。這意著,所有以這種規則的目標為先決條件的目標的命令總被執行。這裡一個例子
clean: FORCE rm $(objects) FORCE:
這裡的目標FORCR’滿足上面的特殊條件以以其為先決條件的目標clean’將總強製它的命令執行於 ‘FORCR’的名字沒有特的要,但‘FORCR’是使用的名字
也許您經明使用FORCR’法和使用假想(phony)目標.PHONY: clean結果一樣,但使用假想(phony)目
標更具體更靈活,由於的版本的make支援假想(phony)目標以‘FORCR’出現下許多makefile檔案中 參閱假想(phony)目標
4.6使用空目標檔案記錄事件
空目標一個假想(phony)目標變數它用控制一命令的執行,這些命令來完成一些經要的具體任務。但 真正的假想(phony)目標它的目標檔案可以實存在,但檔案的內容與無關通常情況下,這些檔案沒有內
空目標檔案的用記錄規則的命令最後一次執行的時間,也是空目標檔案最後更時間。以能夠這樣 執行是因為規則的命令中有一條用更新目標檔案的touch命令外,空目標檔案有一先決條件(否則空目 標檔案沒有在的)。如果空目標比它的先決條件舊,當您命令重建空目標檔案時,有關的命令才會執行。下面有 一個例子
print: foo.c bar.c lpr -p $? touch print
按照這個規則,如果任何一個檔案從上次執行make print'以來發生變化,鍵make print'則執行lpr命令自動變數$?來列那些發生變化的檔案參閱自動變數)。
4.7 內建的特殊目標名
名字作為目標使用則含有特殊的 .PHONY 特殊目標.PHONY的先決條件假想(phony)目標假想(phony)目標是這樣一目標make條件的執行它命令
目錄下是否存檔案它最後一次更新的時間沒有關係。詳細內容參閱假想(phony)目標
.SUFFIXES 特殊目標.SUFFIXES的先決條件後置規則(suffix rule)的後置。詳細內容參閱舊式的後置規則(suffix
rule)
.DEFAULT .DEFAULT指定一命令,這些命令用於那些沒有找到規則具體規則或隱含規則更新的目標。詳細內容參閱定
義最新類型的-預設規則。如果.DEFAULT指定命令則所有的檔案作為先決條件,而不能作為規則的目標;這些指定的命令按照的模式執行。詳細內容參閱隱含規則搜尋算法
.PRECIOUS 特殊目標.PRECIOUS的先決條件將按照下面給定的特殊模式進行處理︰如果在執行這些目標的命令的過程中
make關閉或中斷,這些目標不能刪除,詳細內容參閱關閉和中斷make;如果目標檔案,即使它沒 有任何也不能刪除具體情況目標成一樣參閱隱含規則鏈;該目標的其它和特殊目標 .SECONDARY。如果規則的目標樣式與先決條件的檔案名匹配,您可以使用隱含規則的格式(如‘ %.O’)列目標作為特殊目標.PRECIOUS的先決條件檔案存由這些規則建的中檔案
.INTERMEDIATE 特殊目標.INTERMEDIATE的先決條件處理為中檔案。詳細內容參見隱含規則鏈.INTERMEDIATE如果沒有先
決條件檔案將不會發生作用
.SECONDARY 特殊目標.SECONDARY的先決條件處理為中檔案,但永遠不能自動刪除。詳細內容參見隱含規則鏈
.SECONDARY如果沒有先決條件檔案則所有的makefile檔案中的目標都將處理為中檔案
.DELETE_ON_ERROR 如果在makefile檔案的處.DELETE_ON_ERROR作為一個目標如果該規則生變化或它的命令沒有
確完退出,make將會刪除規則的目標具體行為和它到了刪除號一樣。詳細內容參閱命令錯誤
.IGNORE 如果您為目標.IGNORE指先決條件則MAKE將會處理這些先決條件檔案執行命令生的錯誤。如果
.IGNORE作為一個沒有先決條件的目標提出來,MAKE將忽處理所有檔案時產生的錯誤.IGNORE命令並沒有特的含義.IGNORE的用僅是期版本的。因為.IGNORE影響所有的命令它的用途不大;我們 使用其它來忽特定命令生的錯誤。詳細內容參閱命令錯誤
.SILENT 如果您為.SILENT指先決條件則在執行之前MAKE將不會回顯重新構造檔案的命令。如果.SILENT作為一個
沒有先決條件的目標提出來,任何命令在執行之前都不會列.SILENT並沒有特的含義其用僅是 期版本的。我們推您使用其它方法來處理那些不列印的命令。詳細內容參閱命令回顯。如果您希望所有的命都不列,請使用-s-silent選項(詳細參閱選項概要)
.EXPORT_ALL_VARIABLES 如該特殊目標簡單的作為一個目標MAKE預設地把所有變數子進程中參閱使與子MAKE通
的變數
.NOTPARALLEL
如果.NOTPARALLEL作為一個目標,即使給出‘-j選項make也不使用並行執行。但遞迴的make命令並行執 在呼叫的makefile檔案中引入(include).NOTPARALLEL的目標的例外)。.NOTPARALLEL的任何先決條件都將略。
任何定義的隱含規則後置如果作為目標出現都會為一個特殊規則,即使兩個後置串來也是如如‘.c.o’。 這些目標為後置規則(suffix rule),這種定義舊式的定義隱含規則的廣泛使用的)。原上 ,如果您它分為兩個並後置單中,任何目標名都可法指定。實上,後置一般以‘.’開
,因,這些特的目標以‘.’開。具體參閱舊式的後置規則(suffix rule)
4.8 具有多個目標的規則
具有多個目標的規則同於寫多條規則,這些規則除目標不同之外,完全相同。相同的命令所有目 標,但命令執行的結果可能有所差異,因您可以在命令中使用$@’發不同目標名稱。這條規則
所有的目標有相同的先決條件
以下兩種情況下具有多個目標的規則相當有用
您僅僅需要,但不需要任何命令如︰ kbd.o command.o files.o: command.h
為三提及的目標檔案給出附加的先決條件
所有的目標使用相同的命令命令的執行結果未必完全相同,因為自動變數‘$@’可以在重建指定目標
閱自動變數)。如︰
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
這裡我們假設程式可以產生兩種輸出檔案類型一種給出‘-big’,另一種給出‘-little’。參閱字元串代替和分析函數 ,對函數subst的解釋。 如果您喜歡根據目標變換先決條件使用變數$@’變換命令一樣。您不必使用具有多個目標的規則,您可以使用
靜態樣式規則。詳細內容見
4.9 具有多條規則的目標
一個目標檔案可以有多個規則。在所有規則中的先決條件都將在一個目標的先決條件單中。如果該目標比
任何一個先決條件’,所有的命令執行重建目標。 但如果一條以上的規則對同一檔案給出多條命令make使用最後給出的規則,同時列錯誤訊。(作為特例,如 果檔案名以點‘.’開,不列錯訊。這古怪的行為僅僅是和其它版本的make)。您沒有樣編寫的makefile檔案,這正是make給您發出錯誤訊原因。
一條特的先決條件規則可以來立即給多條目標檔案提供的先決條件例如,使用名為objects的變數變數系統產生的所有輸出檔案。如果‘congfig.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作為所有OBJ檔案的先決條件,如果僅僅輸make命令則不是這 如果沒有具體的規則為目標的生成指定命令,那麼make搜尋合適的隱含規則進而確定一命令來完成生成或重建目 標。詳細內容參閱使用隱含規則
4.10 靜態樣式規則Static Pattern Rules
靜態樣式規則指定多個目標並能夠根據每個目標名構造對應的先決條件名的規則靜態樣式規則在用多個目標
常的規則更常用,因為目標可以不必完全相同的先決條件;也就是說,這些目標的先決條件必須,但不必 完全相同。
4.10.1 靜態樣式規則的語法
這裡是靜態樣式規則的語法格式
targets ...
: target-pattern: dep-patterns ... commands ...
目標單指明該規則用的目標目標可以含有萬用字元具體使用和常的目標規則基本一樣參閱在檔案名中使 用萬用字元)。 目標的格式和先決條件的格式是說明如何個目標先決條件的。從匹配目標樣式的目標名中依據格式 分字元串,這部分字元串為俓(stem)。將俓(stem)分發到每一個先決條件格式中生先決條件名
一個格式通常含字符‘%’。目標樣式匹配目標時,‘%’可以匹配目標名中的任何字元串;這部分匹配的字元串為俓(stem)必須完全相同。如目標foo.o匹配樣式%.o’,字元串foo’稱為俓(stem)。而目標foo.cfoo.out’不匹配樣式
個目標的先決條件名使用俓(stem)代替個先決條件中的%’產。如,如果一個先決條件格式為%.c’,把
(stem)foo代替先決條件格式中的%生成先決條件的檔案名foo.c’。在先決條件格式中%’也是合法 的時對所有目標來說,先決條件是相同
在樣式規則中字符‘%’可以前面反斜線(\)\’方法引用引用%反斜線(\)也可以由更多的反斜線(\)引用 引用%’、‘\’的反斜線(\)在和檔案名俓(stem)代替它之前從格式中移走反斜線(\)不會因為引用‘%’而
亂。如,格式`the\%weird\\%pattern\\'`the%weird\' 加符‘%',和字元串 pattern\\'連接最後的兩個反斜線(\) 由於不能影響任何統符‘%以保
這裡有一個例子將對應.c檔案編譯成foo.obar.o’。
objects = foo.o bar.o all: $(objects) $(objects): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@
這裡‘
$<’是自動變數控制先決條件的名稱,‘$@’也是自動變數掌握目標的名稱
。詳細內容參閱自動變數
一個指定目標必須和目標樣式匹配,如果不符告。如果您有一檔案,僅有其中的一分和樣式匹配,您 可以使用filter函數把不符合的檔案移走參閱字元串替代和分析函數)︰
files = foo.elc bar.o lose.o
$(filter %.o,$(files)): %.o: %.c $(CC) -c $(CFLAGS) $< -o $@ $(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte-compile $<
個例子中,‘$(filter %.o,$(files))'的結果是‘bar.o lose.o',第一個靜態樣式規則是將相應的C語言源檔案編譯更新為 OBJ檔案,‘$(filter %.elc,$(files))' 的結果是‘foo.elc'由‘foo.el構造 另一個例子怎樣在靜態樣式規則中使用$*’︰
bigoutput littleoutput : %output : text.g generate text.g -$* > $@
命令generate執行時,$*展開為俓(stem),即‘biglittle者之
4.10.2靜態樣式規則和隱含規則
靜態樣式規則和定義為樣式規則的隱含規則有相同地方(詳細參閱定義與重新定義樣式規則)。方都目 標的格式和構造先決條件名的格式差異make使用它時機不同。
隱含規則可以應於任何於它匹配的目標,但僅僅是在目標沒有具體規則指定命令先決條件可以搜尋
況下應。如果有多條隱含規則適合,僅有執行其中一條規則依據隱含規則的定義次序。 相靜態樣式規則用在規則中指的目標不能應其它任何目標它的使用模式對於各個目標固定變的。如果使用兩個有命令的規則衝突錯誤
靜態樣式規則如下原因可能比隱含規則更 文件名不能按句法分類的但可以給出列表的文件使用靜態樣式規則可以重載隱含規則鏈
如果不能精確確定使用的路俓(stem),您不能確定一些無關要的文件是否導致make使用錯誤的隱含規則(因為
隱含規則的選根據其定義次序使用靜態樣式規則則沒有這些不確︰每一條規則都精確的用指定的 目標上。
4.11雙冒號規則(::)
雙冒號規則(::)在目標名後使用‘︰︰’代替‘︰’的規則。當同一個目標在一條以上的規則中出現時,雙冒號規則(:
:)和常的規則處理有所差異
一目標在多條規則中出現時,所有的規則必須是同一類型么都是雙冒號規則(::)么都是普通規則。如果們 都是雙冒號規則(::)則它們之間都是相互。如果目標一個雙冒號規則(::)的先決條件’,雙冒號規則(:
:)的命令執行。這可導致具有一目標雙冒號規則(::)全部或部分執行。
雙冒號規則(::)就是將具有相同目標的多條規則相互分離,每一條雙冒號規則(::)立的執行,就這些規則的目不同一樣
對於一個目標的雙冒號規則(::)按照在makefile檔案中出現序執行。然而雙冒號規則(::)真正義的合是雙冒 號規則(::)和執行關的合。
雙冒號規則(::)有糊難解,僅僅提供了一種在特定情況下根據更新的先決條件檔案不同,而不同模 式更新目標的。實用雙冒號規則(::)的情況 一個雙冒號規則(::)都應該指定命令,如果沒有指定命令使用隱含規則。詳細內容參閱使用隱含規則
4.12 自動生成先決條件
在為一個程式編寫的makefile檔案中常常要寫僅僅是說明些OBJ檔案依靠頭檔案的規則如,如果 main.c透過一條#include語句使用defs.h’,您需要寫入的規則
main.o: defs.h
您需條規則讓make如果‘defs.h旦改必須重新構造main.o’。由您可以明對於一個的程式您需 要在makefile檔案中寫樣的規則。而且加或一條#include語句您必須十小心地makefile檔案 為避免煩惱,現代C編譯器根據原程式中的#include語句可以編寫這些規則。如果需要使用這種能,通常可在 編譯程式加入-M’開
如,下面的命令
cc -M main.c
如下輸出︰
main.o : main.c defs.h
您就不必自寫這些規則編譯器可以您完這些工作。 注意,由於在makefile檔案中及構造main.o’,因main.o’將永遠不會隱含規則檔案進行搜尋 ,這同時意make不會在使用它後自動刪除它參閱隱含規則鏈
對於舊版的make程式過一個命令,如‘make depend’,利用編譯的特生成先決條件慣。這些 命令將產生一個depend檔案,該檔案引入(include)所有自動生成的先決條件;然後makefile檔案可以使用include命令讀入參閱引入(include)其它makefile檔案)。
在GNU make中重新構造makefile檔案的特使例成為舊式的東西──永遠不必具體告訴make重新生成先 決條件,因為GNU make重新構造任何舊式的makefile檔案參閱Makefile檔案的重新生成的過程
我們使用自動生成先決條件的慣是把makefile檔案和程式檔案一一對應來。如,對每一個程式檔案name.c有一名為name.d的makefile檔案和它對應,該makefile檔案中列出了名為name.oOBJ檔案所先決條件
的檔案。這種模式的優點是僅程式檔案變的情況下才要重新掃描生成新的先決條件
這裡有一個根據C語言源程式name.c生成名為name.d先決條件檔案的樣式規則
%.d: %.c set -e; $(CC) -M $(CPPFLAGS) $< \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@
定義樣式規則的訊參閱定義與重新定義樣式規則。‘-e’開關是告訴shell如果$(CC)命令執行零狀態退
)立即退出。正情況下,shell退出時有最後一個命令在管中的狀態sed,make不能注意到編譯器產生的狀態
對於GNU C編譯器您可以使用-MM’開關代替-M’,這是略了有關係統頭檔案的先決條件。詳細內容參閱《GNU CC使用手冊中控制預處理選項 命令Sed的作用是翻
如)︰
main.o : main.c defs.h
到︰
main.o main.d : main.c defs.h
使一個.d檔案和與之對應.o檔案依靠相同程式檔案和檔案,據Make可以知如果任一個 程式檔案和檔案生變化必須重新構造先決條件檔案旦您定義重新構造.d檔案的規則,您可以使用使用include命令讀入,(參閱引入(include)其它 makefile檔案),
如︰
sources = foo.c bar.c include $(sources:.c=.d)
(這個例子中使用一個代替變數參照從源程式檔案foo.c bar.c'先決條件檔案foo.d bar.d'。詳細內容參 閱替換引用。)以,‘.d的makefile檔案和其它makefile檔案一樣,即使沒用任何進一的指令make要的候重新建它們。參閱Makefile檔案的重新生成過程
5在規則中使用命令
規則中的命令系列shell命令行一條一條的序執行一條命令行可以分號為 在目標-先決條件行後面外,所有的命令行必須以TAB。空行與在命令行中間出現,處理被忽略。 (但是必須注意,以TAB始的’不是空命令參閱使用空命令。)使用多種不同的shell程式,如果在makefile檔案中沒有指其它的shell則使用預設的/bin/sh’解釋makefile檔案 中的命令參閱命令執行 使用的shell種類決定了是否能夠在命令行釋以編寫使用的語法。當使用‘/bin/sh’作為shell,以‘#’開直延到該。‘#’不必在行首,而且‘#’不是的一
5.1 命令回顯
情況下make在執行命令之前首命令行,我們因這可將您編寫的命令輸出為回顯。 以‘@’起始的行不能回顯,‘@’輸給shell被丟棄型的情況,您可以在makefile檔案中使用一個僅僅用於列 印某內容的命令,如echo命令makefile檔案執行的進程
@echo About to make distribution files
使用make時給出‘-n‘--just-print’標誌僅僅回顯命令而不執行命令參閱選項概要。在這種情況下也有在情況下,所有的命令行回顯,即使以‘@’開的命令行回顯。這個標誌對於使用命令的情況下發現make哪些是必要的命令常有用。 ‘-s--silent標誌可以使make阻止所有命令回顯好像所有的行都以‘@’開一樣在makefile檔案中使用不
先決條件的特目標.SILENT的規則可以達到相同果(參閱內建的特殊目標名)。因‘@’使用更加靈活於現下基本使用特目標.SILENT
5.2執行命令
要執行命令更新目標時,每一命令行都會使用一個獨的子shell環境,保證該命令行得到執行。(實上,make可能影響結果俓(stem)。)
請注意︰這意設定變數的shell命令cd將不影響緊跟的命令行;如果您需要使用cd命令影響到下一個命 令,請把這兩個命令一行用分號開,這樣make將認為它們是一個單一的命令行,把起傳shell,然序執行它們。如︰
foo : bar/lose cd bar; gobble lose > ../foo
如果您喜歡一個單一的命令分成多個文字(text)行,您必須反斜線(\)作為一行的最後一行除外。這 多個文字(text)行過刪除反斜線(\)成一新行,然shell。如,下面的例子和前面的例子是同的
foo : bar/lose cd bar; \ gobble lose > ../foo
用作shell的程式是由變數SHELL指定預設情況下,使用程式/bin/sh作為shell 在MS_DOS執行,如果變數SHELL沒有指定變數COMSPEC的值用代替指定shell 在MS_DOS執行和在其它系統上執行,對於makefile檔案中設定變數SHELL的行的處理也不一樣。因為MS_DOS的 shell,‘command.com’,能十分有限,以許多make用向於安裝一個代替的shell。因在MS_DOS執行 make測變數SHELL的值根據它指定的Unix風格或DOS風格的shell變化它的行為。即使使用變數SHELL指
command.com’ ,make依然測變數SHELL的值。 如果變數SHELL指定Unix風格的shell在MS_DOS執行的make附加指定的shell是否能真正找到;如果不能找到 ,指定的shell在MS_DOS上,GNU make按照下步驟搜尋shell: 1在變數SHELL指定的目錄中如,如果makefile指`SHELL = /bin/sh'make當前路俓(stem)子目錄/bin’。
2當前路俓(stem)下。 3、按序搜尋變數PATH指定的目錄
在所有搜尋的目錄中make先尋指定的檔案(如例子中的sh’)。如果該檔案沒有存在,make將在上述目錄中搜
尋帶有定的執行檔案展開的檔案如︰‘.exe', .com', .bat', .btm', .sh'檔案和其它檔案等
如果上述過程中能夠搜尋一個shell則變數SHELL的值設定為所發現shell的路俓(stem)檔案名。然而如果上 力全部失變數SHELL的值將不改設定shell的行的有性將被忽略。這是在make執行的系統如果確實安裝了 Unix風格的shellmake支援的Unix風格shell特原因。 注意這shell的展開搜尋僅僅限制在makefile檔案中設定變數SHELL的情況。如果在環境或命令行中設定,希望您 定shell的路俓(stem)檔案名,而且全路俓(stem)檔案名在Unix系統中執行的一樣準確無
述的DOS特色的處理,而且您把 ‘sh.exe’安裝在變數PATH指定的目錄中或在makefile檔案內設定 `SHELL = /bin/sh' 和多數Unix的makefile檔案一樣),則在MS_DOS的執行效果和在Unix執行完全一樣。 不其它多數變數變數SHELL從不根據環境設定。這是因為環境變數SHELL指定使用的shell 程式。如果變數SHELL在環境中設定影響makefile檔案的功能,這是算的參閱環境變數。然而在MS- DOS和MS-WINDOWS中在環境中設定變數SHELL的值要使用的,因為在這些系統多數用設定變數
的值make可能變數指定要使用的值。在MS-DOS上,如果變數SHELL的設定對於make不合適,您可以 設定變數MAKESHELL用指定make使用的shell;這種設定使變數SHELL的值
5.3 並行執行
GNU make可以同時執行條命令。正常情況下,make一次執行一個命令,待它完成後在執行下一條命令。然而,使用 -j--jobs選項將告訴make同時執行多條命令在MS-DOS上,‘-j選項沒有作用,因該系統不支援多進程 處理
如果‘-j’選項後面跟一個整數,該整數表示一次執行的命令的條數;這稱為job slots數。如果‘-j’選項後面沒有數 ,也就是沒有對job slots的數目限制。預設的job slots數是一,這意著按序執行(一次執行一條命令)。同時執行多條 命令的一個不理想的結果是每條命令產生的輸出與每條命令發的時間對應,即命令產生的回顯可能混亂
另一個問題兩個進程不能使用一設以必須確定一次有一條命令make能保證正在執 行的命令的標準輸其它的標準輸將失。這意著如果同時從準輸入設入的話,對於 多數子進程將產命的錯誤(即產生一個Broken pipe信號)。
命令一個有的標準輸入或為make的標準輸入設是不可預測的。第一條執 行的命令是第一個得到準輸成一條命令後一條動的另一條命令將得到下一個標準輸等等
如果我們找到一個更替換,我們將改變make的種工作模式間,如果您使用並行處理的特點,您不應 該使用任何需要標準輸入的命令。如果您不使用點,任何需要標準輸入的命令將都能正常工作最後make的遞迴也導致出現問題詳細的內容參閱與子make通訊的選項。 如果一個命令一個號中退出),且該條命令生的錯誤不能略(參閱命令錯誤),剩餘 一目標的命令行將會停止工作。如果一條命令,而且‘-k--keep-going選項沒有給出(參閱選項概要 ),make放棄繼續執行。如果make由於原因(包括信要中子進程在執行到這些子進 再實際退出。 當系統正滿負荷執行時,您許希望負荷再添任務。這時,您可以使用‘-|選項告訴make根據平均負荷
執行的任務。‘-|--max-load選項一一個如︰
-| 2.5 將不make在平均負荷高2.5啟動一項任務。‘-|選項如果沒有據,則取前面‘-|’給定的負荷精確地,當make動一項任務時,而至少一項任務正在執行則它查當前平均負荷;如果不 於‘-|’選項定的負荷時,make平均負荷於限制或所有其它任務完成後啟動其它任務。 預設情況下沒有負荷
5.4命令錯誤
一個shell命令回後make查該命令退的狀態。如果該命令成地完成,下一個命令行就會在新的子shell環境 中執行,當最後一個命令行成後,這條規則告完。如果出現錯誤退狀態), make放棄當前的規則 ,也許是所有的規則一個特定的命令不是出現了問題如︰您可能使用mkdir命令建一個目錄,如果該目錄經存 mkdir將報告錯誤,但您時也許要make繼續執行
Loading...
+ 63 hidden pages