版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
GNUmake中文手ver-翻譯整理:2004-09-關(guān)于本本文瑾獻給所有熱愛Linux的程序員!本中文文檔本文比較完整的講述GNUmake工具,涵蓋GNUmake的用法、語法。同時重點討論如何為一個工程編寫Makefile。作為一個Linux程序員,make工具的使用以及編寫Makefilemake的中文資料比較少,Linuxer18個多月時間完成對“infomake”的翻譯整理,完成這個中文版手冊。本書不是一個純粹的語言翻GNUmake的一些語法和用法根據(jù)我個人的工作經(jīng)驗進行了一可以在支持V3.8版本的GNUmake的系統(tǒng)中正確執(zhí)行。閱讀本書之前,讀者應(yīng)該對GNULinux的一些常用編程工具有一定的了解。諸如:gcc、as、ar、ld、yacc等;同時在書寫Makefile時,需要能夠進行一些基本的s編程。這些工具是一個工程的基礎(chǔ)。如果大家對如果之前你對GNUmakeGNU(作為各章節(jié)的基礎(chǔ)知識 如果你已經(jīng)對GNUmake比較熟悉,你更需要關(guān)心此版本的新增特點、 GNUmake沒有概念、或者剛開始接觸,本身又想成為一個 此中文文檔當前版本v1.5,本文的所有勘誤和版本可在主頁http://x !
目第一章:概概準備知第二章:GNUmake介Makefile簡Makefile規(guī)則介簡單的示make如何工指定變自動推導(dǎo)規(guī)另類風格的 第三章:Makefile總述Makefile的內(nèi)makefile文件包含其它makefile文變量變量其他特殊變makefile文件的重重載另外一個make如何解析makefile文變量取條件語規(guī)則的定總第四章:Makefile的規(guī)一個例規(guī)則語依賴的類文件名使用通配統(tǒng)配符使用通配符存在的缺函數(shù)搜一般搜索(變量選擇性搜索(關(guān)鍵字搜索的命令行和搜隱含規(guī)則和庫文件和搜Makefile偽目強制目標(沒有命令或依賴的規(guī)則空目標文Makefile的特殊目多目多規(guī)則目靜態(tài)模靜態(tài)模式規(guī)則的語靜態(tài)模式和隱含規(guī)雙冒號規(guī)第五章:規(guī)則令命令回命令的執(zhí)并發(fā)執(zhí)行命命令執(zhí)行的錯中斷make的執(zhí)make的遞歸執(zhí)變量變量和遞命令行選項和遞-w選定義命令空命第六章:Makefile中的變變量的兩種變量定義(遞歸展開式直接展開式如何定義一個空“?=”操作變量的高級用變量的替換變量的套嵌變量取如何設(shè)置變追加變量override多行定系統(tǒng)環(huán)境變目標指定模式指定變第七章:Makefile的條件一個例條件判斷的基本關(guān)鍵字關(guān)鍵字關(guān)鍵字關(guān)鍵字第八章:make的內(nèi)嵌函數(shù)函數(shù)的調(diào)用語文本處理函$(subst$(patsubst $(strip$(filter$(filter-out$(sort$(word$(firstword文件名處理函$(dir$(notdir$(suffix$(joinforeach函if函value函 函make的控制函$(error第九章:執(zhí)行指定makefile文指定終極目替代命令的執(zhí)防止特定文件重替換變量定使用make進行編譯測make令行選項第十章:make的隱含規(guī)則隱含規(guī)則的make的隱含規(guī)則一隱含變代表命令的變命令參數(shù)的變make隱含規(guī)模式規(guī)模式規(guī)則介模式規(guī)則示自動化變模式的匹萬用規(guī)重建內(nèi)嵌隱含缺省規(guī)后綴規(guī)隱含規(guī)則搜索算第十一章:使用make更新靜態(tài)庫文庫成員作為靜態(tài)庫的更更新靜態(tài)庫的符號索引make靜態(tài)庫的注意靜態(tài)庫的后綴規(guī)第十二章GNUmake的特源自Systemv的特源自其他版本的特GNUmake自身的特點第十三章和其它版本的兼容第十四章Makefile的約基本的約規(guī)則命令行的約代表命令安 變Makefile的標準目標安裝命令第十五章make的常見錯誤信附錄:關(guān)鍵字索GNUmake可識別的指符GNUmake函GNUmake的自動化變后GNUmake環(huán)境變下一make概Linux環(huán)境下的程序員如果不會使用GNUmake來構(gòu)建和管理自己的工程,UnixLinux(unix)GNU的make工具能夠比較容易的構(gòu)建一個屬于你自己的不過這需要我們投入一些時間去完成一個或者多個稱之為Makefile文件的編寫。此文件正是make正常工作的基礎(chǔ)。所要完成的MakefileMakefile的好處是能夠使用一行命令來完成“自動化編(通常對于一個工程來說會是多個)Makefile。編譯整個工程你所要做的唯一的一件事就是在s提示符下輸入make命令。整個make是一個命令工具,它解釋Makefile中的指令(應(yīng)該說是規(guī)則。在且在Makefile中可以使用系統(tǒng)s所提供的任何命令來完成想要的工作。Makefile(在其它的系統(tǒng)上可能是另外的文件名)在絕大多數(shù)的IDE開發(fā)環(huán)境中make工具和如何編寫Makefile的中文文檔比較少。我整理這個文檔就是希望能使眾多的Linux環(huán)境下的程序員能夠比較容易的掌握和學(xué)會使用GNUmakeGNU的makeRedHat(包括發(fā)布的GNULinux系統(tǒng))所集成的GUNmake工具CmakeC語言工程的,那些編譯器只要能夠smake工具來管理。Make工作文件進行重建或者更新。那么應(yīng)該考慮使用GNUmake工具。GNUmake工具行代碼的編譯正是使用了make的這個特征。makeMakefile的規(guī)新編譯GNUmake的執(zhí)行依據(jù)。準備在開始我們關(guān)于make.o(為“foo.o為.o文件。將多.o文件或者.o文件和庫文件成為可作系統(tǒng)執(zhí)行的可執(zhí).o.o文件中使用的函數(shù)和其它.o(重定位,并系統(tǒng)相關(guān)文件(程序啟動文件等)最終生成可執(zhí)行程序。過程使用GNU的“l(fā)d”工具。File靜態(tài)庫文件的后綴為“.a式,僅僅是一個.o文件的集合。使用“ar”工具和管理靜態(tài)庫。.o.o文件時有編譯器按照一種特殊的方式生成(Linux中,共享庫文件格式通常為“ELF”格式。共享庫已經(jīng)具備libdl.so提供支持。infoldldGNUmakemakeMakefilemake以何種方式編譯源代碼和程序典型地可執(zhí)行文件可由一些.o文件按照一定Makefile。正如前面提到的你只需要在s下執(zhí)行“make。make會自動根據(jù)修改情況完成源文件的對應(yīng).o文件的更新、庫文件的更新、最終的可執(zhí)行程序的更新。make通過比較對應(yīng)文件(的最后修改時間,來決定哪make就執(zhí)行數(shù)據(jù)庫中所記錄的相應(yīng)命令(在makeMakefile以后會建立一個編譯過程的描述來重建它,對于不需要重建的文件make什么也不做。而且可以通過make令行選項來指定需要重新編譯的文件ProblemsandIfyouhaveproblemswithGNU`make'orthinkyou'vefoundabug,pleasereportittothedevelopers;wecannotpromisetodoanythingbutwemightwellwanttofixit.Beforereportingabug,makesureyou'veactuallyfoundarealbug.Carefullyrereadtheationandseeifitreallysaysyoucandowhatyou'retryingtodo.Ifit'snotclearwhetheryoushouldbeabletodosomethingornot,reportthattoo;it'sabugintheBeforereportingabugortryingtofixityourself,trytoisolateittothesmallestmakefilethatreproducestheproblem.Thensendusthemakefileandtheexact`make'gaveyou,includinganyerrororwarningmessages.Pleasedon'tparaphrasethesemessages:it'sbesttocutandpastethemintoyourreport.Whengeneratingthissmallmakefile,besuretonotuseanynon-orunusualtoolsinyourcommands:youcanalmostalwaysemulatewhatsuchatoolwoulddowithsimplescommands.Finally,besuretoexinwhatyouexpectedtooccur;thiswillhelpusdecidewhethertheproblemwasreallyintheation.Onceyouhaveapreciseproblemyoucanreportitinoneoftwoways.Eithersendelectronicmailto:oruseourWeb-basedprojectmanagementtool,Inadditiontotheinformationabove,pleasebecarefultoincludetheversionnumberof`make'youareusing.Youcangetthisinformationwiththecommand`make--version'.Besurealsotoincludethetypeofmachineandoperatingsystemyouareusing.Onewaytoobtainthisinformationisbylookingatthefinallinesofoutputfromthe`make--以上時GNUmake的bugGNUmake過程中。發(fā)現(xiàn)bug或者問題??梢酝ㄟ^以上的方式和反饋。Makefile簡makeMakefile的特殊文件(本文的后續(xù)將Makefile作為這個特殊文件的文件名)make需要做什么(完成什么任務(wù),該怎么做。通常,make工具主要被用來進行工程編譯和程序。Makefile8C的源代碼和三個頭文件的工程進行編譯和。這個Makefile提供給了make必要的信息,make程序根據(jù)Makefile中的規(guī)則描述執(zhí)行相關(guān)令來完成指定的任(如編譯和清除編譯過程文件等。復(fù)雜的Makefile會在本文后續(xù)進行討論。當使用makemake時將會被編譯(重新編譯 所有的源文件沒有被編譯過,則對各個C源文件進行編譯并進行,每一個在上次執(zhí)行make之后修改過的C源代碼文件在本次執(zhí)行時將會被重新編 頭文件在上一次執(zhí)行make之后被修有包含此頭C源文件在本次執(zhí)行make時將會被重新編譯。makeC源文件重新編譯生成.o文件,對于沒新的對應(yīng)的.o.o.o文首先讓我們先來看一些MakefileMakefile規(guī)則一個簡單的Makefile.ocleancommand:規(guī)則令行。是規(guī)則所要執(zhí)行的動作(任意的s 是可在s 下執(zhí)行的程序。它限定了make執(zhí)行這條規(guī)則時所需要的動作。成相應(yīng)的動作。這也是書寫Makefile中容易產(chǎn)生,而且比較隱蔽的錯誤?!癱lean通常規(guī)則中包括了目標的依賴關(guān)(目標的依賴文件和重建目標令make規(guī)則目標所需要令。Makefile文件中通常還包含了除規(guī)則以外的很多東西(后續(xù)我們會一步一步的展開Makefile可能只包含規(guī)則。規(guī)則在有些Makefilemake程序根據(jù)規(guī)則的依賴關(guān)系,決定是否執(zhí)行規(guī)則所定義令的過程我簡單的示Makefile“edit#sampleedit:main.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.occ-oeditmain.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.omain.o:main.cdefs.hcc-cmain.ckbd.o:kbd.cdefs.hcommand.hcc-ckbd.ccommand.o:command.cdefs.hcommand.hcc-ccommand.cdisy.o:disy.cdefs.hbuffer.hcc-cdisy.cinsert.o:insert.cdefs.hbuffer.hcc-cinsert.csearch.o:search.cdefs.hbuffer.hcc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.hcc-cfiles.cutils.o:utils.cdefs.hcc-cutils.ccleanrmeditmain.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.o我們的Makefile書寫清晰、容易閱讀理解。但需要注意:反斜線之后不能有空序“edit”,所要做的就是在包含此Makefile的(當然也在代碼所在的)下輸入命令“make”。刪除已經(jīng)此下之前使用“make”生成的文件(包括那些中間過程的.o文件),也只需要輸入命令“makeclean”就可以了。文件(main.o,kbd.o….);依賴(prerequisites)就是冒號后面的那些.c文件和.h文件)。命令包括“cc–cmaic.c”、“cc–ckbd.c”……的.o文件不會被更新),同時“main.o”的更新將會導(dǎo)致“edit”被更新。在描述依賴關(guān)系行之下通常就是規(guī)則令行(存在一些些規(guī)則沒有命令行(如何根據(jù)依賴文件來更新目標文件Tab]鍵開始以Makefile其他行區(qū)別就是說所有令行必需以Ta][Tbak程序會把出現(xiàn)在第一條規(guī)則之后的所有以[ab字符開始的行都作為命令行來處理。(記?。菏鲋刑峁┱_令?!癿ake”程序所做的就是當目標程序需要更新時執(zhí)行規(guī)則所定義令)。目標“clean”不是一個文件,它僅僅代表執(zhí)行一個動作的標識。正常情況clean規(guī)則的依賴列表中。因此在執(zhí)行make時,它所指定的動作不會被執(zhí)行。除非在執(zhí)行makeclea就是通過這個目標名來執(zhí)行它所定義令akefil中把那些沒有任何(pnytagesclean”目標所定義令,可在s下輸入:makean。make如何默認的情況下,make執(zhí)行的是Makefile中的第一個規(guī)則,此規(guī)則的第一個(Makefile,目標“editMakefile中是第一個目標,因此它就是makeCmake將會重建終極目標“edit當在s提示符下輸入“make”命令以后。make當前 Makefile文件,并將Makefile文件中的第一個目標作為其執(zhí)行的“終極目標件生成目標“edit”令;make在執(zhí)行這個規(guī)則所定義令之前,首先處文件為目標的規(guī)則。對這些.o文件為目標的規(guī)則處理有下列三種情況:目標.o 比目標.o(make之后被修改。則根據(jù)規(guī)則重新 目標.o.o(的.c.h文件(make之后沒有被修改也不做。這些.o.o非明確指定執(zhí)行這個規(guī)則(可以通過make令行指定重建目標,那么這個目clean個.o文件時,make同樣會去尋找它的依賴文件的重建規(guī)則(是這樣一個規(guī)則:這個依賴文件在規(guī)則中作為目標出現(xiàn),在這里就是.c和.h文件的重建規(guī)則。在Makefile中沒有哪個規(guī)則的目標是.c或者.h文件,所以沒有重建.c和.hC言語源程序文件可以使用工具Bison或者Yacc來生成(具edit 則根據(jù)規(guī)則重新生成“edit 上例中如果更改了源文insert.c”后執(zhí)行makeinsert.o將被更新,makekbd.oMakefile中目標和依賴的關(guān)系。我們簡單總結(jié)一下:對于一個Makefile文件make首先解析終極目標所在的規(guī)則(上節(jié)例子中的第一個規(guī)則,根據(jù)其依賴文件(8個.o它文件(main.c、defs.h,則同樣為這個依賴文件尋找創(chuàng)建規(guī)則(創(chuàng)建main.c……,make從最后一個規(guī)則(上例目標為main.o的規(guī)則)回退開始執(zhí)行,最終完成終極目標的第一個依賴文件的main.okbd.ocommand.o”……(或者創(chuàng)建makemake依賴關(guān)系的正確性規(guī)則所定義令的正確性不做任何判斷就是說一個規(guī)make錯誤檢查。makeMakefile中指定同樣是上邊的例子,我們來看一下終極目標“editedit:main.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.occ-oeditmain.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.o“objectsOBJECTSobjsOBJS上例的Makefile中我們可以添加這樣一行:objects=main.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.o“objects”作為一個變量,它代表所有的.o文件的列表。在定義了此變量而不需要羅列所有的.o文件列表(。因此上例的objects=main.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.oedit:cc-oeditclean:rmedit當我們需要為終極目標“edit”增加或者去掉一個.o依賴文件時,只需要改變自動推導(dǎo)在使用make編譯.c源文件時,編譯.c源文件規(guī)則令可以不用明確給生成對應(yīng)的.o文件。它執(zhí)行命令“ccc”來編譯.cMakefile中我們,make的兩個文件,而且使用正確令來重建這個目標文件。對于上邊的例子,此main.o“N.o,而由make自身決定使用默認命令。此默認規(guī)則稱為make的隱含規(guī)則。Makefile時,我們就可以省略掉描述.c文件和.o依賴關(guān)系的規(guī)則,而只需要給出那些特定的規(guī)則描述(.o目標所需要的.h文件。因此上邊objects#sampleobjects=main.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.oedit:cc-oeditmain.o:kbd.o:defs.hcommand.hcommand.o:defs.hcommand.hdisy.o:defs.hbuffer.hinsert.o:defs.hbuffer.hsearch.o:defs.hbuffer.hfiles.o:defs.hbuffer.hcommand.hutils.o:defs.h.PHONY:cleanclean:rmeditmake的隱含規(guī)則在實際工程的make幾乎在所有的Makefile中都用到了make的隱含規(guī)則,make的隱含規(guī)則是非常另類風格的Makefile。在這個Makefile中,根據(jù)依賴而不是目標對規(guī)則進行分組。上例的Makefile就可以這樣來實現(xiàn):#sampleobjects=main.okbd.ocommand.odisy.o\insert.osearch.ofiles.outils.oedit:cc-oedit$(objects):kbd.ocommand.ofiles.o:command.hdisy.oinsert.osearch.ofiles.o:buffer.h其對應(yīng)規(guī)則的目標中所列舉的所有.o文件的依賴文件。Makefile并不值得我們借鑒。問題在于:同時把多個目標導(dǎo)致規(guī)則定義不明了,比較。建議大家不要在Makefile中采用這種方式了書寫。否則后期將會是一件非常痛苦的事情。后期也會非常方便,而且Makefile會更清晰、明了。清除工 過程文了實現(xiàn)清除當前(edit和哪些.o文件cleanrmedit.PHONY:clean-rmedit這樣的一個目標在Makefile中,不能將其作為終極目標(Makefile的第一個目標make將不會被處理。當需要執(zhí)行此規(guī)則,要在make令行選項中明確指定這個目clean第三章:Makefile總Makefile的內(nèi)Makefile5個東西:顯式規(guī)則、隱含規(guī)則、變量 (沒有命令,這樣的規(guī)則只是純粹的描述了文件之間的依賴關(guān)系 make根據(jù)一類目標文件(典型的是根據(jù)文件名的后的依賴文件并使用默認令來對目標進行更新(建立一個規(guī)則。 來實現(xiàn)對文本串的使用。第一章的例子中,我們就定義了一個變量“objects”來表示一個.o文件列表。 Makefile指示符:指示符指明在make程序makefile文件過程中 一個文件給定文件名的文件將其內(nèi)容作為makefile文 決定(通常是根據(jù)一個變量的得值)Makefile中的 注釋:Makefile中“#”字符后的內(nèi)容被作為是注釋內(nèi)容(s腳(\#(\#需要注意的地方將其交給系統(tǒng)s程序去解釋執(zhí)行。因此,以[Tab]字符開始的注釋行也會被交給s來處理,此命令行是否需要被執(zhí)行(s執(zhí)行或者忽略)是由系統(tǒng)s程序來的?!癲efinemake進行處理,決定是注釋還是有效內(nèi)容。Makefile中變量的和C語言中的宏makefile文件默認的情況下,make會在工作 (執(zhí)行make的 序?qū)ふ襪akefile文件并執(zhí)行,查找的文件名順序為“GNUmakefile“makefile“Makefile“Makefile 的一些重要文(README,Chagelist等靠近在尋找時會比較容易的發(fā)現(xiàn)它。make”才可以識別,而其他版本的make程序只會在工作 如果make程序在工作 當makefile文件名不是這三個任何一個時,需要通過make的“-f”或者“--file”選項來指定make的makefile文件。給make指定makefile文-file=NAMEmake時的makefile文件。也可以通過多個“-f”或者“--file”選項來指定多個需要的makefile文件,多個makefile文件將會被按照指定的順序進行并被make解析執(zhí)行。當通過“-f”或者“--file”指定makemakefile的文件時,make就不再自動查找這三個標準命名的makefile當 當前下存在一個源文件foo.c的,我們可以使用“makefoo.o”來使用make的隱含規(guī)則自動生成foo.o。當執(zhí)行“makefoo.o”時。我們可以看到其執(zhí)行cc–c–ofoo.o 不存在。如果使用命令“makefoo.o”時,將回到到如下提示:make:***Noruletomaketarget‘foo.o’.make:***Notargetsspecifiedandnomakefilefound.包含其它makefile文Makefilemakefile文件。Makefileinclude“includeMakefile指定的一個或者多個文件,完成以后再繼續(xù)當前Makefile的。Makefile中includeFILENAMES是s所支持的文件名(可以使用通配符ude(make程序在處理時將忽略這些空格[ab](如果一行以[ab]make程序?qū)⒋诵凶鳛橐粋€命令行來處理udeab]Makefile中,如果存在變量或函數(shù)的。它們將會在包含它們的Makefile中被展開(詳細可參考第六章Makefile中的變量c.mk$(bar)“bishbashincludefoo*.mkincludefooa.mkb.mkc.mkbish之前已經(jīng)提到過makeinclude時,將暫停對當前使用指示符“include”的makefile文件的,而轉(zhuǎn)去依此由“include”指示符指定的文件列表直到完成所有這些文件以后再回過頭繼續(xù)指示“include”所在的makefile文件。 有多個不同的程序,由不同下的幾個獨立的Makefile來描述其重建命名限制在需要使用的Makefile中使用指示符“include”來包含此文 存在另外一個文件中Makefile使用指示include”包含這些文件。Makefile中追加依賴文件的方法要明智的多。其它版本的make已經(jīng)使用這種方式來處理。如果指示符“include”指定的文件不是以斜線開始(/usr/srcMakefile..., 下也不存在此文件;make將根據(jù)文件名試 “/usr/gnu/include 下都沒有找到“include”指定的文件時,make將會提示一個Makefile續(xù)內(nèi)容。當完成整個Makefile后,make將試圖使用規(guī)則來創(chuàng)建通過指示符make將提示致命錯誤并退出。會輸出類似如下錯誤提示:Makefile:錯誤的行數(shù):未找到文件名:提示信息(NosuchfileorMake:***Noruletomaketarget‘<filename>’.”來代替“include“-操作的錯誤。make繼續(xù)執(zhí)行。像下邊那樣:-include會退出;除此之外,和第式效果相同。以下是這兩種方式的比較:FILENAMES...make列表中的任何一個文件不能正常而且不存在一個創(chuàng)建此文件的規(guī)則時make極目標的重建時(某些必需的目標無法在當前已的makefile文件內(nèi)容中找(GNU所支持的方式變量如果在當前環(huán)境定義了一個“MAKEFILES”環(huán)境變量,make執(zhí)行時首先Makefile文件,多個文件之間使用空格分開。類似使用指示符“includeMakefile文件一樣,如果文件名非絕對路徑而且當前也不存在此文件,make會在一些默認的去尋找。它和使用 環(huán)境變量指定的makefilemakemake不會將其作為“終極目標”來看待。如果在make的工作下沒有一個名為“MakefileStop.而在make的工作下存在這樣一個文件“Makefilemakefile”或者“GNUmakefilemake make時,如果不能找到其中某一個文件(不存在或者無法創(chuàng)建。make不會提示錯誤,也不退出。就是說環(huán)境變量“MAKEFILES”定義的包含文件是否存在不會導(dǎo)致make錯 列表,之后才是工作下的makefileinclude在make發(fā)現(xiàn)此關(guān)鍵字的時暫停正在的文件而轉(zhuǎn)去include”一級make都會“MAKEFILES”變量所指定的文件,將導(dǎo)致執(zhí)行出現(xiàn)式設(shè)置的“隱含規(guī)則”和定義的變量可以被任何make進程使用(有點象C語言login程序自動的在自己的工作環(huán)境中設(shè)置此環(huán)境變量,編寫的Makefile在其人的工作環(huán)境中肯定不能正常工作。因為別人的工作環(huán)境中可能沒有設(shè)置相同的環(huán)境變量“MAKEFILES變量make程序在多個makefile文件時,包括由環(huán)境變量“MAKEFILES”在對這些文件進行解析執(zhí)行之前make的文件名將會被自動依次追加到變這樣我們就可以通過測試此變量的最后一個字來獲取當前make程序正在makefilemakefile文件中如果使用指示符可能是指示符“includemakefile的內(nèi) include @echoname1=$(name1)@echoname2=執(zhí)行makename1=Makefilename2=inc.mk此例子中涉及到了make其他特殊變GNUmake.ARIABLES是此點之前makefile文件中所定義的所有全局變量列表包括空變(makefile文件的重Makefile可由其它文件生成例如RCS或SCCS文件如果Makefile由其它文件重建,那么在make在開始解析這個Makefile時需要重新更新后的Makefile、而不是之前的Makefile。make的處理過程是這樣的:make在讀入所有makefile文件之后,首先將所的每個makefile作為makefile文件明確makefilemakefile文件的更新之后,如果之前所任何一個makefile文件被更新,那么make就清除本次執(zhí)行的狀態(tài)重新一遍所有的makefile文件(此過程中,同樣在讀取完成以后也會去試圖更新所有的已經(jīng)的makefile文件,但是一般這些文件不會再次被重建,因為它們在時間戳上已經(jīng)是的。完成以后再開始解析已經(jīng)的makefile文件并開始執(zhí)行必要的動作。makefilemake自動重建它們。但是make在每一次執(zhí)行時總會自動地試圖重建那些已經(jīng)存在的makefile的隱含規(guī)則。例如我們可以書寫一個明確的規(guī)則,以makefile文件作為目標,規(guī)則令定義為空。Makefilemake(此規(guī)則定義令會被無條件執(zhí)行如果這樣一個規(guī)則的目標是makefile文件那么執(zhí)行makemakefile(雙冒號規(guī)則的目標就會被無條件更新,make的執(zhí)行陷入到一個死循環(huán)(akefile文件被不斷的更新、重新更新再重新的過程為了防止這種情況的發(fā)生make在遇到一個目makefile(其中包括了使MFILudemake的所有makefile文件中定義的這一類雙冒號規(guī)則。執(zhí)行make時,如果沒有使用“-f(--file”選項指定一個文件,make程序?qū)⑷笔〉奈募:褪褂谩?f(--file”選項不同,make無法確定工作 是否存在缺省名稱的makefile文件。如果缺省makefile文件不存在,但可以通過一個規(guī)則來創(chuàng)建它(此規(guī)則是隱含規(guī)則,則會自動創(chuàng)建缺省makefile文件,之后重新它并開始執(zhí)行。 下不存在一個缺省的makefile文件,make將會按照搜索makefile文件的名稱順序去試圖創(chuàng)建它,直到創(chuàng)建成功或者其缺省的命名順序。需要明確的一點是:執(zhí)行make時,如果不能成功地創(chuàng)建缺省的makefile文件,并不一定會導(dǎo)致錯誤。一個存在(缺省命名的或者可被創(chuàng)建的)的makefile文件并不是make正確運行的前提(關(guān)于這一點大家會在后續(xù)的閱touch”件的時間戳)時,對于哪些是makefile(makefile文件)make時使用了選項“-tmakefile文件的規(guī)則同樣也會被執(zhí)行(makefilemakequestion過時的makefile文件對其它目標的重建規(guī)則在當前看來可能是錯誤的。正因為如此,執(zhí)行命令“make–fmfile–no”首先會試圖重建“mfile文件并重新它之后會打印出更新目“foo所要執(zhí)行(但不會真正的執(zhí)行這些命令makefilemakemaefie文件作為一個最終目標,這樣選–tmakefilemakefile(-tmakefile文件的時間戳。同樣,命令“make–fmfile–nmfilefo”會文件“mfile,打印出重建文件“mfile”令、重建“foo”令而實際不執(zhí)行任何命令。并且所打印的用于更“foo目標令是選“-f指定的沒有被重建“mfile件中所定義令。重載另外一個makefile文件。其中一個(makefile-A)用這種方式,如果在兩個makefile文件中存在相同目標,而在不同的文件中其描述規(guī)則使用不同令。這樣,相同的目標文件就同時存在兩個不同的規(guī)則命令,這是makefile所不允許的。遇到這種情況,使用指示符“include”顯然是行不通的。GNUmake提供另外一種途徑來實現(xiàn)此目的。具體的做法如下:makefile文件中不能找到重建一個目標的規(guī)看一個例子,如果存在一個命名為“Makefile”的makefile文件,其中描述目標“foo”的規(guī)則和其他的一些規(guī),我們也可以書寫一個內(nèi)容如下命名為#sampleGNUmakefilefrobnicate>%:@$(MAKE)-fMakefile$@:;執(zhí)行命令“makefoomake將使用工作下命名為“GNUmakefile”的文件并執(zhí)行目標“foo”所在的規(guī)則,創(chuàng)建目標“foo”令是“frobnicate>foobar目標的更則。make將使用“所有匹配模式”規(guī)則,執(zhí)行命令“$(MAKE)-fbar規(guī)則會被執(zhí)行。此過程同樣適用于其它“GNUmakefile”中沒有給出的目標更標“foo”的重建規(guī)則,由于make執(zhí)行時首先文件“GUNmakefile”并在其中能夠找到目標“foomake就不會去執(zhí)行這個“所有模式(包含一個makefile文件時所帶來的目標規(guī)則的重復(fù)定義問題。%(定是否需要重建這個目標文件make程序試圖尋找一個規(guī)則去創(chuàng)建目標“”時,又使用了模式規(guī)則“%:”而make如何解析makefile文GUNmake第一階段:所有的makefile文件(包括“MAKIFILES”變量指定的、指示符“include”指定的、以及命令行選項“-f(--file)”指定的makefile文件,理解makeMakefilemake執(zhí)行的第一階段中如果變量和函數(shù)被展開,者在make處理的第二階段它們才會被展開。我們會一步一步的熟悉make內(nèi)容。相信在看完本書之后,會對make的整個過程有全面深入的理解變量定析的規(guī)則如下IMMEDIATE=DEFERREDIMMEDIATE?=DEFERREDIMMEDIATE:=IMMEDIATEIMMEDIATE+=DEFERREDor當變量使用追加符(+=)時,如果此前這個變量是一個簡單變量(:=定義ifdefifeq所有的規(guī)則在makeIMMEDIATE:IMMEDIATE;DEFERRED總make依次變量“MAKEFILES”定義的makefile文件列工 下的makefile文(根據(jù)命名的查找順“GNUmakefile“makefile“Maefile,依次工 makefile文件中使用指示符“include”包含的文查找重建所有已的makefile文件的規(guī)則(如果存在一個目標是當前的某一個makefile文件,則執(zhí)行此規(guī)則重建此makefile文件,完成以后從第一步開始重新執(zhí)行 第四章:Makefile的規(guī)本章討論Makefile的一個重要內(nèi)容,規(guī)則。熟悉規(guī)則對于書寫(除了makefile的“終極目標”所在的規(guī)則以外,其它規(guī)則的順序在makefile文件中沒有意義“終極目標”就是當沒有使用make命令行指定具體目標時,make默認的更新的哪一個目標。它是makefile文件中第一個規(guī)則的目標。如果在makefile中第一個規(guī)則有多個目標的話,那么多個目標中的第一個將會被作為make的“終極目標。有兩種情況的例外:1.目標名以點號“.”開始的并且“/“./” “../” ;2.模式規(guī)則的目標。當這兩種目標所在的規(guī)則是Makefile的第一個規(guī)則時,它們些目標所在規(guī)則在Makefile中的順序無關(guān)緊要。makefile一個foo.o:foo.cdefs.h #modulefortwiddlingthefrobscc-c-gfoo.c(foo.o( “foo.cdefs.h 如何重建目標文件“foo.o。這個規(guī)則中使用cc編譯器。規(guī)則令中defs.h規(guī)則TARGETS:PREREQUISITESTARGETS:PREREQUISITES;COMMAND(規(guī)則“TARGETS”可以是空格分開的多個文件名也可以是一個例clean“M(make更新靜態(tài)庫文件。通常規(guī)則只有一個目標文件(建議( 規(guī)則令部分有兩種書寫方式:a.命令可以和目標:依賴描述放在同()命令在目標依賴的描述的下一行作為獨立令行當作為獨立令行時此行必須以[Tab]字符開始Makefile在第一個規(guī)則之后出 Makefile中符號“$”有特殊的含義(表示變量或者函數(shù)的,在規(guī)“$$ Makefile\”makeMakefile。一個規(guī)則告訴“make”兩件事:1.2.如果前提條件是以下兩者之一:1.2.目標文件存在,但是規(guī)則的一處改動將導(dǎo)致目前已經(jīng)存在的目標文件的內(nèi)容過期規(guī)則令為重建標提供了方法。這些命令運行在系統(tǒng)s之上。依賴的類在GNUmake的規(guī)則中可以使用兩種不同類型的依賴:1.以前章節(jié)所提到Makefile規(guī)則時最常用的一種。2.另外Makefile時不會經(jīng)常使用,它比較特殊、稱之為“order-only”這個規(guī)則的目標(執(zhí)行此規(guī)則令行)之前需要按照什么樣的順序、執(zhí)行那些規(guī)則。就是說對于這樣的規(guī)則:A:BC,那么在重建目標A之前,首先需要完成BCBCMakefile中以文件B和C為目標的規(guī)則。其次,它確定了一個依存關(guān)系;規(guī)則中如果依賴文件有時,需要定義一個這樣的規(guī)則,在更新目標(目標文件已經(jīng)存在)時只分類,一類是在這些依賴文件被更新后,需要更則的目標;另一類是更新這“order-order-|LIBS=foo:foo.c|$(CC)$(CFLAGS)$<-o$@目標“foo”將會被重建,但是當“l(fā)ibtest.a”被修改以后。將不執(zhí)行規(guī)則令來重建文件名使用通配Maekfile?”和“[…]。在Makefile中通配符的用法和含義和Linux(unix)的Bournes完*.c.c”結(jié)尾的文件等。但是Makefile中這些統(tǒng)配符并不是可以用在任何地方,Makefile中統(tǒng)配符可以出 可以用在規(guī)則的目標、依賴中,make在Makefile時會自動對其進; 可出現(xiàn)在規(guī)則令中,通配符的通配處理是在s “(\foo\*bar在Makefilefoo*barMakefile中對一些特殊字符的轉(zhuǎn)移和B- C(~/(在s~(~\)~/bin(當前用戶宿主下的bin。波浪線之后跟一個單詞(~word,代表由這個“word”所指定的用戶的宿主。例如“~john/binjohn的宿主下的bin。Windows 由s進行處理。例如Makefile的清空過程文件規(guī)則:rm-f通配符也可以用在規(guī)則的依賴文件名中。這個例子。執(zhí)行“makeprintprint:lpr-ptouch兩點說明:1.上述的規(guī)則中目標“print(當前下存在一個文件“print后一次執(zhí)行此規(guī)則的時間。2.自動環(huán)變量“$?”在這里表示依賴文件列表中被符,否則在某些情況下會出現(xiàn)非預(yù)期的結(jié)果,下一小節(jié)將會詳細討論。在objects*.o字符串“*.o(wildcard(objects=*.o)Makefile.ofooobjects=*.ofoo:$(objects)cc-ofoo$(CFLAGS)”的值是一個字符串“*.o*.o如果在工作下已經(jīng)存在必需的.o文件,那么這些.o文件將成為目標的依賴但是如果將工作下所有的.omake*.o))函數(shù)之前提到過,在規(guī)則中,通配符會被自動展開。但在變量的定義和函數(shù)wildcard它的用法是:$(wildcardPATTERN...)Makefile中,它被展開為已經(jīng)存在一般我們可以使用“$(wildcard*.c)”來獲取工作下的所有的.c文件列*.c))“wildcard”函數(shù)獲取工作下的.c文件列表;之后將列表中所有文件名的后綴.c替換為.o。這樣我們就可以得到在當前可生成的.o文件列表。因此在一個下可以使用如下內(nèi)容的Makefile來將工作下的所有的.c文件進行編#sampleobjects:=$(patsubst%.c,%.o,$(wildcardfoo:cc-ofoo這里我們使用了make的隱含規(guī)則來編譯.c(:=搜在一個較大的工程中一般會將源代碼和二進制文(.o文件和可執(zhí)行文件) 來進行區(qū)分管理。這種情況下,我們可以使用make提供的目 下自動搜索依賴文件。在Makefile 不更改Makefile的規(guī)則,只更改依賴文件的搜索 本節(jié)詳細討論在書寫Makefile時如何使用這一特性。在自己的工一般搜索(變量VTH定依賴文件的搜索路徑,當規(guī)則的依賴文件在當前不存在時,make會在此變量所指定的定義變量“VPATH”時,使用空格或者冒號(:)將多個需要搜索的分開。make搜索的順序是按照變量“VPATH”定義中的順序進行的(當前是第一搜索。例如對變量的定義如下:src”和“../headersfoo:foo.cfoo.cfoo:src:/foo.c不類型的文件指定不同的搜索時,需要使用另外式。下一小節(jié)選擇性搜索(關(guān)鍵字make的“vpath”關(guān)鍵字(全小寫的make的關(guān)鍵字,它所實現(xiàn)的功能和上一小節(jié)文件名區(qū)分)指定不同的搜索。它的使用方法有三種: “S多 (2、vpath3、%%.h”表示所有以“.h”結(jié)尾的文件。如果在%就是給定了此文件的所在(和其他的特使字符的一樣。定了搜索此類文件。當規(guī)則的依賴文件列表中的文件不能在當前下找到時,makeDIRECTORIES”所描述的下尋找此文件。例如:vpath%.h其含義是:Makefile中出現(xiàn)的.h文件;如果不能在當前 “../headers”下尋找。注意:這里指定的路徑僅限于在Makefile文件內(nèi)容中出現(xiàn)的.h文件。并不能指定源文件中包含的頭文件所在的路徑(在.c源文件中所包含的頭文件路徑需要使用gcc“-I”選項來指定可參考gcc的info文檔“PATTERNmake就對這些vpath語句一個一個進行處理,搜索某種模式文件的 有的通過vpath指定的符合此模式的多個 的順序由vpath語句在Makefile出現(xiàn)的先后次序來決定。多個具有相同“PATTERN”的vpath語句之間相互獨立。下邊是兩種方式下,所有的.c文件的查找 的搜索處于最優(yōu)先地位)比較:vpath%.cfoovpath%blishvpath%.c表示對所有的.c文件,make依次查 “foovpath%.cfoo:barvpath%blish對于所有的.c文件make將依次查 “foo ,/home/Stallman/fo.c“foo:foo.c在執(zhí)行搜索后可能得到的依賴文件為“../src/foo.c” 門討論。makeMakefile文件執(zhí)行規(guī)則時對文件路徑保存或廢棄所依據(jù) 首先,如果規(guī)則的目標文件在Makefile文件所在的 完成第三步的依賴處理后,make程序就可以決定規(guī)則的目標是否需要 的路徑名無效規(guī)則中的目標文件將會被在工 下重建就是說 makemake則使用了一種比較簡單的(通過搜索可以定位到目標文件,無論該目標是否需要重建,都使用搜索到的目標文件完整路徑名。實際上,GNUmake也可以實現(xiàn)這種功能。如果需要make在執(zhí)行時,將目GPATH”變量來指定這些目標所在的GPATH”變量和“VPATH”變量具有相同的語法格式。make在執(zhí)行時,如果通過搜尋得到一個過時的完整的目標文件路徑名,而目標存在的又出現(xiàn)在“GPATH”變量的定義列表中,則該目標的完整路徑將不廢prom“prom”的子srcsum.cmemcp.cprom”下的MakefileLIBS=libtest.aVPATH=srclibtest.a:sum.o$(AR)$(ARFLAGS)$@ “prom”“src)“ea行make時將會在當前 “l(fā)ibtest.alibtest.a makemake程序會搜索到“src”下的已經(jīng)存在的目標“l(fā)ibtest.a重建目標。并且目標所在的不會發(fā)生變化。 當我們修改了文sum.cmemcp.c以后執(zhí)行makelibtest.a”和“sum.o”或者“memcp.o”文件將會被在當前下創(chuàng)建(目標完整路徑名被廢棄src”下更新這些已經(jīng)存在的文件。此時在兩個下“prom”和“src)同時存在文件“l(fā)ibtest.a“prom/libtest.a”是的庫文件。當在上邊的MakefileGPATH”指定時,情況就不一樣了。首先看看怎么使用“GPATHMakefile內(nèi)容如下:LIBS=LDFLAGS+=-L./.同樣;當兩 都不存在目標文件“l(fā)ibtest.a”時,目標將會在當“prom” “l(fā)ibtest.a其依賴文件任何一個被改變以后執(zhí)行make,目標“l(fā)ibtest.a”將會被在下被更新(目標完整路徑名不會被廢棄make在執(zhí)行時,通過搜索得到的目標的依賴文件可能會在其它此因此書寫命令時須保證當依賴文件在其它下被發(fā)現(xiàn)時規(guī)則令能解決這個問題的方式是在規(guī)則令行中使用“自動化變量,諸如“$^”等。規(guī)則命令行中的自動化變量“$^”代表所有通過搜索得到的依賴文件的完整路徑名(+一般文件名)$@”代表規(guī)則的目標。所以對于一foo.o:cc-c$(CFLAGS)$^-o變量“CFLAGS”是編譯.cgccMakefile中給它指件(make程序決定目標是否需要重建時才有意義。$^VPATH=src:../headersfoo.o:foo.cdefs.hhack.hcc-c$(CFLAGS)$<-o$<”代表規(guī)則中通過搜索得到的依賴文件列表的第一個依Tvpathfoo.Mkefile中沒有重建它的明確規(guī)則,makefoo.foo.makemake會使用隱含規(guī)則根據(jù)搜索到的文件完整的路徑名去重建目標,編譯這個.c源文件。隱含規(guī)則中令行中就是使用自動化變量來解決搜索可能帶來的問題;相應(yīng)令中的文件名都是使用搜索得到的完整的路徑名(可參考上Makefile中程序的靜態(tài)庫、共享庫同樣也可以通過搜索得到。這一lNAME話這就不難理解了“-lNAME”的表示方式和ld的對庫的方式完全一Makefile的規(guī)則時使用了這種書寫方式。所以你不應(yīng)該感態(tài)連接還是靜態(tài)連接,這里我們不討論。來看一下詳細的過程。1.make在執(zhí) 下搜索一個名字為“l(fā)ibNAME.so”的文件;2.如果當前 “VPATH 。3.還是不存在,make將搜索系統(tǒng)庫文件存在的默認 “/lib“PREFIX/lib(“usr/local/lib,/usr/lib/bcures.a(/usr/lib/libcures.sofoo:foo.c-lcursescc$^-o$@時將使用命令“ccfoo.cusr/lib/libcurses.aofoo”來完成目標文件的重建。需能這樣寫,因為“-lNAME”只是告訴了器在生成目標時需要那個庫文當所有的搜索中不存在庫“l(fā)ibcurses”時。Make將提示“沒有規(guī)則可以創(chuàng)lcurseslibNAME.a模式字符(%)而得到第一個庫文件名,根據(jù)這個庫文件名在搜索LIBTTENSlib%.solib%.a這也是默認情況下在規(guī)則存在“-lNAME”格式的依賴時,生成目標時使用變量“.LIBPATTERNS”就是告訴器在執(zhí)行過程中對于出現(xiàn)“-LNAME”的文件如何展開。當然我們也可以將此變量制空,取消器對“-Makefile偽目Makefile的一個重要的特殊目標:偽目標。偽目標是這樣一個目標:它不代表一個真正的文件名,在執(zhí)行make時可以指定這個目標來執(zhí)行原因:1.Makefile中定義的只執(zhí)行命令的目標(此目標的目的為了執(zhí)行執(zhí)行一些列命令,而不需要創(chuàng)建這個目標)和工作下的實際文件出現(xiàn)名字。2.提高執(zhí)行make時的效率,特別是對于一個大型的工程來說,編如果我們需要書寫這樣一個規(guī)則:規(guī)則所定義令不是去創(chuàng)建目標文件,而是通過make命令行明確指定它來執(zhí)一些特定令。像常見的clean目rm*.o規(guī)則中“rm”不是創(chuàng)建文件“clean”令,而是刪除當前下的所有.o文temp文件。當工作下不存在“clean”這個文件時,我們輸入“makecleanrm”但是如果在當前工作下存在文件“cleanclean”標為偽目標的方法是將它作為特殊目標.PHONY”的依賴。如下.PHONY:這樣目“clean”就被為一個偽目標無論在當前 這個文件。我們輸入“makeclean”之后“rm”命令都會被執(zhí)行。而且,當一個目標被為偽目標后,make在執(zhí)行此規(guī)則時不會去試圖去查找隱含規(guī)則來創(chuàng)建它。這樣也提高了make的執(zhí)行效率,同時也不用擔心由于目標和文件名重名而使我們的期望失敗在書寫偽目標規(guī)則時首先需要目標是一個偽目標,.PHONY:rm*.omake的并行和遞歸執(zhí)行過程中。此情況下一般會存在一個變量,定義為所有需要make的子。對多個進行make的實現(xiàn)方式可以是在一個規(guī)則令行中使用s循環(huán)來完成如下:SUBDIRS=foobarfordirin$(SUBDIRS);do$(MAKE)-C$$dir;但這種實現(xiàn)方法存在以下幾個問題。1.當子執(zhí)行make出現(xiàn)錯誤時,make不會退出。就是說,在對某一個執(zhí)行make失敗以后,會繼續(xù)對其他的進行make。在最終執(zhí)行失敗的情況下,我們很難根據(jù)錯誤提示定位出具體是在那個下執(zhí)行make時發(fā)生錯誤。這樣給問題定位造成了很大的。為了解題就是使用這種s的循環(huán)方式時,沒有用到make對的并行處理功能,由于規(guī)則令是一條完整的s命令,不能被并行處理。SUBDIRS=foobar.PHONY:subdirs$(SUBDIRS)subdirs:$(SUBDIRS)$(MAKE)-Cfoo:上邊的實現(xiàn)中有一個沒有命令行的規(guī)則“foo:bazmake順序。它的作用是限制同步“foo”和“baz”的make過程(在處理“foo”之前,需要等待“baz”處理完成。提醒大家:在書寫一個并行執(zhí)行make的Makefile時,的處理順序是需要特別注意的。文件的依賴包含偽目標時每一次在執(zhí)行這個規(guī)則時偽目標所定義令都會被件的依賴時我們只能通過make令行來明確指定它為make的終極目標,來執(zhí)行它所在規(guī)則所定義令。例如“makeclean在Makefile(可以是一個或者多個文件、一個或者多個偽目標。在一個下如果需要創(chuàng)建多個可執(zhí)行程序,我們可以MakefileMakefile中第一個目標是#sampleall:prog1prog2.PHONY:prog1:prog1.occ-oprog1prog1.oprog2:cc-oprog2prog2.oprog3:prog3.osort.outils.occ-oprog3prog3.osort.o執(zhí)行make時,目標“all”被作為終極目標。為了完成對它的更新,make會創(chuàng)prog3makeprog1行C語言中的函數(shù)調(diào)用一樣。下邊的例子就是這種用法:.PHONY: lcleanobjclel:cleanobjcleandiffrmprogramcleanobjrmcleandiffrm“clearall時會觸發(fā)它們所定義令被執(zhí)行我們可以輸“makeclel”例子首先通過特殊目“.PHONY了多個偽目標它們之間使用空各分割,通常在清除文件的偽目標所定義令中“rm”使用選項“–f(--)來之前加上“-”來防止“rmmake會提示錯誤信息但不會退出。為了不看到這些討厭的信息,需要使用上述的第式。另外make存在一個內(nèi)嵌隱含變量“RM它被定義為RMrm–f因“rm,強制目標(沒有命令或依賴的規(guī)則如clean:rm:這個例子中,目標“”符合上邊的條件。它作為目標“clean”的依賴,在執(zhí)行make時,總被認為被更新過。因此“clean”所在規(guī)則在被執(zhí)行時其所定義令總會被執(zhí)行。這樣的一個目標通常其命名為“”上邊的例子中使用“”目標的效果和將“clean為偽目標效果在非GNU版本的make中?!痹谑褂肎NUmake,應(yīng)避免使用這種方式。在GNUmake中我們推薦使用空目標文——通過make命令行指定將其作為終極目標來執(zhí)行此規(guī)則所定義令和偽錄此規(guī)則命令的最后執(zhí)行時間。make時通過命令行將此目標作為終極目標,當 “touch極目標,在它所依賴的文件比它新時,此目標所在規(guī)則令行將被執(zhí)行。就是說如果空目標的依賴文件被改變之后空目標所在規(guī)則中定義令會被執(zhí)行。print:foo.cbar.clpr-p$?touchprintprint–p$?”都會被執(zhí)行,打印這個被修改的文件。Makefile的特殊目們是一些特殊的目標,GNUmake所支持的特殊的目標有:使用make命令行指定此目標時,這個目標所在規(guī)則定義令、無論目標文件后綴名(就是當前make需要處理的后綴。Makefile中,目標“.DEFAULT”所在規(guī)則定義令,被用在重建那些沒賴,但卻不是另外一個規(guī)則的目標時。Make程序無法找到重建此文件的規(guī)則,此種情況時就執(zhí)行“.DEFAULT”所指定令。目標“.PRECIOUSmake間過程文件,同樣這些文件不會被刪除。這一點目標“.PRECIOUS”和目標%.o.INTERMEDITE.DELETE_ON_ERRORmake過程中,如果規(guī)則令執(zhí)行錯誤,將刪除已經(jīng)被修改的目標文件。目標“.LOW_RESOLUTION_TIMEmake認為是低分辨率通常文件的時間輟都是高分辨率的,make在處理依賴關(guān)系時、對規(guī)則目標作為目標“.LOW_RESOLUTION_TIME”的依賴,這個文件是一個低分辨.LOW_RESOLUTION_TIME:dst:cp-psrcdst晚(因為命令不能更新文件“dst”的細粒度時間make在判斷文件依賴的情況下,某些命令在make中的一些缺陷。出現(xiàn)在目標“.SILENT”的依賴列表中的文件,make在創(chuàng)建這些文件時,不打印出重建此文件所執(zhí)行令。同樣,給目標“.SILENT”指定命令行是沒沒有任何依賴文件的目標“.SILENT”告訴make在執(zhí)行過程中不打印任何執(zhí)行令。現(xiàn)行版本make支持目標“.SILENT”的這種功能和用法是為了和silent變量傳遞給子make進程。.NOARALLEL行,即使存在make令行參數(shù)“-。但在遞歸調(diào)用的字make進程中,命.c.o“$@kbd.ocommand.ofiles.o: 對于多個具有類似重建命令的目標。重建這些目標令并不需要是完bigoutputlittleoutput:generatetext.g-$(substoutput,,$@)>bigoutput:generatetext.g-big>bigoutputlittleoutput:text.ggeneratetext.g-little>的字符串處理函數(shù)“subst”來根據(jù)目標產(chǎn)生對應(yīng)令行選項$@實現(xiàn)這個目的是,要用到make的靜態(tài)模式。多規(guī)則目文件和依賴文件的時間戳)時,make將會執(zhí)行特定令來重建這個目標。makeGNUmake中應(yīng)該避免使用這個功能。某些情objects它定義為所有的需要編譯生成的.o文件的列表。當這些.o文件在其源文件所包的方式來書寫Makefile:objects=foo.obar.ofoo.o:defs.hbar.o:defs.h$(objects):已經(jīng)存在的Makefile.o文件依賴的頭文件。在一個大的工程中,對于一個單獨下的.o文件的依賴規(guī)則建議使用此方式。規(guī)則中頭文件的依賴描述規(guī)則也可以使用gcc自動產(chǎn)生。$(objects):的.o文件的依賴文件。當然我們只執(zhí)行“make”的話,就沒有指定任何文件作為.o文件的依賴文件。在多規(guī)則的目標中,如果目標的任何一個規(guī)則沒有定義重建此目標令,make將會尋找一個合適的隱含規(guī)則來重建此目標。關(guān)于隱含規(guī)則可參考第十章make的隱含規(guī)則靜態(tài)模%(TAGET-PATTERN)中“%”可以匹配目標文件的,模式字符“%”%.ofooPATTERNS)中的模式字符“%”而得到。例如:上邊的例子中依賴模式為“%.cfoofoo.c 。反斜杠也可以由的反斜杠“%“\”的反斜杠在和文件名比較或 “%”而如,最后的兩個反斜杠由于沒有任何轉(zhuǎn)義“%”所以保持不變。。我們來看一個例子,它根據(jù)相應(yīng)的.c文件來編譯生成“foo.o”和“bar.o”objects=foo.obar.oall:$(objects)$(objects):%.o:$(CC)-c$(CFLAGS)$<-o例子中規(guī)則描述了所有的.o文件的依賴文件為對應(yīng)的.c文件對于目foo.ofoo.cfoo.cfoo.o$<$@foo.o:$(CC)-c$(CFLAGS)foo.c-ofoo.obar.o:bar.c$(CC)-c$(CFLAGS)bar.c-omakefiles=foo.elcbar.o$(filter%.o,$(files)):%.o:$(CC)-c$(CFLAGS)$<-o$(filter%.elc,$(files)):%.elc:%.elemacs-f pile$<$(filterlose.ofilter些目標文件是通過編譯對應(yīng)的.cbigoutputlittleoutput:%output:text.ggeneratetext.g-$*>$@當執(zhí)行此規(guī)則令時,自動環(huán)變量“$*”被展開為“莖。在這里就是“big”和“l(fā)ittlemake.rules的文件中。在工程各個模塊的Makefile中包含此文件。Makefile的文件依賴關(guān)系,兩者不同的地方是make在執(zhí)行時使用它們的時機。Makefile中沒有為這個目相反的,靜態(tài)模式規(guī)則只能用在規(guī)則中明確的那些文件的重建過程中。 對于無法確定工作內(nèi)容,并且不能確定是否此下的無關(guān)文件make失敗的情況。當存在多個適合此雙冒號規(guī)冒號規(guī)則允許在多個規(guī)則中為同一個目標指定不同的重建目標令。Makeile的不同點表現(xiàn)在以下幾個方面: 沒有依賴而只有命令行的雙冒號規(guī)則當此目標時規(guī)則令將會被無條件執(zhí)行而普通規(guī)則當規(guī)則的目標文件存在時此規(guī)則令永遠不會被執(zhí)行(目標文件是的。 我們來看一個例子,在我們的MakefileNewprog::$(CC)$(CFLAGS)$<-o$@Newprog::bar.c$(CC)$(CFLAGS)$<-ofoo.cfoo.cNewprog果以上兩個規(guī)則為普通規(guī)時出現(xiàn)的情況是什么?(make將會出錯并提示錯誤信行順序一樣,按照其在Makefile中的書寫順序執(zhí)行。GNUmake的雙冒號規(guī)則給我們提供一種根據(jù)依賴的更新情況而執(zhí)行不同自動產(chǎn)生Makefile中,有時需要書寫一些規(guī)則來描述一個.o文件和頭文件的依賴關(guān)defs.h像下邊那樣的規(guī)則來描述當頭文件“defs.hmake,目標main.o:Makefile中書寫很多條類似于這樣的規(guī)則。并且當在源文件中加入或刪除頭文件后也需要地去修改Makefile這一件非常費力費時并且容易出錯誤工作為了避免這個討厭的問題,現(xiàn)代的c#ude通過“-M-Mgcma.ch,那么在Lu下執(zhí)行下面令:gcc-Mmain.o:main.cma.cgcc-Mgcc需要使用“-MM”參數(shù)。在使用gcc自動產(chǎn)生依賴關(guān)系時,所產(chǎn)生的規(guī)則中明確的指明了目標是“main.o.c文件直接產(chǎn)生可執(zhí)行文件時,作為中間過程文件的makeMakefile中書寫一個偽目標“depend”的規(guī)則來定義自動產(chǎn)生依賴關(guān)系文件令。輸入依賴規(guī)則描述。Makefile中使用“include在新版本的makeNAME.c“NAME.d件“NAME.o我們可以使用如下的模式規(guī)則來自動生成每一個.c文件對應(yīng)的.d%.d:$(CC)-M$(CPPFLAGS)$<>$@.$$$$;sed's,\($*\)\.o[:]*,\1.o$@:,g'<$@.$$$$>$@;\rm-f$@.$$$$此規(guī)則的含義是:所有的.d文件依賴于同名的.c第一行;使用c編譯器自自動生成依賴文件($<)的頭文件的依賴關(guān)系,并$$$$MM”代替“-Msed處理第二行已產(chǎn)生的那個臨時文件并生成此規(guī)則的目標文件。這里sed完成了如下的轉(zhuǎn)換過程。例如對已一個.c源文件。將編譯器產(chǎn)生main.o:main.cmain.omain.d:main.c這樣就將.d.o文件文件一樣依賴于對應(yīng)的.c.c源文件或者頭文件被改變之后規(guī)則將會被執(zhí)行,相應(yīng)的.d文件同樣會被更新。使用上例的規(guī)則就可以建立一個描述目標文件依賴關(guān)系的.d文件。我們可以在Makefile中使用include指示符將描述將這個文件包含進來。在執(zhí)行make下.dsources=foo.cbar.csinclude$(sources:.c=.d)例子中,變量“sources”定義了當前下的需要編譯的源文件。變量置換“$(sources.c=.d)”的功能是根據(jù)變量“source”指定的.c文件自動產(chǎn)生對應(yīng)的.d文件,并在當前Makefile文件中包含這些.d文件。.d文件和其它的一些可被make解析的makefile文件。則。當一個Makefile使用指示符include這些.d文件時,應(yīng)該注意它應(yīng)該出現(xiàn)在終極目標之后,以免.dMakefile的終極規(guī)則。關(guān)于這個前面第五章:規(guī)則通常系統(tǒng)中可能存在多個不同的s。但在make處理Makefile過程時,執(zhí)行過程所使用的s決定了規(guī)則中令的語法和處理機制。當使用默makemakefile文件時,對待注釋也是采用同樣的處理方式。我們的s也一樣。命令回通常,make在執(zhí)行命令行之前會把要執(zhí)行令行輸出到標準輸出設(shè)備。我們稱之為“回顯,就好像我們在s環(huán)境下輸入命令執(zhí)行時一樣。@echoXXX模塊 @echoXXX模塊XXX模塊print,make才會打印出所有make需要執(zhí)行令,其中也包括了使用“@”字符開始令。這個選項對于我們調(diào)試Makefile非常有用,使用這個選項我們可以按執(zhí)行順序打印出Makefile中所有需要執(zhí)行的所有命令。而make參數(shù)“-s”或“--slient”則是所有執(zhí)行命令的顯示,就好像所有令行均使用“@”開始一樣。在Makefile中使用沒有依賴的特殊目標書寫Makefile時,我們推薦使用“@”來控制命令的回顯。命令的行命令,那么每一行命令將在一個獨立的子s 行命令的執(zhí)行是在一個獨立的s 在Makefile中書寫在同一行中的多個命令屬于一個完整的s命令行,書寫在獨立行的一條命令是一個獨立的s命令行因此在一個規(guī)則令中,命令“c改變不會對其后令的執(zhí)行產(chǎn)生影響就是說其后令執(zhí)行的工作d就不能“c和其后令放在兩行來書寫而應(yīng)該把這兩條命令寫在一行上,用分號分隔。這樣它們才是一個完整的s命令行。如:foo:cdbar;gobblelose>如果希望把一個完整的s命令行書寫在多行上,需要使用反斜杠(\)來對處于多行令進行連接,表示他們是一個完整的s命令行。例如上例我foo:cdbar;\gobblelose>../foomake對所有規(guī)則命令的解析使用環(huán)境變量“S 在GNUmake中,默認的程序是“/bin/shmake的環(huán)境變量“S 直接交互過程的make顯然不合適。在make的環(huán)境變量中“S 賦值;它作為一個變量我們也可以在Makefile中明確地給它賦值(解釋程“/bin/sh /bin/sh(在MS-DOS下有些不同,MS-DOS不存在S環(huán)境變量這里不對MS-DOS下make進行介紹,有地可以自行參考infomake關(guān)于此部分的并發(fā)執(zhí)行命GNUmake令同時被執(zhí)行(MS-DOS中此選項無效,因為它是單任務(wù)操作系統(tǒng)如果選項“-jmake在同一時刻可允許slotsslots為1表示make將串行的執(zhí)行規(guī)則(同一時刻只能有一條命令被執(zhí)行。 多個同時執(zhí)令的輸出信息將同時被輸出到終端。當出現(xiàn)錯誤時很難 在同一時刻可能會存在多個命令執(zhí)行進程同時標準輸入,但是對于標準輸入設(shè)備來說在同一時刻只能存在一個進程它就是說
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 總經(jīng)理年會致辭15篇
- 開學(xué)典禮大會學(xué)生發(fā)言稿(5篇)
- 學(xué)校社團活動總結(jié)(合集15篇)
- 湖南省永州市高三上學(xué)期第一次模擬考試語文試題(含答案)
- 水下自激吸氣式射流裝置沖刷特性研究
- 二零二五年度社會保險停繳合同范本(國有企業(yè))3篇
- 基于FPGA的聲紋識別系統(tǒng)研究與實現(xiàn)
- 二零二五版外專局外籍教師教學(xué)成果推廣與應(yīng)用合同規(guī)范3篇
- 融資租賃合同出租人取回權(quán)制度的法律問題研究
- 建筑與市政工程巡查結(jié)果的評估與總結(jié)
- 文檔協(xié)同編輯-深度研究
- 七年級數(shù)學(xué)新北師大版(2024)下冊第一章《整式的乘除》單元檢測習(xí)題(含簡單答案)
- 2024-2025學(xué)年云南省昆明市盤龍區(qū)高一(上)期末數(shù)學(xué)試卷(含答案)
- 五年級上冊寒假作業(yè)答案(人教版)
- 2025年山東浪潮集團限公司招聘25人高頻重點提升(共500題)附帶答案詳解
- 2024年財政部會計法律法規(guī)答題活動題目及答案一
- 2025年江西省港口集團招聘筆試參考題庫含答案解析
- 2025年中考語文復(fù)習(xí)熱搜題速遞之說明文閱讀(2024年7月)
- (2024年)中國傳統(tǒng)文化介紹課件
- 綜治工作培訓(xùn)課件
- 液化氣安全檢查及整改方案
評論
0/150
提交評論