版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、Makefile的編寫指導(dǎo)概述什么是makefile?或許很多Windows的程序員都不知道這個東西,因?yàn)槟切¦indows的IDE都為你做了這個工作,但我覺得要作一個好的和professional的程序員,makefile還是要懂。這就好像現(xiàn)在有這么多的HTML的編輯器,但如果你想成為一個專業(yè)人士,你還是要了解HTML的標(biāo)識的含義。特別在Unix下的軟件編譯,你就不能不自己寫makefile了,會不會寫makefile,從一個側(cè)面說明了一個人是否具備完成大型工程的能力。因?yàn)?,makefile關(guān)系到了整個工程的編譯規(guī)則。一個工程中的源文件不計數(shù),其按類型、功能、模塊分別放在若干個目錄中,mak
2、efile定義了一系列的規(guī)則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進(jìn)行更復(fù)雜的功能操作,因?yàn)閙akefile就像一個Shell腳本一樣,其中也可以執(zhí)行操作系統(tǒng)的命令。makeefille帶來來的好處處就是“自自動化編編譯”,一旦旦寫好,只需要要一個mmakee命令,整個工工程完全全自動編編譯,極極大的提提高了軟軟件開發(fā)發(fā)的效率率。maake是是一個命命令工具具,是一一個解釋釋makkefiile中中指令的的命令工工具,一一般來說說,大多多數(shù)的IIDE都都有這個個命令,比如:Dellphii的maake,VissuallC+的nmmakee,Liinuxx下
3、GNNU的mmakee??梢娨?,maakeffilee都成為為了一種種在工程程方面的的編譯方方法。現(xiàn)在講述述如何寫寫makkefiile的的文章比比較少,這是我我想寫這這篇文章章的原因因。當(dāng)然然,不同同產(chǎn)商的的makke各不不相同,也有不不同的語語法,但但其本質(zhì)質(zhì)都是在在“文件依依賴性”上做文文章,這這里,我我僅對GGNU的的makke進(jìn)行行講述,我的環(huán)環(huán)境是RRedHHatLLinuux 88.0,makke的版版本是33.800。必竟竟,這個個makke是應(yīng)應(yīng)用最為為廣泛的的,也是是用得最最多的。而且其其還是最最遵循于于IEEEE 110033.2-19992標(biāo)準(zhǔn)準(zhǔn)的(PPOSIIX.22
4、)。在這篇文文檔中,將以CC/C+的源源碼作為為我們基基礎(chǔ),所所以必然然涉及一一些關(guān)于于C/CC+的的編譯的的知識,相關(guān)于于這方面面的內(nèi)容容,還請請各位查查看相關(guān)關(guān)的編譯譯器的文文檔。這這里所默默認(rèn)的編編譯器是是UNIIX下的的GCCC和CCC。關(guān)于程序序的編譯譯和鏈接接在此,我我想多說說關(guān)于程程序編譯譯的一些些規(guī)范和和方法,一般來來說,無無論是CC、C+、還還是paas,首首先要把把源文件件編譯成成中間代代碼文件件,在WWinddowss下也就就是 .objj文件,UNIIX下是是 .oo 文件件,即 Objjectt Fiile,這個動動作叫做做編譯(commpille)。然后再再把大量量
5、的ObbjecctFiile合合成執(zhí)行行文件,這個動動作叫作作鏈接(linnk)。編譯時,編譯器器需要的的是語法法的正確確,函數(shù)數(shù)與變量量的聲明明的正確確。對于于后者,通常是是你需要要告訴編編譯器頭頭文件的的所在位位置(頭頭文件中中應(yīng)該只只是聲明明,而定定義應(yīng)該該放在CC/C+文件件中),只要所所有的語語法正確確,編譯譯器就可可以編譯譯出中間間目標(biāo)文文件。一一般來說說,每個個源文件件都應(yīng)該該對應(yīng)于于一個中中間目標(biāo)標(biāo)文件(O文件件或是OOBJ文文件)。鏈接時,主要是是鏈接函函數(shù)和全全局變量量,所以以,我們們可以使使用這些些中間目目標(biāo)文件件(O文文件或是是OBJJ文件)來鏈接接我們的的應(yīng)用程程序。
6、鏈鏈接器并并不管函函數(shù)所在在的源文文件,只只管函數(shù)數(shù)的中間間目標(biāo)文文件(OObjeectFFilee),在在大多數(shù)數(shù)時候,由于源源文件太太多,編編譯生成成的中間間目標(biāo)文文件太多多,而在在鏈接時時需要明明顯地指指出中間間目標(biāo)文文件名,這對于于編譯很很不方便便,所以以,我們們要給中中間目標(biāo)標(biāo)文件打打個包,在Wiindoows下下這種包包叫“庫文件件”(LiibraaryFFilee),也也就是 .liib 文文件,在在UNIIX下,是Arrchiive Fille,也也就是 .a 文件??偨Y(jié)一下下,源文文件首先先會生成成中間目目標(biāo)文件件,再由由中間目目標(biāo)文件件生成執(zhí)執(zhí)行文件件。在編編譯時,編譯器器
7、只檢測測程序語語法,和和函數(shù)、變量是是否被聲聲明。如如果函數(shù)數(shù)未被聲聲明,編編譯器會會給出一一個警告告,但可可以生成成ObjjecttFille。而而在鏈接接程序時時,鏈接接器會在在所有的的Objjectt Fiile中中找尋函函數(shù)的實(shí)實(shí)現(xiàn),如如果找不不到,那那到就會會報鏈接接錯誤碼碼(LiinkeerErrrorr),在在VC下下,這種種錯誤一一般是:Linnk 220011錯誤,意思說說是說,鏈接器器未能找找到函數(shù)數(shù)的實(shí)現(xiàn)現(xiàn)。你需需要指定定函數(shù)的的Objjectt Fiile.好,言歸歸正傳,GNUU的maake有有許多的的內(nèi)容,閑言少少敘,還還是讓我我們開始始吧。Makeefille 介
8、介紹makee命令執(zhí)執(zhí)行時,需要一一個 MMakeefille 文文件,以以告訴mmakee命令需需要怎么么樣的去去編譯和和鏈接程程序。首先,我我們用一一個示例例來說明明Makkefiile的的書寫規(guī)規(guī)則。以以便給大大家一個個感興認(rèn)認(rèn)識。這這個示例例來源于于GNUU的maake使使用手冊冊,在這這個示例例中,我我們的工工程有88個C文文件,和和3個頭頭文件,我們要要寫一個個Makkefiile來來告訴mmakee命令如如何編譯譯和鏈接接這幾個個文件。我們的的規(guī)則是是:1)如果這這個工程程沒有編編譯過,那么我我們的所所有C文文件都要要編譯并并被鏈接接。2)如果這這個工程程的某幾幾個C文文件被修修
9、改,那那么我們們只編譯譯被修改改的C文文件,并并鏈接目目標(biāo)程序序。3)如果這這個工程程的頭文文件被改改變了,那么我我們需要要編譯引引用了這這幾個頭頭文件的的C文件件,并鏈鏈接目標(biāo)標(biāo)程序。只要我們們的Maakeffilee寫得夠夠好,所所有的這這一切,我們只只用一個個makke命令令就可以以完成,makke命令令會自動動智能地地根據(jù)當(dāng)當(dāng)前的文文件修改改的情況況來確定定哪些文文件需要要重編譯譯,從而而自己編編譯所需需要的文文件和鏈鏈接目標(biāo)標(biāo)程序。一、Maakeffilee的規(guī)則則在講述這這個Maakeffilee之前,還是讓讓我們先先來粗略略地看一一看Maakeffilee的規(guī)則則。targget
10、 . : preereqquissitees .ccommmandd.targget也也就是一一個目標(biāo)標(biāo)文件,可以是是ObjjecttFille,也也可以是是執(zhí)行文文件。還還可以是是一個標(biāo)標(biāo)簽(LLabeel),對于標(biāo)標(biāo)簽這種種特性,在后續(xù)續(xù)的“偽目標(biāo)標(biāo)”章節(jié)中中會有敘敘述。prerrequuisiitess就是,要生成成那個ttargget所所需要的的文件或或是目標(biāo)標(biāo)。commmandd也就是是makke需要要執(zhí)行的的命令。(任意意的Shhelll命令)這是一個個文件的的依賴關(guān)關(guān)系,也也就是說說,taargeet這一一個或多多個的目目標(biāo)文件件依賴于于preereqquissitees中的的文
11、件,其生成成規(guī)則定定義在ccommmandd中。說說白一點(diǎn)點(diǎn)就是說說,prrereequiisittes中中如果有有一個以以上的文文件比ttargget文文件要新新的話,commmannd所定定義的命命令就會會被執(zhí)行行。這就就是Maakeffilee的規(guī)則則。也就就是Maakeffilee中最核核心的內(nèi)內(nèi)容。說到底,Makkefiile的的東西就就是這樣樣一點(diǎn),好像我我的這篇篇文檔也也該結(jié)束束了。呵呵呵。還還不盡然然,這是是Makkefiile的的主線和和核心,但要寫寫好一個個Makkefiile還還不夠,我會以以后一點(diǎn)點(diǎn)一點(diǎn)地地結(jié)合我我的工作作經(jīng)驗(yàn)給給你慢慢慢到來。內(nèi)容還還多著呢呢。:)二、
12、一個個示例正如前面面所說的的,如果果一個工工程有33個頭文文件,和和8個CC文件,我們?yōu)闉榱送瓿沙汕懊嫠龅哪悄侨齻€規(guī)規(guī)則,我我們的MMakeefille應(yīng)該該是下面面的這個個樣子的的。editt : maiin.oo kbbd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.occc -oo eddit maiin.oo kbbd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.omainn.o : mmainn
13、.c deffs.hhcc -c maiin.cckbdd.o : kkbd.c ddefss.h commmannd.hhcc -c kbdd.cccommmandd.o : ccommmandd.c deffs.hh coommaand.hccc -cc coommaand.cdiispllay.o : diispllay.c ddefss.h buffferr.hccc -c ddispplayy.ciinseert.o : innserrt.cc deefs.h bbufffer.hccc -cc innserrt.ccseaarchh.o : ssearrch.c ddefss.h
14、buffferr.hccc -c ssearrch.cfiiless.o : ffilees.cc deefs.h bbufffer.h ccommmandd.hccc -c ffilees.ccutiils.o : uttilss.c deffs.hhcc -c utiils.cclleann :rrm eeditt maain.o kkbd.o ccommmandd.o dissplaay.oo iinseert.o ssearrch.o ffilees.oo uttilss.o反斜杠()是是換行符符的意思思。這樣樣比較便便于Maakeffilee的易讀讀。我們們可以把把這個內(nèi)內(nèi)容保存存在
15、文件件為“Makkefiile”或“makkefiile”的文件件中,然然后在該該目錄下下直接輸輸入命令令“makke”就可以以生成執(zhí)執(zhí)行文件件ediit。如如果要刪刪除執(zhí)行行文件和和所有的的中間目目標(biāo)文件件,那么么,只要要簡單地地執(zhí)行一一下“makkeclleann”就可以以了。在這個mmakeefille中,目標(biāo)文文件(ttargget)包含:執(zhí)行文文件eddit和和中間目目標(biāo)文件件(*.o),依賴文文件(pprerrequuisiitess)就是是冒號后后面的那那些.cc 文件件和 .h文件件。每一一個 .o 文文件都有有一組依依賴文件件,而這這些 .o 文文件又是是執(zhí)行文文件 eedi
16、tt的依賴賴文件。依賴關(guān)關(guān)系的實(shí)實(shí)質(zhì)上就就是說明明了目標(biāo)標(biāo)文件是是由哪些些文件生生成的,換言之之,目標(biāo)標(biāo)文件是是哪些文文件更新新的。在定義好好依賴關(guān)關(guān)系后,后續(xù)的的那一行行定義了了如何生生成目標(biāo)標(biāo)文件的的操作系系統(tǒng)命令令,一定定要以一一個Taab鍵作作為開頭頭。記住住,maake并并不管命命令是怎怎么工作作的,他他只管執(zhí)執(zhí)行所定定義的命命令。mmakee會比較較tarrgetts文件件和prrereequiisittes文文件的修修改日期期,如果果preereqquissitees文件件的日期期要比ttarggetss文件的的日期要要新,或或者taargeet不存存在的話話,那么么,maake
17、就就會執(zhí)行行后續(xù)定定義的命命令。這里要說說明一點(diǎn)點(diǎn)的是,cleean不不是一個個文件,它只不不過是一一個動作作名字,有點(diǎn)像像C語言言中的llablle一樣樣,其冒冒號后什什么也沒沒有,那那么,mmakee就不會會自動去去找文件件的依賴賴性,也也就不會會自動執(zhí)執(zhí)行其后后所定義義的命令令。要執(zhí)執(zhí)行其后后的命令令,就要要在maake命命令后明明顯得指指出這個個labble的的名字。這樣的的方法非非常有用用,我們們可以在在一個mmakeefille中定定義不用用的編譯譯或是和和編譯無無關(guān)的命命令,比比如程序序的打包包,程序序的備份份,等等等。三、maake是是如何工工作的在默認(rèn)的的方式下下,也就就是我
18、們們只輸入入makke命令令。那么么,1、maake會會在當(dāng)前前目錄下下找名字字叫“Makkefiile”或“makkefiile”的文件件。2、如果找找到,它它會找文文件中的的第一個個目標(biāo)文文件(ttargget),在上上面的例例子中,他會找找到“ediit”這個文文件,并并把這個個文件作作為最終終的目標(biāo)標(biāo)文件。3、如如果eddit文文件不存存在,或或是eddit所所依賴的的后面的的 .oo 文件件的文件件修改時時間要比比ediit這個個文件新新,那么么,他就就會執(zhí)行行后面所所定義的的命令來來生成eeditt這個文文件。44、如果果ediit所依依賴的.o文件件也存在在,那么么makke會在
19、在當(dāng)前文文件中找找目標(biāo)為為.o文文件的依依賴性,如果找找到則再再根據(jù)那那一個規(guī)規(guī)則生成成.o文文件。(這有點(diǎn)點(diǎn)像一個個堆棧的的過程)5、當(dāng)當(dāng)然,你你的C文文件和HH文件是是存在的的啦,于于是maake會會生成.o 文文件,然然后再用用 .oo 文件件生命mmakee的終極極任務(wù),也就是是執(zhí)行文文件eddit了了。這就是整整個maake的的依賴性性,maake會會一層又又一層地地去找文文件的依依賴關(guān)系系,直到到最終編編譯出第第一個目目標(biāo)文件件。在找找尋的過過程中,如果出出現(xiàn)錯誤誤,比如如最后被被依賴的的文件找找不到,那么mmakee就會直直接退出出,并報報錯,而而對于所所定義的的命令的的錯誤,或
20、是編編譯不成成功,mmakee根本不不理。mmakee只管文文件的依依賴性,即,如如果在我我找了依依賴關(guān)系系之后,冒號后后面的文文件還是是不在,那么對對不起,我就不不工作啦啦。通過上述述分析,我們知知道,像像cleean這這種,沒沒有被第第一個目目標(biāo)文件件直接或或間接關(guān)關(guān)聯(lián),那那么它后后面所定定義的命命令將不不會被自自動執(zhí)行行,不過過,我們們可以顯顯示要mmakee執(zhí)行。即命令令“makkeclleann”,以此此來清除除所有的的目標(biāo)文文件,以以便重編編譯。于是在我我們編程程中,如如果這個個工程已已被編譯譯過了,當(dāng)我們們修改了了其中一一個源文文件,比比如fiile.c,那那么根據(jù)據(jù)我們的的依賴
21、性性,我們們的目標(biāo)標(biāo)fille.oo會被重重編譯(也就是是在這個個依性關(guān)關(guān)系后面面所定義義的命令令),于于是fiile.o的文文件也是是最新的的啦,于于是fiile.o的文文件修改改時間要要比eddit要要新,所所以eddit也也會被重重新鏈接接了(詳詳見eddit目目標(biāo)文件件后定義義的命令令)。而如果我我們改變變了“commmannd.hh”,那么么,kddb.oo、coommaand.o和ffilees.oo都會被被重編譯譯,并且且,eddit會會被重鏈鏈接。四、maakeffilee中使用用變量在上面的的例子中中,先讓讓我們看看看eddit的的規(guī)則:editt : maiin.oo kb
22、bd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.occc -oo eddit maiin.oo kbbd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.o我們可以以看到.o文件的的字符串串被重復(fù)復(fù)了兩次次,如果果我們的的工程需需要加入入一個新新的.o文文件,那那么我們們需要在在兩個地地方加(應(yīng)該是是三個地地方,還還有一個個地方在在cleean中中)。當(dāng)當(dāng)然,我我們的mmakeefille并不不復(fù)雜,所以在在兩
23、個地地方加也也不累,但如果果makkefiile變變得復(fù)雜雜,那么么我們就就有可能能會忘掉掉一個需需要加入入的地方方,而導(dǎo)導(dǎo)致編譯譯失敗。所以,為了mmakeefille的易易維護(hù),在maakeffilee中我們們可以使使用變量量。maakeffilee的變量量也就是是一個字字符串,理解成成C語言言中的宏宏可能會會更好。比如,我我們聲明明一個變變量,叫叫objjectts, OBJJECTTS, objjs, OBJJS, objj, 或或是OBBJ,反反正不管管什么啦啦,只要要能夠表表示obbj文件件就行了了。我們們在maakeffilee一開始始就這樣樣定義:objeectss = mai
24、in.oo kbbd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.o于是,我我們就可可以很方方便地在在我們的的makkefiile中中以“$(oobjeectss)”的方式式來使用用這個變變量了,于是我我們的改改良版mmakeefille就變變成下面面這個樣樣子:objeectss = maiin.oo kbbd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.oeditt : $(oobjeectss)ccc
25、-oo eddit $(oobjeectss)maain.o : maain.c ddefss.hccc -c mmainn.ckkbd.o : kbbd.cc deefs.h ccommmandd.hccc -c kkbd.ccoommaand.o : coommaand.c ddefss.h commmannd.hhcc -c commmannd.ccdissplaay.oo : dissplaay.cc deefs.h bbufffer.hccc -cc diispllay.cinnserrt.oo : inssertt.c deffs.hh buuffeer.hhcc -c insse
26、rtt.cssearrch.o : seearcch.cc deefs.h bbufffer.hccc -cc seearcch.ccfilles.o : fiiless.c deffs.hh buuffeer.hh coommaand.hccc -cc fiiless.cuutills.oo : utiils.c ddefss.hccc -c uutills.cccleean :rmm eddit $(oobjeectss)于是如果果有新的的 .oo 文件件加入,我們只只需簡單單地修改改一下 objjectts 變變量就可可以了。關(guān)于變量量更多的的話題,我會在在后續(xù)給給你一一一道來。五、讓m
27、makee自動推推導(dǎo)GNU的的makke很強(qiáng)強(qiáng)大,它它可以自自動推導(dǎo)導(dǎo)文件以以及文件件依賴關(guān)關(guān)系后面面的命令令,于是是我們就就沒必要要去在每每一個.o文件后后都寫上上類似的的命令,因?yàn)?,我們的的makke會自自動識別別,并自自己推導(dǎo)導(dǎo)命令。只要maake看看到一個個.oo文件件,它就就會自動動的把.c文件加加在依賴賴關(guān)系中中,如果果makke找到到一個wwhatteveer.oo,那么么whaatevver.c,就就會是wwhatteveer.oo的依賴賴文件。并且ccc -c wwhatteveer.cc 也會會被推導(dǎo)導(dǎo)出來,于是,我們的的makkefiile再再也不用用寫得這這么復(fù)雜雜。我
28、們們的是新新的maakeffilee又出爐爐了。objeectss = maiin.oo kbbd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.oeditt : $(oobjeectss)ccc -oo eddit $(oobjeectss)mainn.o : ddefss.hkkbd.o : deefs.h ccommmandd.hccommmandd.o : ddefss.h commmannd.hhdissplaay.oo : deffs.hh buuffeer.hhinssertt.o : d
29、defss.h buffferr.hssearrch.o : deefs.h bbufffer.hfiiless.o : ddefss.h buffferr.h commmannd.hhutiils.o : deefs.h.PHOONY : ccleaanclleann :rrm eeditt $(objjectts)這種方法法,也就就是maake的的“隱晦規(guī)規(guī)則”。上面面文件內(nèi)內(nèi)容中,“.PHHONYY”表示,cleean是是個偽目目標(biāo)文件件。關(guān)于更為為詳細(xì)的的“隱晦規(guī)規(guī)則”和“偽目標(biāo)標(biāo)文件”,我會會在后續(xù)續(xù)給你一一一道來來。六、另類類風(fēng)格的的makkefiile即然我們們的maake可可以
30、自動動推導(dǎo)命命令,那那么我看看到那堆堆.oo和.h的依賴賴就有點(diǎn)點(diǎn)不爽,那么多多的重復(fù)復(fù)的.h,能不能能把其收收攏起來來,好吧吧,沒有有問題,這個對對于maake來來說很容容易,誰誰叫它提提供了自自動推導(dǎo)導(dǎo)命令和和文件的的功能呢呢?來看看看最新新風(fēng)格的的makkefiile吧吧。objeectss = maiin.oo kbbd.oo coommaand.o ddispplayy.o innserrt.oo seearcch.oo fiiless.o utiils.oeditt : $(oobjeectss)ccc -oo eddit $(oobjeectss)$(obbjeccts) : d
31、effs.hhkbdd.o commmannd.oo fiiless.o : ccommmandd.hddispplayy.o inssertt.o seaarchh.o filles.o : buuffeer.hh.PHOONY : ccleaanclleann :rrm eeditt $(objjectts)這種風(fēng)格格,讓我我們的mmakeefille變得得很簡單單,但我我們的文文件依賴賴關(guān)系就就顯得有有點(diǎn)凌亂亂了。魚魚和熊掌掌不可兼兼得。還還看你的的喜好了了。我是是不喜歡歡這種風(fēng)風(fēng)格的,一是文文件的依依賴關(guān)系系看不清清楚,二二是如果果文件一一多,要要加入幾幾個新的的.o文文件,那那就理不
32、不清楚了了。七、清空空目標(biāo)文文件的規(guī)規(guī)則每個Maakeffilee中都應(yīng)應(yīng)該寫一一個清空空目標(biāo)文文件(.o和執(zhí)執(zhí)行文件件)的規(guī)規(guī)則,這這不僅便便于重編編譯,也也很利于于保持文文件的清清潔。這這是一個個“修養(yǎng)”(呵呵呵,還記記得我的的編程程修養(yǎng)嗎)。一般的的風(fēng)格都都是:cleaan:rrm eeditt $(objjectts)更為穩(wěn)健健的做法法是:.PHOONY : ccleaanclleann :-rm ediit $(obbjeccts)前面說過過,.PPHONNY意思思表示ccleaan是一一個“偽目標(biāo)標(biāo)”,。而而在rmm命令前前面加了了一個小小減號的的意思就就是,也也許某些些文件出出現(xiàn)
33、問題題,但不不要管,繼續(xù)做做后面的的事。當(dāng)當(dāng)然,ccleaan的規(guī)規(guī)則不要要放在文文件的開開頭,不不然,這這就會變變成maake的的默認(rèn)目目標(biāo),相相信誰也也不愿意意這樣。不成文文的規(guī)矩矩是“clleann從來都都是放在在文件的的最后”。上面就是是一個mmakeefille的概概貌,也也是maakeffilee的基礎(chǔ)礎(chǔ),下面面還有很很多maakeffilee的相關(guān)關(guān)細(xì)節(jié),準(zhǔn)備好好了嗎?準(zhǔn)備好好了就來來。Makeefille 總總述 一、Maakeffilee里有什什么?Makeefille里主主要包含含了五個個東西:顯式規(guī)規(guī)則、隱隱晦規(guī)則則、變量量定義、文件指指示和注注釋。1、顯式式規(guī)則。顯式規(guī)
34、規(guī)則說明明了,如如何生成成一個或或多的的的目標(biāo)文文件。這這是由MMakeefille的書書寫者明明顯指出出,要生生成的文文件,文文件的依依賴文件件,生成成的命令令。2、隱晦晦規(guī)則。由于我我們的mmakee有自動動推導(dǎo)的的功能,所以隱隱晦的規(guī)規(guī)則可以以讓我們們比較粗粗糙地簡簡略地書書寫Maakeffilee,這是是由maake所所支持的的。3、變量量的定義義。在MMakeefille中我我們要定定義一系系列的變變量,變變量一般般都是字字符串,這個有有點(diǎn)你CC語言中中的宏,當(dāng)Maakeffilee被執(zhí)行行時,其其中的變變量都會會被擴(kuò)展展到相應(yīng)應(yīng)的引用用位置上上。4、文件件指示。其包括括了三個個部分
35、,一個是是在一個個Makkefiile中中引用另另一個MMakeefille,就就像C語語言中的的inccludde一樣樣;另一一個是指指根據(jù)某某些情況況指定MMakeefille中的的有效部部分,就就像C語語言中的的預(yù)編譯譯#iff一樣;還有就就是定義義一個多多行的命命令。有有關(guān)這一一部分的的內(nèi)容,我會在在后續(xù)的的部分中中講述。5、注釋釋。Maakeffilee中只有有行注釋釋,和UUNIXX的Shhelll腳本一一樣,其其注釋是是用“#”字符,這個就就像C/C+中的“/”一樣。如果你你要在你你的Maakeffilee中使用用“#”字符,可以用用反斜框框進(jìn)行轉(zhuǎn)轉(zhuǎn)義,如如:“#”。最后,還還值
36、得一一提的是是,在MMakeefille中的的命令,必須要要以TTab鍵開始始。二、Maakeffilee的文件件名默認(rèn)的情情況下,makke命令令會在當(dāng)當(dāng)前目錄錄下按順順序找尋尋文件名名為“GNUUmakkefiile”、“makkefiile”、“Makkefiile”的文件件,找到到了解釋釋這個文文件。在在這三個個文件名名中,最最好使用用“Makkefiile”這個文文件名,因?yàn)?,這個文文件名第第一個字字符為大大寫,這這樣有一一種顯目目的感覺覺。最好好不要用用“GNUUmakkefiile”,這個個文件是是GNUU的maake識識別的。有另外外一些mmakee只對全全小寫的的“makke
37、fiile”文件名名敏感,但是基基本上來來說,大大多數(shù)的的makke都支支持“makkefiile”和“Makkefiile”這兩種種默認(rèn)文文件名。當(dāng)然,你你可以使使用別的的文件名名來書寫寫Makkefiile,比如:“Makke.LLinuux”,“Makke.SSolaariss”,“Makke.AAIX”等,如如果要指指定特定定的Maakeffilee,你可可以使用用makke的“-f”和“-ffilee”參數(shù),如:mmakee-f Makke.LLinuux或mmakee -fille MMakee.AIIX。三、引用用其它的的Makkefiile在Makkefiile使使用inncl
38、uude關(guān)關(guān)鍵字可可以把別別的Maakeffilee包含進(jìn)進(jìn)來,這這很像CC語言的的#inncluude,被包含含的文件件會原模模原樣的的放在當(dāng)當(dāng)前文件件的包含含位置。inccludde的語語法是:inclludee fileenamme可以以是當(dāng)前前操作系系統(tǒng)Shhelll的文件件模式(可以保保含路徑徑和通配配符)在inccludde前面面可以有有一些空空字符,但是絕絕不能是是Taab鍵鍵開始。inccludde和可以用用一個或或多個空空格隔開開。舉個個例子,你有這這樣幾個個Makkefiile:a.mmk、bb.mkk、c.mk,還有一一個文件件叫fooo.mmakee,以及及一個變變量$
39、(barr),其其包含了了e.mmk和ff.mkk,那么么,下面面的語句句:inclludee fooo.mmakee *.mk $(bbar)等價于:inclludee fooo.mmakee a.mk b.mmk cc.mkk e.mk f.mmkmakee命令開開始時,會把找找尋inncluude所所指出的的其它MMakeefille,并并把其內(nèi)內(nèi)容安置置在當(dāng)前前的位置置。就好好像C/C+的#iinclludee指令一一樣。如如果文件件都沒有有指定絕絕對路徑徑或是相相對路徑徑的話,makke會在在當(dāng)前目目錄下首首先尋找找,如果果當(dāng)前目目錄下沒沒有找到到,那么么,maake還還會在下下面的
40、幾幾個目錄錄下找:1、如果果makke執(zhí)行行時,有有“-I”或“-iinclludee-diir”參數(shù),那么mmakee就會在在這個參參數(shù)所指指定的目目錄下去去尋找。2、如如果目錄錄/inccludde(一一般是:/ussr/llocaal/bbin或或/ussr/iinclludee)存在在的話,makke也會會去找。如果有文文件沒有有找到的的話,mmakee會生成成一條警警告信息息,但不不會馬上上出現(xiàn)致致命錯誤誤。它會會繼續(xù)載載入其它它的文件件,一旦旦完成mmakeefille的讀讀取,mmakee會再重重試這些些沒有找找到,或或是不能能讀取的的文件,如果還還是不行行,maake才才會出現(xiàn)
41、現(xiàn)一條致致命信息息。如果果你想讓讓makke不理理那些無無法讀取取的文件件,而繼繼續(xù)執(zhí)行行,你可可以在iinclludee前加一一個減號號“-”。如:-inccludde 其表示示,無論論inccludde過程程中出現(xiàn)現(xiàn)什么錯錯誤,都都不要報報錯繼續(xù)續(xù)執(zhí)行。和其它它版本mmakee兼容的的相關(guān)命命令是ssinccludde,其其作用和和這一個個是一樣樣的。四、環(huán)境境變量 MAKKEFIILESS如果你的的當(dāng)前環(huán)環(huán)境中定定義了環(huán)環(huán)境變量量MAKKEFIILESS,那么么,maake會會把這個個變量中中的值做做一個類類似于iinclludee的動作作。這個個變量中中的值是是其它的的Makkefii
42、le,用空格格分隔。只是,它和iinclludee不同的的是,從從這個環(huán)環(huán)境變中中引入的的Makkefiile的的“目標(biāo)”不會起起作用,如果環(huán)環(huán)境變量量中定義義的文件件發(fā)現(xiàn)錯錯誤,mmakee也會不不理。但是在這這里我還還是建議議不要使使用這個個環(huán)境變變量,因因?yàn)橹灰@個變變量一被被定義,那么當(dāng)當(dāng)你使用用makke時,所有的的Makkefiile都都會受到到它的影影響,這這絕不是是你想看看到的。在這里里提這個個事,只只是為了了告訴大大家,也也許有時時候你的的Makkefiile出出現(xiàn)了怪怪事,那那么你可可以看看看當(dāng)前環(huán)環(huán)境中有有沒有定定義這個個變量。五、maake的的工作方方式GNU的的ma
43、kke工作作時的執(zhí)執(zhí)行步驟驟入下:(想來來其它的的makke也是是類似)1、讀入入所有的的Makkefiile。2、讀讀入被iinclludee的其它它Makkefiile。3、初初始化文文件中的的變量。4、推推導(dǎo)隱晦晦規(guī)則,并分析析所有規(guī)規(guī)則。55、為所所有的目目標(biāo)文件件創(chuàng)建依依賴關(guān)系系鏈。66、根據(jù)據(jù)依賴關(guān)關(guān)系,決決定哪些些目標(biāo)要要重新生生成。77、執(zhí)行行生成命命令。1-5步步為第一一個階段段,6-7為第第二個階階段。第第一個階階段中,如果定定義的變變量被使使用了,那么,makke會把把其展開開在使用用的位置置。但mmakee并不會會完全馬馬上展開開,maake使使用的是是拖延戰(zhàn)戰(zhàn)術(shù),如如
44、果變量量出現(xiàn)在在依賴關(guān)關(guān)系的規(guī)規(guī)則中,那么僅僅當(dāng)這條條依賴被被決定要要使用了了,變量量才會在在其內(nèi)部部展開。當(dāng)然,這這個工作作方式你你不一定定要清楚楚,但是是知道這這個方式式你也會會對maake更更為熟悉悉。有了了這個基基礎(chǔ),后后續(xù)部分分也就容容易看懂懂了。書寫規(guī)則則 規(guī)則包含含兩個部部分,一一個是依依賴關(guān)系系,一個個是生成成目標(biāo)的的方法。在Makkefiile中中,規(guī)則則的順序序是很重重要的,因?yàn)?,Makkefiile中中只應(yīng)該該有一個個最終目目標(biāo),其其它的目目標(biāo)都是是被這個個目標(biāo)所所連帶出出來的,所以一一定要讓讓makke知道道你的最最終目標(biāo)標(biāo)是什么么。一般般來說,定義在在Makkefii
45、le中中的目標(biāo)標(biāo)可能會會有很多多,但是是第一條條規(guī)則中中的目標(biāo)標(biāo)將被確確立為最最終的目目標(biāo)。如如果第一一條規(guī)則則中的目目標(biāo)有很很多個,那么,第一個個目標(biāo)會會成為最最終的目目標(biāo)。mmakee所完成成的也就就是這個個目標(biāo)。好了,還還是讓我我們來看看一看如如何書寫寫規(guī)則。一、規(guī)則則舉例foo.o : fooo.cc deefs.h # fooo模塊塊cc -c -g fooo.c看到這個個例子,各位應(yīng)應(yīng)該不是是很陌生生了,前前面也已已說過,fooo.o是是我們的的目標(biāo),fooo.c和和deffs.hh是目標(biāo)標(biāo)所依賴賴的源文文件,而而只有一一個命令令“cc -c -gffoo.c”(以TTab鍵鍵開頭
46、)。這個個規(guī)則告告訴我們們兩件事事:1、文件件的依賴賴關(guān)系,fooo.o依依賴于ffoo.c和ddefss.h的的文件,如果ffoo.c和ddefss.h的的文件日日期要比比fooo.o文文件日期期要新,或是ffoo.o不存存在,那那么依賴賴關(guān)系發(fā)發(fā)生。22、如果果生成(或更新新)fooo.oo文件。也就是是那個ccc命令令,其說說明了,如何生生成fooo.oo這個文文件。(當(dāng)然ffoo.c文件件inccludde了ddefss.h文文件)二、規(guī)則則的語法法targgetss : preereqquissiteescoommaand.或是這樣樣:targgetss : preereqquiss
47、itees ; coommaandccommmandd.targgetss是文件件名,以以空格分分開,可可以使用用通配符符。一般般來說,我們的的目標(biāo)基基本上是是一個文文件,但但也有可可能是多多個文件件。commmandd是命令令行,如如果其不不與“tarrgett:prrereequiisittes”在一行行,那么么,必須須以TTab鍵鍵開頭頭,如果果和prrereequiisittes在在一行,那么可可以用分分號做為為分隔。(見上上)prerrequuisiitess也就是是目標(biāo)所所依賴的的文件(或依賴賴目標(biāo))。如果果其中的的某個文文件要比比目標(biāo)文文件要新新,那么么,目標(biāo)標(biāo)就被認(rèn)認(rèn)為是“過時
48、的的”,被認(rèn)認(rèn)為是需需要重生生成的。這個在在前面已已經(jīng)講過過了。如果命令令太長,你可以以使用反反斜框()作為為換行符符。maake對對一行上上有多少少個字符符沒有限限制。規(guī)規(guī)則告訴訴makke兩件件事,文文件的依依賴關(guān)系系和如何何成成目目標(biāo)文件件。一般來說說,maake會會以UNNIX的的標(biāo)準(zhǔn)SShelll,也也就是/binn/shh來執(zhí)行行命令。三、在規(guī)規(guī)則中使使用通配配符如果我們們想定義義一系列列比較類類似的文文件,我我們很自自然地就就想起使使用通配配符。mmakee支持三三各通配配符:“*”,“?”和“.”。這是是和Unnix的的B-SShelll是相相同的。波浪號(“”)字符符在文件件
49、名中也也有比較較特殊的的用途。如果是是“/ttestt”,這就就表示當(dāng)當(dāng)前用戶戶的$HHOMEE目錄下下的teest目目錄。而而“hcchenn/teest”則表示示用戶hhcheen的宿宿主目錄錄下的ttestt目錄。(這些些都是UUnixx下的小小知識了了,maake也也支持)而在WWinddowss或是MMS-DDOS下下,用戶戶沒有宿宿主目錄錄,那么么波浪號號所指的的目錄則則根據(jù)環(huán)環(huán)境變量量“HOMME”而定。通配符代代替了你你一系列列的文件件,如“*.cc”表示所所以后綴綴為c的的文件。一個需需要我們們注意的的是,如如果我們們的文件件名中有有通配符符,如:“*”,那么么可以用用轉(zhuǎn)義字
50、字符“”,如“*”來表示示真實(shí)的的“*”字符,而不是是任意長長度的字字符串。好吧,還還是先來來看幾個個例子吧吧:cleaan:rrm -f *.o上面這個個例子我我不不多多說了,這是操操作系統(tǒng)統(tǒng)Sheell所所支持的的通配符符。這是是在命令令中的通通配符。prinnt: *.cclprr -pp $?touuch priint上面這個個例子說說明了通通配符也也可以在在我們的的規(guī)則中中,目標(biāo)標(biāo)priint依依賴于所所有的.c文件。其中的的“$?”是一個個自動化化變量,我會在在后面給給你講述述。objeectss = *.oo上面這個個例子,表示了了,通符符同樣可可以用在在變量中中。并不不是說*.
51、oo會展展開,不不!obbjeccts的的值就是是“*.oo”。Maakeffilee中的變變量其實(shí)實(shí)就是CC/C+中的的宏。如如果你要要讓通配配符在變變量中展展開,也也就是讓讓objjectts的值值是所有有.oo的文文件名的的集合,那么,你可以以這樣:objeectss := $(willdcaard *.oo)這種用法法由關(guān)鍵鍵字“willdcaard”指出,關(guān)于MMakeefille的關(guān)關(guān)鍵字,我們將將在后面面討論。四、文件件搜尋在一些大大的工程程中,有有大量的的源文件件,我們們通常的的做法是是把這許許多的源源文件分分類,并并存放在在不同的的目錄中中。所以以,當(dāng)mmakee需要去去找尋
52、文文件的依依賴關(guān)系系時,你你可以在在文件前前加上路路徑,但但最好的的方法是是把一個個路徑告告訴maake,讓maake在在自動去去找。Makeefille文件件中的特特殊變量量“VPAATH”就是完完成這個個功能的的,如果果沒有指指明這個個變量,makke只會會在當(dāng)前前的目錄錄中去找找尋依賴賴文件和和目標(biāo)文文件。如如果定義義了這個個變量,那么,makke就會會在當(dāng)當(dāng)當(dāng)前目錄錄找不到到的情況況下,到到所指定定的目錄錄中去找找尋文件件了。VPATTH = srrc:./hheadderss上面的的的定義指指定兩個個目錄,“srcc”和“./heaaderrs”,maake會會按照這這個順序序進(jìn)行搜
53、搜索。目目錄由“冒號”分隔。(當(dāng)然然,當(dāng)前前目錄永永遠(yuǎn)是最最高優(yōu)先先搜索的的地方)另一個設(shè)設(shè)置文件件搜索路路徑的方方法是使使用maake的的“vpaath”關(guān)鍵字字(注意意,它是是全小寫寫的),這不是是變量,這是一一個maake的的關(guān)鍵字字,這和和上面提提到的那那個VPPATHH變量很很類似,但是它它更為靈靈活。它它可以指指定不同同的文件件在不同同的搜索索目錄中中。這是是一個很很靈活的的功能。它的使使用方法法有三種種:1、vppathh 為符合模模式的文文件指定定搜索目目錄。2、vppathh 清除符合合模式的的文件的的搜索目目錄。3、vppathh清除所有有已被設(shè)設(shè)置好了了的文件件搜索目目錄
54、。vaptth使用用方法中中的需要要包含“%”字符?!?”的意思思是匹配配零或若若干字符符,例如如,“%.hh”表示所所有以“.h”結(jié)尾的的文件。指定了了要搜索索的文件件集,而而則指指定了的的文件集集的搜索索的目錄錄。例如如:vpatth %.h ./heaaderrs該語句表表示,要要求maake在在“./heaaderrs”目錄下下搜索所所有以“.h”結(jié)尾的的文件。(如果果某文件件在當(dāng)前前目錄沒沒有找到到的話)我們可以以連續(xù)地地使用vvpatth語句句,以指指定不同同搜索策策略。如如果連續(xù)續(xù)的vppathh語句中中出現(xiàn)了了相同的的,或是是被重復(fù)復(fù)了的,那么,makke會按按照vppathh
55、語句的的先后順順序來執(zhí)執(zhí)行搜索索。如:vpatth %.c fooovpaath % bblisshvppathh %.c bbar其表示“.c”結(jié)尾的的文件,先在“fooo”目錄,然后是是“bliish”,最后后是“barr”目錄。vpatth %.c fooo:baarvppathh % bliish而上面的的語句則則表示“.c”結(jié)尾的的文件,先在“fooo”目錄,然后是是“barr”目錄,最后才才是“bliish”目錄。五、偽目目標(biāo)最早先的的一個例例子中,我們提提到過一一個“cleean”的目標(biāo)標(biāo),這是是一個“偽目標(biāo)標(biāo)”,cleaan:rrm *.o temmp正像我們們前面例例子中的的
56、“cleean”一樣,即然我我們生成成了許多多文件編編譯文件件,我們們也應(yīng)該該提供一一個清除除它們的的“目標(biāo)”以備完完整地重重編譯而而用。 (以“makkeclleann”來使用用該目標(biāo)標(biāo))因?yàn)?,我我們并不不生成“cleean”這個文文件?!皞文繕?biāo)標(biāo)”并不是是一個文文件,只只是一個個標(biāo)簽,由于“偽目標(biāo)標(biāo)”不是文文件,所所以maake無無法生成成它的依依賴關(guān)系系和決定定它是否否要執(zhí)行行。我們們只有通通過顯示示地指明明這個“目標(biāo)”才能讓讓其生效效。當(dāng)然然,“偽目標(biāo)標(biāo)”的取名名不能和和文件名名重名,不然其其就失去去了“偽目標(biāo)標(biāo)”的意義義了。當(dāng)然,為為了避免免和文件件重名的的這種情情況,我我們可以以使
57、用一一個特殊殊的標(biāo)記記“.PHHONYY”來顯示示地指明明一個目目標(biāo)是“偽目標(biāo)標(biāo)”,向mmakee說明,不管是是否有這這個文件件,這個個目標(biāo)就就是“偽目標(biāo)標(biāo)”。.PHOONY : ccleaan只要有這這個聲明明,不管管是否有有“cleean”文件,要運(yùn)行行“cleean”這個目目標(biāo),只只有“makke ccleaan”這樣。于是整整個過程程可以這這樣寫:.PHOONY: clleanncleean:rm *.oo teemp偽目標(biāo)一一般沒有有依賴的的文件。但是,我們也也可以為為偽目標(biāo)標(biāo)指定所所依賴的的文件。偽目標(biāo)標(biāo)同樣可可以作為為“默認(rèn)目目標(biāo)”,只要要將其放放在第一一個。一一個示例例就是,如
58、果你你的Maakeffilee需要一一口氣生生成若干干個可執(zhí)執(zhí)行文件件,但你你只想簡簡單地敲敲一個mmakee完事,并且,所有的的目標(biāo)文文件都寫寫在一個個Makkefiile中中,那么么你可以以使用“偽目標(biāo)標(biāo)”這個特特性:all : pprogg1 pprogg2 pprogg3.PPHONNY : alllprogg1 : prrog11.o utiils.occc -oo prrog11 prrog11.o utiils.oprogg2 : prrog22.occc -o pprogg2 pprogg2.ooprogg3 : prrog33.o sorrt.oo uttilss.occc
59、-o pprogg3 pprogg3.oo soort.o uutills.oo我們知道道,Maakeffilee中的第第一個目目標(biāo)會被被作為其其默認(rèn)目目標(biāo)。我我們聲明明了一個個“alll”的偽目目標(biāo),其其依賴于于其它三三個目標(biāo)標(biāo)。由于于偽目標(biāo)標(biāo)的特性性是,總總是被執(zhí)執(zhí)行的,所以其其依賴的的那三個個目標(biāo)就就總是不不如“alll”這個目目標(biāo)新。所以,其它三三個目標(biāo)標(biāo)的規(guī)則則總是會會被決議議。也就就達(dá)到了了我們一一口氣生生成多個個目標(biāo)的的目的?!?PHHONYY: aall”聲明了了“alll”這個目目標(biāo)為“偽目標(biāo)標(biāo)”。隨便提一一句,從從上面的的例子我我們可以以看出,目標(biāo)也也可以成成為依賴賴。所以
60、以,偽目目標(biāo)同樣樣也可成成為依賴賴。看下下面的例例子:.PHOONY: clleannalll clleannobjj clleanndifffcleaanalll : clleannobjj clleanndifffrmm prrogrramcleaanobbj :rm *.oocleaandiiff :rmm *.difff“makke ccleaan”將清除除所有要要被清除除的文件件?!癱leeanoobj”和“cleeanddifff”這兩個個偽目標(biāo)標(biāo)有點(diǎn)像像“子程序序”的意思思。我們們可以輸輸入“makkeclleannalll”和“makke ccleaanobbj”和“makke
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度瓷磚產(chǎn)品研發(fā)資金投入合同3篇
- 2025年回遷房屋買賣合同
- 2025年度個人創(chuàng)業(yè)投資貸款合同書(創(chuàng)業(yè)扶持專項(xiàng))2篇
- 2025年環(huán)保項(xiàng)目的混合贈與合同
- 2025年房屋定金收取合同
- 2025年醫(yī)藥銷售配送代理合同
- 2025年家政服務(wù)管家合同
- 二零二五年度木工工藝培訓(xùn)與分包勞務(wù)合同4篇
- 2025年度農(nóng)藥包裝廢棄物回收處理合同范本4篇
- 南匯工商行政管理志2025年版編纂與檔案管理合同4篇
- 課題申報書:GenAI賦能新質(zhì)人才培養(yǎng)的生成式學(xué)習(xí)設(shè)計研究
- 2024年江蘇省中醫(yī)院高層次衛(wèi)技人才招聘筆試歷年參考題庫頻考點(diǎn)附帶答案
- 駱駝祥子-(一)-劇本
- 全國醫(yī)院數(shù)量統(tǒng)計
- 《中國香文化》課件
- 2024年醫(yī)美行業(yè)社媒平臺人群趨勢洞察報告-醫(yī)美行業(yè)觀察星秀傳媒
- 第六次全國幽門螺桿菌感染處理共識報告-
- 天津市2023-2024學(xué)年七年級上學(xué)期期末考試數(shù)學(xué)試題(含答案)
- 經(jīng)濟(jì)學(xué)的思維方式(第13版)
- 盤錦市重點(diǎn)中學(xué)2024年中考英語全真模擬試卷含答案
- 提高保險公司客戶投訴處理能力的整改措施
評論
0/150
提交評論