GNU make中文手冊-第二章: GNU make 介紹
作者: hew 發(fā)布日期:
2006-3-21
查看數(shù):
151
出自: http://www.
第二章: GNU make 介紹
--------------------------------------------------------------------------------
make在執(zhí)行時(shí),需要一個(gè)命名為Makefile的文件。這個(gè)文件告訴make以何種方式編譯源代碼和鏈接程序。典型地,可執(zhí)行文件可由一些.o文件按
照一定的順序生成或者更新。如果在你的工程中已經(jīng)存在一個(gè)或者多個(gè)正確的Makefile。當(dāng)對工程中的若干源文件修改以后,需要根據(jù)修改來更新可執(zhí)行文
件或者庫文件,正如前面提到的你只需要在shell下執(zhí)行“make”。make會(huì)自動(dòng)根據(jù)修改情況完成源文件的對應(yīng).o文件的更新、庫文件的更新、最終
的可執(zhí)行程序的更新。
make通過比較對應(yīng)文件(規(guī)則的目標(biāo)和依賴,)的最后修改時(shí)間,來決定哪些文件需要更新、那些文件不需要更新。對需要更新的文件make就執(zhí)行數(shù)據(jù)庫中
所記錄的相應(yīng)命令(在make讀取Makefile以后會(huì)建立一個(gè)編譯過程的描述數(shù)據(jù)庫。此數(shù)據(jù)庫中記錄了所有各個(gè)文件之間的相互關(guān)系,以及它們的關(guān)系描
述)來重建它,對于不需要重建的文件make什么也不做。
而且可以通過make的命令行選項(xiàng)來指定需要重新編譯的文件。
--------------------------------------------------------------------------------
Problems and Bugs
=================
If you have problems with GNU `make‘ or think you‘ve found a bug,
please report it to the developers; we cannot promise to do anything
but we might well want to fix it.
Before reporting a bug, make sure you‘ve actually found a real
bug.Carefully reread the documentation and see if it really says you
can do what you‘re trying to do. If it‘s not clear whether you should
be able to do something or not, report that too; it‘s a bug in the
documentation!
Before reporting a bug or trying to fix it yourself, try to isolate it
to the smallest possible makefile that reproduces the problem. Then
send us the makefile and the exact results `make‘ gave you, including
any error or warning messages. Please don‘t paraphrase these messages:
it‘s best to cut and paste them into your report. When generating this
small makefile, be sure to not use any non-free or unusual tools in
your commands: you can almost always emulate what such a tool would do
with simple shell commands. Finally, be sure to explain what you
expected to occur; this will help us decide whether the problem was
really in the documentation.
Once you have a precise problem you can report it in one of two ways.Either send electronic mail to:
bug-make@
or use our Web-based project management tool, at:
http://savannah./projects/make/
In addition to the information above, please be careful to include the
version number of `make‘ you are using. You can get this information
with the command `make --version‘. Be sure also to include the type of
machine and operating system you are using. One way to obtain this
information is by looking at the final lines of output from the command
`make --help‘.
--------------------------------------------------------------------------------
以上時(shí)GNU make的bug反饋方式。如果在你使用GNU make過程中。發(fā)現(xiàn)bug或者問題。可以通過以上的方式和渠道反饋。
好了。開始我們的神奇之旅吧!
2.1 Makefile簡介
在執(zhí)行make之前,需要一個(gè)命名為Makefile的特殊文件(本文的后續(xù)將使用Makefile作為這個(gè)特殊文件的文件名)來告訴make需要做什么(完成什么任務(wù)),該怎么做。通常,make工具主要被用來進(jìn)行工程編譯和程序鏈接。
本節(jié)將分析一個(gè)簡單的Makefile,它對一個(gè)包含8個(gè)C的源代碼和三個(gè)頭文件的工程進(jìn)行編譯和鏈接。這個(gè)Makefile提供給了make必要的信
息,make程序根據(jù)Makefile中的規(guī)則描述執(zhí)行相關(guān)的命令來完成指定的任務(wù)(如:編譯、鏈接和清除編譯過程文件等)。復(fù)雜的Makefile我們
將會(huì)在本文后續(xù)進(jìn)行討論。
當(dāng)使用make工具進(jìn)行編譯時(shí),工程中以下幾種文件在執(zhí)行make時(shí)將會(huì)被編譯(重新編譯):
1. 所有的源文件沒有被編譯過,則對各個(gè)C源文件進(jìn)行編譯并進(jìn)行鏈接,生成最后的可執(zhí)行程序;
2. 每一個(gè)在上次執(zhí)行make之后修改過的C源代碼文件在本次執(zhí)行make時(shí)將會(huì)被重新編譯;
3. 頭文件在上一次執(zhí)行make之后被修改。則所有包含此頭文件的C源文件在本次執(zhí)行make時(shí)將會(huì)被重新編譯。
后兩種情況是make只將修改過的C源文件重新編譯生成.o文件,對于沒有修改的文件不進(jìn)行任何工作。重新編譯過程中,任何一個(gè)源文件的修改將產(chǎn)生新的對應(yīng)的.o文件,新的.o文件將和以前的已經(jīng)存在、此次沒有重新編譯的.o文件重新連接生成最后的可執(zhí)行程序。
首先讓我們先來看一些Makefile相關(guān)的基本知識。
2.2 Makefile規(guī)則介紹
一個(gè)簡單的Makefile描述規(guī)則組成:
TARGET... : PREREQUISITES...
COMMAND
...
...
target:規(guī)則的目標(biāo)。通常是程序中間或者最后需要生成的文件名??梢允?o文件、也可以是最后的可執(zhí)行程序的文件名。另外,目標(biāo)也可以是一個(gè)make執(zhí)行的動(dòng)作的名稱,如目標(biāo)“clean”,成這樣的目標(biāo)是“偽目標(biāo)”。
prerequisites:規(guī)則的依賴。生成規(guī)則目標(biāo)所需要的文件名列表。通常一個(gè)目標(biāo)依賴于一個(gè)或者多個(gè)文件。
command:規(guī)則的命令行。是make程序所有執(zhí)行的動(dòng)作(任意的shell命令或者可在shell下執(zhí)行的程序)。
一個(gè)規(guī)則可以有多個(gè)命令行,每一條命令占一行。注意:每一個(gè)命令行必須以[Tab]字符開始,[Tab]字符告訴make此行是一個(gè)命令行。make按照命令完成相應(yīng)的動(dòng)作。這也是書寫Makefile中容易產(chǎn)生,而且比較隱蔽的錯(cuò)誤。
命令就是在任何一個(gè)目標(biāo)的依賴文件發(fā)生變化后重建目標(biāo)的動(dòng)作描述。一個(gè)目標(biāo)可以沒有依賴而只有動(dòng)作(指定的命令)。比如Makefile中的目標(biāo)“clean”,此目標(biāo)沒有依賴,只有命令。它所指定的命令用來刪除make過程產(chǎn)生的中間文件(清理工作)。
在Makefile中“規(guī)則”就是描述在什么情況下、如何重建規(guī)則的目標(biāo)文件,通常規(guī)則中包括了目標(biāo)的依賴關(guān)系(目標(biāo)的依賴文件)和重建目標(biāo)的命令。
make執(zhí)行重建目標(biāo)的命令,來創(chuàng)建或者重建規(guī)則的目標(biāo)(此目標(biāo)文件也可以是觸發(fā)這個(gè)規(guī)則的上一個(gè)規(guī)則中的依賴文件)。規(guī)則包含了目標(biāo)和依賴的關(guān)系以及更
新目標(biāo)所要求的命令。
Makefile中可以包含除規(guī)則以外的部分。一個(gè)最簡單的Makefile可能只包含規(guī)則描述。規(guī)則在有些Makefile中可能看起來非常復(fù)雜,但是無論規(guī)則的書寫是多么的復(fù)雜,它都符合規(guī)則的基本格式。
2.3 簡單的示例
本小節(jié)開始我們在第一小節(jié)中提到的例子。此例子由3個(gè)頭文件和8個(gè)C文件組成。我們講述寫一個(gè)簡單的Makefile,來描述如何創(chuàng)建最終的可執(zhí)行文件“edit”,此可執(zhí)行文件依賴于8個(gè)C源文件和3個(gè)頭文件。Makefile文件的內(nèi)容如下:
#sample Makefile
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
在書寫時(shí),一個(gè)較長行可以使用反斜線(\)分解為多行,這樣做可以使Makefile清晰、容易閱讀。注意:反斜線之后不能有空格(這也是大家最容易犯的
錯(cuò)誤,而且錯(cuò)誤比較隱蔽)。大家在書寫Makefile時(shí),推薦者中將較長行分解為使用反斜線連接得多個(gè)行的方式。當(dāng)我們完成了這個(gè)Maekfile以
后;創(chuàng)建可執(zhí)行程序“edit”,你所要做的就是在包含此Makefile的目錄(當(dāng)然也在代碼所在的目錄)下輸入命令“make”。刪除已經(jīng)本目錄下生
成的文件和所有的.o文件,只需要輸入命令“make clean”就可以了。
在這個(gè)Makefile中,目標(biāo)(target)包含:可執(zhí)行文件“edit”和.o文件(main.o,kbd.o….),依賴
(prerequisites)就是冒號后面的那些 .c 文件和
.h文件。所有的.o文件既是依賴(相對于可執(zhí)行程序edit)又是目標(biāo)(相對于.c和.h文件)。命令包括 “cc –c maic.c”、“cc
–c kbd.c”……
目標(biāo)是一個(gè)文件時(shí),當(dāng)它的任何一個(gè)依賴文件被修改以后,這個(gè)目標(biāo)文件將會(huì)被重新編譯或者重新連接。當(dāng)然,此目標(biāo)的任何一個(gè)依賴文件如果有必要?jiǎng)t首先會(huì)被重
新編譯。在這個(gè)例子中,“edit”的依賴為8個(gè).o文件;而“main.o”的依賴文件為“main.c”和“defs.h”。當(dāng)“main.c”或者
“defs.h”被修改以后,再次執(zhí)行“make”時(shí)“main.o”就會(huì)被更新(其它的.o文件不會(huì)被更新),同時(shí)“main.o”
的更新將會(huì)導(dǎo)致“edit”被更新。
在描述目標(biāo)和依賴之下的shell命令行,它描述了如何更新目標(biāo)文件。命令行必需以[Tab]鍵開始,以和Makefile其他行區(qū)別。就是說所有的命令
行必需以[Tab]
字符開始,但并不是所有的以[Tab]鍵出現(xiàn)行都是命令行。但make程序會(huì)把出現(xiàn)在第一條規(guī)則之后的所有的以[Tab]字符開始的行都作為命令行來處
理。(要記?。簃ake程序不關(guān)心命令是如何工作的,對目標(biāo)文件的更新需要你在規(guī)則的描述中提供正確的命令。“make”程序所做的就是當(dāng)目標(biāo)程序需要更
新時(shí)執(zhí)行規(guī)則所定義的命令)。
目標(biāo)“clean”不是一個(gè)文件,它僅僅代表了執(zhí)行一個(gè)動(dòng)作的標(biāo)識。通常情況下,不需要執(zhí)行這個(gè)規(guī)則所定義的動(dòng)作,因此目標(biāo)“clean”沒有出現(xiàn)在其它
規(guī)則的依賴列表中。在執(zhí)行make時(shí),它所指定的動(dòng)作不會(huì)被執(zhí)行。除非執(zhí)行make時(shí)明確地指定它作為重建目標(biāo)。而且目標(biāo)“clean”沒有任何依賴文
件,它只有一個(gè)目的,就是通過這個(gè)目標(biāo)名來執(zhí)行它所定義的命令。Makefile中把那些沒有任何依賴只有執(zhí)行動(dòng)作的目標(biāo)稱為“偽目標(biāo)”(phony
targets)。執(zhí)行“clean”目標(biāo)所定義的命令,可在shell下輸入:make clean。
2.4 make如何工作
默認(rèn)的情況下,make執(zhí)行Makefile中的第一個(gè)規(guī)則,此規(guī)則的第一個(gè)目標(biāo)稱之為“最終目的”或者“終極目標(biāo)”(就是一個(gè)Makefile最終需要更新或者創(chuàng)建的目標(biāo))。
上例的Makefile,目標(biāo)“edit”在Makefile中是第一個(gè)目標(biāo),因此它就是make的“終極目標(biāo)”。當(dāng)修改了任何C源文件或者頭文件后,執(zhí)行make將會(huì)重建終極目標(biāo)“edit”。
當(dāng)在shell提示符下輸入“make”命令以后。make讀取當(dāng)前目錄下的Makefile文件,并將Makefile文件中的第一個(gè)目標(biāo)作為其“終極
目標(biāo)”,開始處理第一個(gè)規(guī)則(終極目標(biāo)所在的規(guī)則)。在我們的例子中,第一個(gè)規(guī)則就是目標(biāo)“edit”所在的規(guī)則。規(guī)則描述了“edit”的依賴關(guān)系,并
定義了鏈接.o文件生成目標(biāo)“edit”的命令;
make在處理這個(gè)規(guī)則之前,首先將處理目標(biāo)“edit”的所有的依賴文件(例子中的那些.o文件)的更新規(guī)則;對包含這些.o文件的規(guī)則進(jìn)行處理。對.
o文件所在的規(guī)則的處理有下列三種情況:
1. 目標(biāo).o文件不存在,使用其描述規(guī)則創(chuàng)建它;
2. 目標(biāo).o文件存在,目標(biāo).o文件所依賴的.c源文件、.h文件中的任何一個(gè)比目標(biāo).o文件“更新”(在上一次make之后被修改)。則根據(jù)規(guī)則重新編譯生成它;
3. 目標(biāo).o文件存在,目標(biāo).o文件比它的任何一個(gè)依賴文件(的.c源文件、.h文件)“更新”(它的依賴文件在上一次make之后沒有被修改),則什么也不做。
這些.o文件所在的規(guī)則之所以會(huì)被執(zhí)行,是因?yàn)檫@些.o文件出現(xiàn)在“終極目標(biāo)”的依賴列表中。如果在Makefile中一個(gè)規(guī)則所描述的目標(biāo)不是“終極目
標(biāo)”所依賴的(或者“終極目標(biāo)”的依賴文件所依賴的),那么這個(gè)規(guī)則將不會(huì)被執(zhí)行。除非明確指定這個(gè)規(guī)則(可以通過make的命令行指定重建目標(biāo),那么這
個(gè)目標(biāo)所在的規(guī)則就會(huì)被執(zhí)行,例如 “make
clean”)。在編譯或者重新編譯生成一個(gè).o文件時(shí),make同樣會(huì)去尋找它的依賴文件的重建規(guī)則(是這樣一個(gè)規(guī)則:這個(gè)依賴文件在規(guī)則中作為目標(biāo)出
現(xiàn)),就是.c和.h文件的重建規(guī)則。在上例的Makefile中沒有哪個(gè)規(guī)則的目標(biāo)是.c或者.h文件,所以沒有重建.c和.h文件的規(guī)則。不過C言語
的源程序文件可以使用工具Bison或者Yacc來生成(具體用法可參考相應(yīng)的手冊)。
完成了對.o文件的創(chuàng)建(第一次編譯)或者更新之后,make程序?qū)⑻幚斫K極目標(biāo)“edit”所在的規(guī)則,分為以下三種情況:
1. 目標(biāo)文件“edit”不存在,則執(zhí)行規(guī)則創(chuàng)建目標(biāo)“edit”。
2. 目標(biāo)文件“edit”存在,其依賴文件中有一個(gè)或者多個(gè)文件比它“更新”,則根據(jù)規(guī)則重新鏈接生成“edit”。
3. 目標(biāo)文件“edit”存在,它比它的任何一個(gè)依賴文件都“更新”,則什么也不做。
上例中,如果更改了源文件“insert.c”后執(zhí)行make,“insert.o”將被更新,之后終極目標(biāo)“edit”將會(huì)被重生成;如果我們修改了頭
文件“command.h”之后運(yùn)行“make”,那么“kbd.o”、“command.o”和“files.o”將會(huì)被重新編譯,之后同樣終極目標(biāo)
“edit”也將被重新生成。
以上我們通過一個(gè)簡單的例子,介紹了Makefile中目標(biāo)和依賴的關(guān)系。對于Makefile中的目標(biāo)。在執(zhí)行“make”時(shí)首先執(zhí)行終極目標(biāo)所在的規(guī)
則,接下來一層層地去尋找終極目標(biāo)的依賴文件所在的規(guī)則并執(zhí)行。當(dāng)終極目標(biāo)的規(guī)則被完全的展開以后,make將從最后一個(gè)被展開的規(guī)則處開始執(zhí)行,之后處
理倒數(shù)第二個(gè)規(guī)則,……依次回退。最后一步執(zhí)行的就是終極目標(biāo)所在的規(guī)則。整個(gè)過程就類似于C語言中的遞歸實(shí)現(xiàn)一樣。在更新(或者創(chuàng)建)終極目標(biāo)的過程
中,如果出現(xiàn)錯(cuò)誤make就立即報(bào)錯(cuò)并退出。整個(gè)過程make只是負(fù)責(zé)執(zhí)行規(guī)則,而對具體規(guī)則所描述的依賴關(guān)系的正確性、規(guī)則所定義的命令的正確性不做任
何判斷。就是說,一個(gè)規(guī)則的依賴關(guān)系是否正確、描述重建目標(biāo)的規(guī)則命令行是否正確,make不做任何錯(cuò)誤檢查。
因此,需要正確的編譯一個(gè)工程。需要在提供給make程序的Makefile中來保證其依賴關(guān)系的正確性、和執(zhí)行命令的正確性。
2.5 指定變量
同樣是上邊的例子,我們來看一下終極目標(biāo)“edit”所在的規(guī)則:
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
在這個(gè)規(guī)則中.o文件列表出現(xiàn)了兩次;第一次:作為目標(biāo)“edit”的依賴文件列表出現(xiàn),第二次:規(guī)則命令行中作為“cc”的參數(shù)列表。這樣做所帶來的問
題是:如果我們需要為目標(biāo)“edit”增加一個(gè)的依賴文件,我們就需要在兩個(gè)地方添加(依賴文件列表和規(guī)則的命令中)。添加時(shí)可能在“edit”的依賴列
表中加入了、但卻忘記了給命令行中添加,或者相反。這樣給后期的維護(hù)和修改帶來了很多不方便,而且容易出現(xiàn)修改遺漏。
為了避免這個(gè)問題,在實(shí)際工作中大家都比較認(rèn)同的方法是,使用一個(gè)變量“objects”、“OBJECTS”、“objs”、“OBJS”、“obj”
或者“OBJ”來作為所有的.o文件的列表的替代。在使用到這些文件列表的地方,使用此變量來代替。在上例的Makefile中可是添加這樣一行:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
“objects”作為一個(gè)變量,它代表所有的.o文件的列表。在定義了此變量后,我們就可以在需要使用這些.o文件列表的地方使用“$(objects)”來表示它,而不需要羅列所有的.o文件列表。因此上例的規(guī)則就可以這樣寫:
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
…….
…….
clean :
rm edit $(objects)
需要增加或者去掉一個(gè).o文件時(shí)。我們只需要改變“objects”的定義(加入或者去掉若干個(gè).o文件)。這樣做不但減少維護(hù)的工作量,而且可以避免由于遺漏而產(chǎn)生錯(cuò)誤的可能。
2.6 自動(dòng)推導(dǎo)規(guī)則
在使用make編譯.c源文件時(shí),可以省略編譯一個(gè).c文件所使用的命令。這是因?yàn)閙ake存在一個(gè)默認(rèn)的規(guī)則,能夠自動(dòng)完成對.c文件的編譯并生成對應(yīng)
的.o文件。它執(zhí)行命令“cc -c”來編譯.c源文件。對于上邊的例子,此默認(rèn)規(guī)則就使用命令“cc -c main.c -o
main.o”來創(chuàng)建文件“main.o”。因此對一個(gè)目標(biāo)文件是“N.o”,倚賴文件是“N.c”的規(guī)則??梢允÷云湟?guī)則的命令行,使用make的默認(rèn)
命令。此默認(rèn)規(guī)則稱為make的隱含規(guī)則。
我們書寫Makefile時(shí),對于一個(gè).c文件如果使用make的隱含規(guī)則,那么它會(huì)被自動(dòng)作為對應(yīng).o文件的一個(gè)依賴文件(對應(yīng)是指:文件名除后綴外,其余都相同的兩個(gè)文件)。因此我們也可以在規(guī)則中省略目標(biāo)的倚賴.c文件。
我們上邊的例子就可以以更加簡單的方式書寫,使用了變量“objects”。簡化版本的Makefile如下:
# sample 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更接近于我們實(shí)際的應(yīng)用。(關(guān)于目標(biāo)“clean”的詳細(xì)說明我們在后邊。
make的隱含規(guī)則在實(shí)際工程的make中會(huì)經(jīng)常使用,它使得編譯過程變得方便。幾乎在所有的Makefile中都用到了make的隱含規(guī)則,make的隱含規(guī)則是非常重要的一個(gè)概念。后續(xù)我們會(huì)在第九章會(huì)專門討論make的隱含規(guī)則。
2.7 另類風(fēng)格的makefile
Makefile中,目標(biāo)使用隱含規(guī)則生成,我們就可以也可以書寫另外一種風(fēng)格Makefile。在這個(gè)Makefile中,根據(jù)依賴而不是目標(biāo)對規(guī)則進(jìn)行分組。上例的Makefile就可以這樣來實(shí)現(xiàn):
#sample 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”作為所有.o文件的依賴文件。其它兩個(gè)頭文件作為其對應(yīng)規(guī)則的目標(biāo)中所列舉的所有.o文件的依賴文件。
但是這種風(fēng)格的Makefile并不值得我們借鑒。問題在于:同時(shí)把多個(gè)目標(biāo)文件的依賴放在同一個(gè)規(guī)則中進(jìn)行描述(一個(gè)規(guī)則中含有多個(gè)目標(biāo)文件),這樣導(dǎo)
致規(guī)則定義不明了,比較混亂。建議大家不要在Makefile中采用這種方式了書寫。否則后期維護(hù)將會(huì)是一件非常痛苦的事情。
書寫規(guī)則建議的方式是:單目標(biāo),多依賴。就是說盡量要做到一個(gè)規(guī)則中只存在一個(gè)目標(biāo)文件,可有多個(gè)依賴文件。盡量避免多目標(biāo),單依賴的方式。這樣后期維護(hù)也會(huì)非常方便,而且Makefile會(huì)更清晰、明了。
2.8 清除工作目錄過程文件
在Makefile中的規(guī)則也可以完成除編譯以外的任務(wù)。例如:前邊提到的實(shí)現(xiàn)清除當(dāng)前目錄中在編譯過程中生成的文件(edit和哪些.o文件)的規(guī)則:
clean :
rm edit $(objects)
在實(shí)際應(yīng)用時(shí),我們會(huì)把這個(gè)規(guī)則寫成如下稍微復(fù)雜一些的樣子。以防止出現(xiàn)始料未及的情況。
.PHONY : clean
clean :
-rm edit $(objects)
這兩個(gè)實(shí)現(xiàn)有兩點(diǎn)不同: 1. 通過“.PHONY”特殊目標(biāo)將“clean”目標(biāo)聲明為偽目標(biāo)。防止當(dāng)磁盤上存在一個(gè)名為“clean”文件時(shí),“clean”所在規(guī)則的命令無法執(zhí)行。2. 在命令行之前使用“-”,意思是忽略命令“rm”的執(zhí)行錯(cuò)誤。
這樣的一個(gè)目標(biāo)在Makefile中,不能將其作為終極目標(biāo)(Makefile的第一個(gè)目標(biāo))。因?yàn)槲覀兊某踔圆⒉皇钱?dāng)你在命令行上輸入make以后執(zhí)行
刪除動(dòng)作。而是要?jiǎng)?chuàng)建或者更新程序。在我們上邊的例子中。就是在輸入make以后要需要對目標(biāo)“edit”進(jìn)行創(chuàng)建或者重建。
上例中因?yàn)槟繕?biāo)“clean”沒有出現(xiàn)在終極目標(biāo)“edit”依賴關(guān)系中,所以我們執(zhí)行“make”時(shí),目標(biāo)“clean”所在的規(guī)則將不會(huì)被處理。如果需要執(zhí)行此規(guī)則,需要在make的命令行選項(xiàng)中明確指定這個(gè)目標(biāo)(執(zhí)行“make clean”)。 |
|