版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第5章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第5章Make及makefile文件的編寫 1.1Linux系統(tǒng)下的文件編譯程序的編譯和鏈接源程序(.c)編譯(compile)鏈接(linker)形成目標文件形成可執(zhí)行程序(1)預編譯(2)匯編階段Linux系統(tǒng)下的文件編譯程序的編譯和鏈接源程序(.c)編譯2什么是make?Make是大型程序維護工具Make工作時,需要名字為“makefile”的makefile文件。根據(jù)依賴關系自動決定項目的那些部分需要重新編譯?;驹恚喝绻硞€源程序文件被修改,那么依賴這個源程序文件的所有目標文件,都需要重新編譯。什么是make?Make是大型程序維護工具3MakefileRuleRule的格式為:target…:prerequisites… command … …Target依賴prerequisites的目標Prerequisites被依賴的源程序,例如c文件或h文件Command需要執(zhí)行的命令當prerequisites任何一個文件的時戳新于target的時戳時,就執(zhí)行command。MakefileRuleRule的格式為:4makefile規(guī)則介紹一個簡單的Makefile描述規(guī)則組成:TARGET...:PREREQUISITES... <tab>COMMAND ...--target:規(guī)則的目標。--通常是程序中間文件(.o)或者最后可執(zhí)行文件名--目標也可以是一個make執(zhí)行的動作的名稱,如目標“clean”,這樣的目標是“偽目標--prerequisites:規(guī)則的依賴。--生成規(guī)則目標所需要的文件名列表。通常一個目標依賴于一個或者多個文件。--command:規(guī)則的命令行--是make程序所有執(zhí)行的動作(任意的shell命令或者可在shell下執(zhí)行的程序)--一個規(guī)則可以有多個命令行,每一條命令占一行。注意:每一個命令行必須以[Tab]字符開始makefile規(guī)則介紹一個簡單的Makefile描述規(guī)則組5makefile文件在makefile(Makefile)文件中,采用自頂向下到的方法來說明依賴關系network:network.osubrs.o(1)gccnetwork.osubrs.o–onetwork(2)network.o:etdefs.h(3)gcc–cnetwork.c-onetwork.o(4)subrs.o:etdefs.h(5)gcc–csubrs.c.PHONYcleanclean:rm-r*.o(6)makefile文件在makefile(Makefile)文6執(zhí)行make在makefile(Makefile)文件所在的目錄中,執(zhí)行make命令語法:make[選項][宏定義][目標文件]執(zhí)行make在makefile(Makefile)文件所在的7Make的工作過程1.make在當前目錄下找名字叫“Makefile”或“makefile”的文件2.如果找到,它會找文件中的第一個目標文件(target),比如找到“network”這個文件,并把這個文件作為最終的目標文件。3.如果network文件不存在,或是network所依賴的后面的.o文件的文件修改時間要比network這個文件新,那么,他就會執(zhí)行后面所定義的命令來生成network這個文件。4.如果network所依賴的.o文件也存在,那么make會在當前文件中找目標為.o文件的依賴性,如果找到則再根據(jù)那一個規(guī)則生成.o文件(使用源文件和.h文件)。(這有點像一個堆棧的過程)Make的工作過程1.make在當前目錄下找名字叫“Make8make時,哪些文件被重新編譯1.所有的源文件沒有被編譯過,則對各個C源文件進行編譯并進行鏈接,生成最后的可執(zhí)行程序;2.每一個在上次執(zhí)行make之后修改過的C源代碼文件在本make時將會被重新編譯;3.頭文件在上一次執(zhí)行make之后被修改。則所有包含此頭文件的C源文件在本次執(zhí)行make時將會被重新編譯。make時,哪些文件被重新編譯1.所有的源文件沒有被編譯9關于Makefile文件名默認的情況下,make命令會在當前目錄下按順序找尋文件名為“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解釋這個文件。也可以使用別的文件名來書寫Makefile,這是執(zhí)行Make命令時,需使用“-f”和“--file”參數(shù)。如:make-fMake.Linux或make--fileMake.AIX關于Makefile文件名默認的情況下,make命令會在當前10對“規(guī)則”的再認識在Makefile中“規(guī)則”就是描述在什么情況下、如何重建規(guī)則的目標文件,通常規(guī)則中包括了目標的依賴關系(目標的依賴文件)和重建目標的命令。make執(zhí)行重建目標的命令,來創(chuàng)建或者重建規(guī)則的目標(此目標文件也可以是觸發(fā)這個規(guī)則的上一個規(guī)則中的依賴文件)。規(guī)則包含了目標和依賴的關系以及更新目標所要求的命令。對“規(guī)則”的再認識在Makefile中“規(guī)則”就是描述在11一個簡單的例子1.注釋以#開頭2.一個較長行可以使用反斜線(\)分解為多行,\后不能有空格3.目標“clean”不是一個文件,它僅僅代表了執(zhí)行一個動作的標識。Makefile中把那些沒有任何依賴只有執(zhí)行動作的目標稱為“偽目標”在執(zhí)行make時,它所指定的動作不會被執(zhí)行。除非執(zhí)行make時明確地指定它作為重建目標。而且目標“clean”沒有任何依賴文件,它只有一個目的,就是通過這個目標名來執(zhí)行它所定義的命令。Makefile中把執(zhí)行“clean”目標所定義的命令,可在shell下輸入:makeclean。
一個簡單的例子1.注釋以#開頭12使用變量在上例的Makefile中可是添加這樣一行:objects=main.okbd.ocommand.odisplay.oinsert.o\search.ofiles.outils.o“objects”作為一個變量,它代表所有的.o文件的列表,在需要使用這些.o文件列表的地方使用“$(objects)”來表示它objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.oedit:$(objects)gcc$(objects)-oedit…….…….clean:rmedit$(objects)使用變量在上例的Makefile中可是添加這樣一行:13使用變量的例子exe:main.oio.ogccmain.oio.o-oexemain.o:main.c
gcc-g-cmain.c–omain.oio.o:io.c
gcc-g-cio.c-oio.oOBJS=main.oio.oexe:$(OBJS)
gcc$(OBJS)-oexemain.o:main.cCFLAGS=-g
gcc$(CFLAGS)–cmain.c-omain.oio.o:io.cgcc$(CFLAGS)-cio.c-oio.o使用變量的例子exe:main.oio.oOBJS=14自動推導規(guī)則(隱含規(guī)則)make中,編譯.o文件時,make會認為其源程序就是同文件名的.c源文件,因此依賴列表中可以省略.c文件,這是make的隱含規(guī)則書寫Makefile時,對于一個.c文件如果使用make的隱含規(guī)則,那么它會被自動作為對應.o文件的一個依賴文件(對應是指:文件名除后綴外,其余都相同的兩個文件)。因此可以在規(guī)則中省略目標的倚賴.c文件。自動推導規(guī)則(隱含規(guī)則)make中,編譯.o文件時,make15清洗工作目錄過程文件clean:rmedit$(objects)一般寫為:.PHONY:cleanclean:-rmedit$(objects)兩個實現(xiàn)有兩點不同:
1.通過“.PHONY”特殊目標將“clean”目標聲明為偽目標。防止當磁盤上存在一個名為“clean”文件時,“clean”所在規(guī)則的命令無法執(zhí)行。2.在命令行之前使用“-”,意思是忽略命令“rm”的執(zhí)行錯誤清洗工作目錄過程文件clean:兩個實現(xiàn)有兩點不同:16第7章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第7章Make及makefile文件的編寫 1.17Makefile的內容在一個完整的Makefile中,包含了5個東東:顯式規(guī)則隱含規(guī)則變量的定義指示符注釋它描述了在何種情況下如何更新一個或者多個被稱為目標的文件。在書寫Makefile是需要明確地給出目標文件、目標的依賴文件列表以及更新目標文件所需要的命令。它是make根據(jù)此類目標文件的命名(典型的是文件名的后綴)而自動推導出來的規(guī)則。make根據(jù)目標文件的名字,自動產(chǎn)生目標的依賴文件并使用默認的命令來對目標進行更新。就是使用一個字符串代表一段文本串,當定義了變量以后,Makefile后續(xù)在需要使用此文本串的地方,通過引用這個變量來實現(xiàn)對文本串的使用指明在make程序讀取makefile文件過程中所要執(zhí)行的一個動作。包括:1.讀取給定文件名的文件。2.決定(通常是根據(jù)一個變量的得值)處理或忽略Makefile中的某一特定部分3.定義一個多行變量。Makefile中“#”字符后的內容被作為是注釋內容注釋行的結尾如果存在反斜線(\),那么下一行也被作為注釋行當在Makefile中需要使用字符“#”時,可以使用反斜線加“#”(\#)來實現(xiàn)Makefile的內容在一個完整的Makefile中,包18makefile文件的命名執(zhí)行make命令時,默認的情況下,make會在工作目錄(執(zhí)行make的目錄)下按照文件名順序尋找makefile文件讀取并執(zhí)行,查找的文件名順序為:“GNUmakefile”、“makefile”、“Makefile”。通常應該使用“makefile”或者“Makefile”作為一個makefile的文件名,“GNUmakefile”不推薦使用,因為以此命名的文件只有“GNUmake”才可以識別。當makefile文件的命名不是這三個任何一個時,需要通過make的“-f”或者“--file”選項來指定make讀取的makefile文件。makefile文件的命名執(zhí)行make命令時,默認的情況下,19包含其它的MakefileincludeFILENAMES...make暫停讀取當前的Makefile,轉而去讀取include下的Makefile,結束后,繼續(xù)當前的Makefile書寫在獨立的一行,不可以tab開頭可使用“-include”來代替“include”,忽略由于包含文件不存在或者無法創(chuàng)建時的錯誤提示(“-”的意思是告訴make,忽略此操作的錯誤。make繼續(xù)執(zhí)行)包含其它的MakefileincludeFILENAMES20MAKEFILES變量如果當前環(huán)境定義了一個“MAKEFILES”的環(huán)境變量,make執(zhí)行時首先將此變量的值作為需要讀入的Makefile文件,多個文件之間使用空格分開。類似使用指示符“include”包含其它Makefile文件一樣變量“MAKEFILES”主要用在“make”的遞歸調用過程中的的通信,實際應用中很少設置此變量。MAKEFILES變量如果當前環(huán)境定義了一個“MAKEFIL21MAKEFILE_LIST變量make程序在讀取多個makefile文件時,在對這些文件進行解析執(zhí)行之前,將會被自動的追加到變量“MAKEFILE_LIST”的定義域中。MAKEFILE_LIST變量make程序在讀取多個mak22make如何解析Makefile分為兩個階段第1階段:讀取所有的Makefile文件,內建所有的變量、明確規(guī)則和隱含規(guī)則,并建立所有目標和依賴之間的依賴關系結構鏈表。第2階段:根據(jù)第1階段建立的目標和依賴之間的依賴關系結構鏈表決定哪些目標需要更新,并使用響應的規(guī)則,對該目標進行更新。理解make執(zhí)行過程的兩個階段是很重要的。它能幫助我們更深入的了解執(zhí)行過程中變量以及函數(shù)是如何被展開的。在make的第1階段,變量和函數(shù)被展開的,稱為立即展開,否則為延后展開。make如何解析Makefile分為兩個階段23第7章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第7章Make及makefile文件的編寫 1.24Makefile規(guī)則Makefile中,規(guī)則描述了何種情況下使用什么命令來重建一個特定的文件,此文件被稱為規(guī)則“目標”(通常規(guī)則中的目標只有一個)。規(guī)則所羅列的其他文件稱為“目標”的依賴規(guī)則中的命令是用來更新或者創(chuàng)建此規(guī)則的目標終極目標所在的規(guī)則,應該是Makefile中的第1個規(guī)則,其余規(guī)則不分次序。Makefile規(guī)則Makefile中,規(guī)則描述了何種情況下25終極目標終極目標,就是執(zhí)行make時,沒有指明具體目標時,make默認的那個目標。第1個規(guī)則有多個目標時,第1個目標為終極目標,除非以下兩種情況1.目標名以點號”.”隔開,其后沒有斜線”/”2.作為模式規(guī)則的目標“終極目標“是執(zhí)行make的唯一目的,其所在的規(guī)則作為第一個規(guī)則。終極目標終極目標,就是執(zhí)行make時,沒有指明具體目標時,m26規(guī)則的語法通常規(guī)則的語法格式如下:TARGETS:PREREQUISITESCOMMAND...或者是這樣:TARGETS:PREREQUISITES;COMMANDCOMMAND...規(guī)則的語法通常規(guī)則的語法格式如下:27規(guī)則的核心思想規(guī)則的中心思想就是:目標文件的內容是由依賴文件決定,依賴文件的任何一處改動,將導致目前已經(jīng)存在的目標文件的內容過期。規(guī)則的命令為重建目標提供了方法。這些命令運行在系統(tǒng)shell之上。規(guī)則中的命令被執(zhí)行有兩種情況1.目標文件不存在;2.存在一個依賴的最后修改時間比目標的最后修改時間晚規(guī)則的核心思想規(guī)則的中心思想就是:目標文件的內容是由依賴文件28依賴的類型常規(guī)依賴常規(guī)依賴中的任何一個文件更新,都會導致重建目標。常用的形式order-only依賴在更新目標(目標文件已經(jīng)存在)時,只需要根據(jù)依賴文件中的部分來決定目標是否需要被重建,而不是在依賴文件的任何一個被修改后都重建目標。依賴的改動不會導致目標重建,稱為order-only依賴在書寫規(guī)則時,“order-only”依賴使用管道符號“|”開始,左邊是常規(guī)依賴,管道符右邊的全部是order-only依賴。依賴的類型常規(guī)依賴29舉例LIBS=libtest.afoo:foo.c|$(LIBS)$(CC)$(CFLAGS)$<-o$@$(LIBS)執(zhí)行make時,如果foo.c修改了,目標foo會重建,libtest.a修改了,foo不會重建libtest.a只有在foo不存在的情況下,才會參與規(guī)則的執(zhí)行。舉例LIBS=libtest.a30文件名使用通配符可使用的通配符有:“*”、“?”Makefile中統(tǒng)配符可以出現(xiàn)在以下兩種場合:1.可以用在規(guī)則的目標、依賴中,此時make會自動將其展開;2.可出現(xiàn)在規(guī)則的命令中,其展開是在shell在執(zhí)行此命令時完成。變量定義中使用的通配符不會被展開。變量objects=*.o”。那么變量“objects”的值就是“*.o”。需要變量“objects”代表所有的.o文件,使用函數(shù)“wildcard”來實現(xiàn)(objects=$(wildcard*.o))。文件名使用通配符可使用的通配符有:“*”、“?”31函數(shù)wildcard在規(guī)則中,通配符會被自動展開。在變量的定義和使用函數(shù)時,通配符不會被自動展開。這種情況下需要通配符有效,要用到函數(shù)“wildcard”語法格式:$(wildcardPATTERN...)函數(shù)wildcard在規(guī)則中,通配符會被自動展開。32目錄搜索在一個較大的工程中,一般會把源碼文件和2進制文件(.o文件和可執(zhí)行文件)安排在不同的目錄來進行區(qū)分管理。需要使用make提供的目錄自動搜索依賴文件功能目錄搜索在一個較大的工程中,一般會把源碼文件和2進制文件(33VPATH變量通過變量“VPATH”可以指定依賴文件的搜索路徑。在規(guī)則的依賴文件在當前目錄不存在時,make會在此變量所指定的目錄下去尋找這些依賴文件變量“VPATH”的定義中,使用空格或者冒號(:)將多個目錄分開。make搜索的目錄順序按照變量“VPATH”定義中順序進行(當前目錄永遠是第一搜索目錄)。舉例:VPATH=src:../headers,指定兩個搜索目錄,分別是src和../headersVPATH變量通過變量“VPATH”可以指定依賴文件的搜索路34Makefile的偽目標偽目標:它不代表一個真正的文件名,在執(zhí)行make時可以指定這個目標來執(zhí)行其所在規(guī)則定義的命令有時我們也可以將一個偽目標稱為標簽使用偽目標的原因1.避免在Makefile中定義的只執(zhí)行命令的的目標(此目標的目的為了執(zhí)行執(zhí)行一些列命令,而不需要創(chuàng)建這個目標)和工作目錄下的實際文件出現(xiàn)名字沖突。2.提高執(zhí)行make時的效率。Makefile的偽目標偽目標:35避免和實際文件名沖突clean:rm*.otemp執(zhí)行makeclean,如果目錄下沒有clean文件,執(zhí)行結果與要求一致,刪除所有.o文件和temp目錄如果目錄下有clean文件,會怎么樣?規(guī)則沒有依賴文件,目標會被認為是最新的,而不去執(zhí)行規(guī)則的命令。這不是我們的初衷。把clean明確聲明為偽目標。將一個目標聲明為偽目標需要將它作為特殊目標“.PHONY”的依賴.PHONY:clean避免和實際文件名沖突clean:36偽目標規(guī)則的書寫首先需要聲明目標是一個偽目標然后是偽目標的規(guī)則定義。舉例:.PHONY:cleanclean:rm*.otemp這里clean是人為定義的偽目標,可以是任何一個合法的名字。偽目標規(guī)則的書寫首先需要聲明目標是一個偽目標37偽目標的依賴應用場合1.創(chuàng)建當前目錄下的多個應用程序2.分類執(zhí)行不同的動作偽目標的依賴應用場合38創(chuàng)建當前目錄下的多個應用程序約定的做法是使用一個稱為“all”的偽目標來作為終極目標all:prog1prog2prog3.PHONY:allprog1:prog1.outils.occ-oprog1prog1.outils.oprog2:prog2.occ-oprog2prog2.oprog3:prog3.osort.outils.occ-oprog3prog3.osort.outils.omake,更新全部makeprog1,只更新prog1創(chuàng)建當前目錄下的多個應用程序約定的做法是使用一個稱為“all39分類執(zhí)行不同的動作把一個偽目標作為另外一個偽目標的依賴,make將其作為另外一個偽目標的子例程來處理,類似函數(shù)調用。.PHONY:cleanallcleanobjcleandiffcleanall:cleanobjcleandiffrmprogramcleanobj:rm*.ocleandiff:rm*.diff執(zhí)行makecleanall時,會調用執(zhí)行makecleanobj和makecleandiff。也可單獨執(zhí)行makecleanobj,刪除所有的obj文件。分類執(zhí)行不同的動作把一個偽目標作為另外一個偽目標的依賴,ma40多目標一個規(guī)則中可以有多個目標,規(guī)則所定義的命令對所有的目標有效。一個具有多目標的規(guī)則相當于多個規(guī)則。多目標通常用在以下兩種情況:1.僅需要一個描述依賴關系的規(guī)則,而不需要在規(guī)則中定義命令kbd.ocommand.ofiles.o:command.h2.對于多個具有類似重建命令的目bigoutputlittleoutput:text.ggeneratetext.g-$(substoutput,,$@)>$@等價于bigoutput:text.ggeneratetext.g-big>bigoutputlittleoutput:text.ggeneratetext.g-little>littleoutput多目標一個規(guī)則中可以有多個目標,規(guī)則所定義的命令對所有的目標41多規(guī)則目標Makefile中,一個文件作為多個規(guī)則的目標出現(xiàn)。此目標文件的所有依賴文件將會被合并成此目標一個依賴文件列表,其中任何一個依賴文件比目標更新(比較目標文件和依賴文件的時間戳)時,make將會執(zhí)行特定的命令來重建這個目標。重建此目標的命令只能出現(xiàn)在一個規(guī)則中。如果多個規(guī)則同時給出重建此目標的命令,make將使用最后一個規(guī)則所用的命令,同時提示錯誤信息如果目標的任何一個規(guī)則沒有定義重建此目標的命令,make將會尋找一個合適的隱含規(guī)則來重建此目標。多規(guī)則目標Makefile中,一個文件作為多個規(guī)則的目標出現(xiàn)42多規(guī)則目標舉例objects=foo.obar.ofoo.o:defs.hbar.o:defs.htest.h$(objects):config.h這是一個描述規(guī)則,僅僅用來描述依賴關系foo.o和bar.o都是多規(guī)則的目標,如果config.h文件發(fā)生變化,則foo.o和bar.o都會自動重建。多規(guī)則目標舉例objects=foo.obar.o43靜態(tài)模式規(guī)則靜態(tài)模式規(guī)則是這樣一個規(guī)則:規(guī)則存在多個目標,并且不同的目標可以根據(jù)目標文件的名字來自動構造出依賴文件?;菊Z法TARGETS...:TARGET-PATTERN:PREREQ-PATTERNSCOMMANDS...--“TAGETS”列出了此規(guī)則的一系列目標文件--可以使用通配符--目標模式(TAGET-PATTERN)--依賴模式(PREREQ-PATTERNS)--說明了如何為目標文件生成依賴文件--生成方法:從目標模式的目標文件中抽取一部分字符(稱為莖)來代替依賴模式中的相應部分。靜態(tài)模式規(guī)則靜態(tài)模式規(guī)則是這樣一個規(guī)則:規(guī)則存在多個目標,并44自動生成依賴文件的過程在目標模式和依賴模式中,一般需要包含模式字符%”。在目標模式(TAGET-PATTERN)中“%”可以匹配目標文件的任何部分,模式字符“%”匹配的部分就是“莖”。比如目標“foo.o”符合模式“%.o”,其“莖”為“foo”。而目標“foo.c”和“foo.out”就不符合此目標模式。每一個目標的依賴文件是使用此目標的“莖”代替依賴模式PREREQ-PATTERNS)中的模式字符“%”而得到。如果依賴模式(PREREQ-PATTERNS)為“%.c”,那么使用“foo”替代依賴模式中的“%”得到的依賴文件就是“foo.c”。自動生成依賴文件的過程在目標模式和依賴模式中,一般需要包含模45靜態(tài)模式舉例objects=foo.obar.oall:$(objects)$(objects):%.o:%.c$(CC)-c$(CFLAGS)$<-o$@對目標foo.o,根據(jù)目標模式”%.o”,所以其莖應為foo,使用該莖,替代依賴模式”%.c”中的模式字符“%”,因此foo.o的依賴文件就是foo.c命令行中“$<”和“$@”是自動化變量,“$<”表示規(guī)則中的第一個依賴文件。$@表示規(guī)則中的目標文件foo.o:foo.c
$(CC)-c$(CFLAGS)foo.c-ofoo.obar.o:bar.c$(CC)-c$(CFLAGS)bar.c-obar.o靜態(tài)模式舉例objects=foo.obar.ofo46雙冒號規(guī)則雙冒號規(guī)則就是使用“::”代替普通規(guī)則的“:”得到的規(guī)則雙冒號規(guī)則允許在多個規(guī)則中為同一個目標指定不同的重建目標的命令注意:Makefile中,一個目標可以出現(xiàn)在多個規(guī)則中。但是這些規(guī)則必須是同一種規(guī)則,要么都是普通規(guī)則,要么都是雙冒號規(guī)則。而不允許一個目標同時出現(xiàn)在兩種不同的規(guī)則中雙冒號規(guī)則雙冒號規(guī)則就是使用“::”代替普通規(guī)則的“:”得到47雙冒號規(guī)則和普通規(guī)則的區(qū)別對于一個沒有依賴而只有命令行的雙冒號規(guī)則,當引用此目標時,規(guī)則的命令將會被無條件執(zhí)行。普通規(guī)則呢?當同一個文件作為多個雙冒號規(guī)則的目標時。這些不同的規(guī)則會被獨立的處理。就是說多個雙冒號規(guī)則中的每一個的依賴文件被改變之后,make只執(zhí)行此規(guī)則定義的命令,而其它的以這個文件作為目標的雙冒號規(guī)則將不會被執(zhí)行普通規(guī)則呢?雙冒號規(guī)則和普通規(guī)則的區(qū)別對于一個沒有依賴而只有命令行的雙冒48雙冒號規(guī)則舉例Newprog::foo.c$(CC)$(CFLAGS)$<-o$@Newprog::bar.c$(CC)$(CFLAGS)$<-o$@如果foo.c更改,執(zhí)行make,根據(jù)foo.c文件重建目標newprog如果bar.c更改,執(zhí)行make,根據(jù)bar.c文件重建目標newprog如果是普通規(guī)則,執(zhí)行make時會怎樣?執(zhí)行make時出錯,并提示錯誤信息雙冒號規(guī)則舉例Newprog::foo.c49自動生成依賴描述.o文件和頭文件的依賴關系。比如main.c中#include“def.h”,因此在Makefile的依賴關系中需要如下描述mai.o:main.cdef.h。有什么缺點:1.如果很多源程序文件中用到了頭文件,就需要做很多這樣的依賴關系描述2.如果修改了源文件中使用的頭文件,那么這么依賴關系描述也需要修改。自動產(chǎn)生依賴,使用GCC的-M選項,GCC將自動找尋源文件中包含的頭文件,并生成一個依賴關系gcc-Mmain.c,輸出main.o:main.cdef.h自動生成依賴描述.o文件和頭文件的依賴關系。比如main.c50第7章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第7章Make及makefile文件的編寫 1.51規(guī)則中書寫命令規(guī)則的命令由一些shell命令行組成每一行命令行必需一[Tab]字符開始對所有規(guī)則中命令行的解析默認使用“/bin/sh”來完成規(guī)則中書寫命令規(guī)則的命令由一些shell命令行組成52命令的回顯make在執(zhí)行命令行之前會,把要執(zhí)行的命令行進行輸出。稱之為“回顯”如果要執(zhí)行的命令行以字符“@”開始,則make在執(zhí)行時這個命令就不會被回顯@echo開始編譯XXX模塊......echo開始編譯XXX模塊......使用make的命令行參數(shù)“-n”或“--just-print”,make執(zhí)行時只顯示所要執(zhí)行的命令,但不會真正的去執(zhí)行這些命令make參數(shù)“-s”或“--slient”,禁止所有執(zhí)行命令的顯示命令的回顯make在執(zhí)行命令行之前會,把要執(zhí)行的命令行進行53命令行的執(zhí)行書寫在同一行中的多個命令(各命令用分號分隔)屬于一個完整的shell命令行寫在獨立行的一條命令是一個獨立的shell命令行多行命令之間的執(zhí)行是相互獨立的,相互之間不存在依賴。比如,前行的cd命令,并不會影響到下一行。為了實現(xiàn)這個目的,應該在一行上書寫,用分號分隔foo:bar/losecdbar;gobblelose>../foofoo:bar/losecdbar;\gobblelose>../foo或命令行的執(zhí)行書寫在同一行中的多個命令(各命令用分號分隔)屬于54命令執(zhí)行的錯誤規(guī)則中的命令在運行結束后,make會檢測命令執(zhí)行的返回狀態(tài)返回成功,就執(zhí)行下一條命令出錯(返回狀態(tài)非0),make就會放棄對當前規(guī)則的執(zhí)行,也有可能會終止所有規(guī)則的執(zhí)行。在命令之前加一個減號“-”(在[Tab]字符之后),make忽略此命令的執(zhí)行失敗。clean:-rm*.o即使刪除.o文件失敗,make也繼續(xù)執(zhí)行命令執(zhí)行的錯誤規(guī)則中的命令在運行結束后,make會檢測命令執(zhí)55命令執(zhí)行的錯誤在執(zhí)行make時,如果使用命令行選項“-i”或者“—ignore-errors”,make會忽略所有規(guī)則中命令執(zhí)行的錯誤。但會提示有錯誤出現(xiàn),并提示該錯誤被忽略。后續(xù)命令可能不能繼續(xù)執(zhí)行,退出make。使用make的命令行選項“-k”或者“--keep-going”,當出現(xiàn)錯誤時不立即退出,而是繼續(xù)后續(xù)命令的執(zhí)行。直到無法繼續(xù)執(zhí)行命令時才異常退出。在make執(zhí)行失敗時,修改錯誤之后再次執(zhí)行make之前,使用“makeclean”明確的刪除第一次錯誤重建的所有目標。為什么?命令執(zhí)行的錯誤在執(zhí)行make時,如果使用命令行選項“-i56中斷make的執(zhí)行CTRL+C再次執(zhí)行make之前,請先使用makeclean來清除中斷make時產(chǎn)生的目標文件。中斷make的執(zhí)行CTRL+C57make的遞歸執(zhí)行在Makefile中使用“make”作為一個命令來執(zhí)行本身或者其它makefile文件。一般用在一個存在有多級子目錄的項目中。舉例:當前目錄下,包含一個子目錄subdir,子目錄中也有一個Makefile,當前目錄下make時,完成包括子目錄的所有編譯,在當前目錄下的Makefile中,就可以使用make的遞歸subsystem:cdsubdir&&$(MAKE)subsystem:$(MAKE)-Csubdir或make的遞歸執(zhí)行在Makefile中使用“make”作58變量MAKE在使用make的遞歸調用時,在Makefile中規(guī)則的命令行中應該使用變量“MAKE”來代替直接使用“make”使用MAKE變量的目的保證最上層使用的make程序和其子目錄下執(zhí)行的make保持一致對某些make的選項不起作用subsystem:cdsubdir&&$(MAKE)make–t時,直接使用make,和使用MAKE變量,會有很大的區(qū)別。變量MAKE在使用make的遞歸調用時,在Makefi59變量和遞歸上層Makefile中,使用“export變量名”聲明的變量,會傳遞給子make過程中。變量“SHELL”和“MAKEFLAGS”除非使用指示符“unexport”對它們進行聲明,否則在整個make的執(zhí)行過程中它們會始終被自動的傳遞給子make指示符“export”或者“unexport”的參數(shù)(變量部分),如果它是對一個變量或者函數(shù)的引用,這些變量或者函數(shù)將會被立即展開。并賦值給export或者unexport的變量變量和遞歸上層Makefile中,使用“export變量名60export的用法定義變量時,同時進行聲明。例如1.exportVARIABLE=value等效于:VARIABLE=valueexportVARIABLE2.exportVARIABLE:=value等效于:VARIABLE:=valueexportVARIABLE不帶任何參數(shù)的指示符“export”,表示將此Makefile中定義的所有變量傳遞給子make過程export的用法定義變量時,同時進行聲明。例如61變量MAKELEVEL在多級遞歸調用的make執(zhí)行過程中。變量“MAKELEVEL”代表了調用的深度。最上一級時“MAKELEVEL”的值為“0”、下一級時為“1”、再下一級為“2”:變量MAKELEVEL在多級遞歸調用的make執(zhí)行過程中62命令行選項和遞歸在make的遞歸執(zhí)行過程中。最上層(可以稱之為主控)make的命令行選項“-k”、“-s”等被自動的通過環(huán)境變量“MAKEFLAGS”傳遞給子make進程。在主控執(zhí)行make時使用“-k”和“-s”選項,那么“MAKEFLAGS”的值就為“ks”“-C”、“-f”、“-o”和“-W,這些命令行選項不會被賦值給變量“MAKEFLAGS”命令行選項和遞歸在make的遞歸執(zhí)行過程中。最上層(可以稱63定義命令包什么是命令包?類似C語言中的自定義函數(shù)語法格式:define名稱命令塊endef命令包的使用和對變量的使用一樣foo.c:foo.y$(run-yacc)definerun-yaccyacc$(firstword$^)mvy.tab.c$@endef自動化變量定義命令包什么是命令包?definerun-yacc自動64空命令規(guī)則中,只有目標文件(可以有依賴文件,但一般不用),但沒有命令行。這就是空命令規(guī)則。格式:target:;使用空命令行可以防止make在執(zhí)行時圖重建這個目標而查找隱含命令空命令規(guī)則中,只有目標文件(可以有依賴文件,但一般不用),但65第7章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第7章Make及makefile文件的編寫 1.66使用變量/宏Makefile中的變量有如下特征1.Makefile中變量和函數(shù)的展開(除規(guī)則的命令行以外),是在make讀取makefile文件時進行的2.變量名是不包括“:”、“#”、“=”、前置空白和尾空白的任何字符串,但建議只使用字母、數(shù)字、下劃線3.變量名是大小寫敏感的4.自動化變量。使用變量/宏Makefile中的變量有如下特征67變量的引用“$(VARIABLE_NAME)”或者“${VARIABLE_NAME}”來引用一個變量,變量的引用展開過程完全和c語言中的宏展開的過程一樣,是一個嚴格的文本替換過程。objects=program.ofoo.outils.oprogram:$(objects)cc-oprogram$(objects)$(objects):defs.hprogram:program.ofoo.outils.occ-oprogramprogram.ofoo.outils.oprogram.ofoo.outils.o:defs.h展開后變量的引用“$(VARIABLE_NAME)”或者“${V68兩種變量定義一個變量的定義有兩種方式(或者稱為風格)遞歸展開式變量直接展開式變量變量的這兩種不同的風格的區(qū)別在于:1.定義方式;2.展開時機。兩種變量定義一個變量的定義有兩種方式(或者稱為風格)69遞歸展開式變量變量的定義使用“=”或者“define”指示符來定義在引用的地方是嚴格的文本替換過程如果此變量定義中存在對其他變量的引用,這些被引用的變量會在它被展開的同時被展開foo=$(bar)bar=$(ugh)ugh=Huh?all:;echo$(foo)執(zhí)行make時,顯示“Huh?”替換過程為:首先“$(foo)”被替換“$(bar)”,接下來“$(bar)”被替換為“$(ugh)”,最后“$(ugh)”被替換為“Hug?”。整個替換的過程是在執(zhí)行“echo$(foo)”時進行的。遞歸展開式變量變量的定義使用“=”或者“define”指示符70優(yōu)缺點優(yōu)點:可以引用其它的之前沒有定義的變量,可能在后續(xù)部分定義,或者是通過make的命令行選項傳遞的變量缺點:1.可能會由于出現(xiàn)變量的遞歸定義而導致make陷入到無限的變量展開過程中,最終使make執(zhí)行失敗。例如x=$(y)y=$(x)$(z)2.如果引用了函數(shù),那么函數(shù)總會在其被引用的地方被執(zhí)行。優(yōu)缺點優(yōu)點:可以引用其它的之前沒有定義的變量,可能在后續(xù)部分71直接展開式變量使用“:=”來定義的變量該類型變量值中對另外變量的引用或者函數(shù)的引用在定義時被展開不能實現(xiàn)對其后定義變量的引用推薦使用這種方式定義變量x:=fooy:=$(x)barx:=latery:=foobarx:=later直接展開式變量使用“:=”來定義的變量x:=fooy72“?=”操作符只有此變量在之前沒有賦值的情況下才會對這個變量進行賦值FOO?=bar如果變量“FOO”沒有定義過,就給它賦值“bar”。否則不改變它的值“?=”操作符只有此變量在之前沒有賦值的情況下才會對這個變量73追加變量的值在便令定義時,賦給一個基本的值,后續(xù)根據(jù)需要,給它增加一些必要的值使用“+=”操作符objects=main.ofoo.obar.outils.oobjects+=another.o會把another.o追加到objects的末尾,并以空格分隔追加變量的值在便令定義時,賦給一個基本的值,后續(xù)根據(jù)需要,給74目標指定變量在Makefile中定義一個變量,這個變量對此Makefile的所有規(guī)則都是有效的。是一個“全局的”變量。另一種變量是目標指定變量“Target-specificVariable)”。允許對于相同變量根據(jù)目標指定不同的值,目標指定的變量值只在指定它的目標的上下文中有效。此種變量是“局部的”。.設置一個目標指定變量的語法為:TARGET...:VARIABLE-ASSIGNMENT或者:TARGET...:overrideVARIABLE-ASSIGNMENT目標指定變量在Makefile中定義一個變量,這個變量對此M75目標指定變量說明“VARIABLE-ASSIGNMENT”可以使用任何一個有效的賦值方式,“=”(遞歸)、“:=”(靜態(tài))、“+=”(追加)或者“?=”(條件)。使用目標指定變量值時,目標指定的變量值不會影響同名的那個全局變量的值。只對指定的這些目標有效目標指定的變量變量會作用到由這個目標所引發(fā)的所有的規(guī)則中去。prog:CFLAGS=-gprog:prog.ofoo.obar.o對于目標“prog”以及其所引發(fā)的所有(包含目標為“prog.o”、“foo.o”和“bar.o”的所有規(guī)則)規(guī)則,變量“CFLAGS”值都是“-g”。目標指定變量說明“VARIABLE-ASSIGNMENT”可76目標指定變量舉例#sampleMakefileCUR_DIR=$(shellpwd)INCS:=$(CUR_DIR)/includeCFLAGS:=-Wall–I$(INCS)
EXEF:=foobar.PHONY:allcleanall:$(EXEF)foo:foo.cfoo:CFLAGS+=-O2bar:bar.cbar:CFLAGS+=-g………..………..$(EXEF):debug.h$(CC)$(CFLAGS)$(addsuffix.c,$@)–o$@clean:$(RM)*.o*.d$(EXES)使用目標指定變量可以在Makefile實現(xiàn),對于不同的目標文件使用不同的編譯參數(shù)目標指定變量舉例#sampleMakefile使用目77第7章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第7章Make及makefile文件的編寫 1.78執(zhí)行make的一般方法在shell提示符下,執(zhí)行make命令,會自動讀取該目錄下的Makefile文件,從而執(zhí)行相應的規(guī)則。執(zhí)行make的其它用途:1.使用make更新一部分過時文件而不是全部2.需要使用另外的編譯器或者重新定義編譯選項3.只需要察看哪些文件被修改,而不需要重新編譯為了達到這些目的,就需要使用make的命令行參數(shù)執(zhí)行make的一般方法在shell提示符下,執(zhí)行make命令79Make退出的狀態(tài)0:狀態(tài)為0時,表示執(zhí)行成功。2:執(zhí)行過程出現(xiàn)錯誤,同時會提示錯誤信息。1:在執(zhí)行make時使用了“-q”參數(shù),而且當前存在過時的目標文件Make退出的狀態(tài)0:狀態(tài)為0時,表示執(zhí)行成功。80指定Makefile文件當需要將一個普通命名的文件作為makefile文件時,需要使用make的“-f”、“--file”或者“--makefile”選項默認情況,在沒有使用“-f”(“--file”或者“--makefile”)指定文件時。make會在工作目錄(當前目錄)依次搜索命名為“GNUmakefile”、“makefile”和“Makefile”的文件,最終解析執(zhí)行的是這三個文件中首先搜索到的那一個。指定Makefile文件當需要將一個普通命名的文件作為mak81指定終極目標默認情況下,終極目標就是出現(xiàn)在Makefile中,除以點號“.”開始的第1個規(guī)則中的目標。點號開始的是什么目標?(.PHONY)如果第1個規(guī)則中有多個目標,那么第1個目標就是終極目標??梢灾付ù舜蝝ake過程的終極目標,方法為:make目標名,例如:makeclean。變量“MAKECMDGOALS”記錄了命令行參數(shù)指定的終極目標列表。指定終極目標默認情況下,終極目標就是出現(xiàn)在Makefile中82防止特定文件重建當修改了工程中的某一個文件后,并不希望重建那些依賴于這個文件的目標。例如頭文件修改后,并不對于依賴該頭文件的目標造成任何影響。方法:1.執(zhí)行編譯,使用“make–oHEADERFILE”,“HEADERFILE”為需要忽略更改的頭文件,防止那些依賴于這個頭文件的目標被重建。-o”參數(shù)的這種使用方式僅限于頭文件(.h文件)2.執(zhí)行make-t防止特定文件重建當修改了工程中的某一個文件后,并不希望重建那83常用的make命令行選項-n:指定make執(zhí)行空操作(不執(zhí)行規(guī)則的命令),只打印出需要重建目標使用的命令(只打印過期的目標的重建命令),而不對目標進行重建。-t:新所有目標文件的時間戳(對于過時的目標文件不進行內容更新,只更新時間戳)。-q:不執(zhí)行任何命令并且不打印任何輸出信息,只檢查所指定的目標是否已經(jīng)是最新更。如果是則返回0,否則返回1常用的make命令行選項-n:指定make執(zhí)行空操作(不84自動化變量$@----代表規(guī)則中的目標文件名$<----規(guī)則的第一個依賴文件名$^----規(guī)則的所有依賴文件列表,使用空格分隔$%----規(guī)則的目標文件是一個靜態(tài)庫文件時,代表靜態(tài)庫的一個成員名。例如,規(guī)則的目標是“foo.a(bar.o)”,那么,“$%”的值就為“bar.o”,“$@”的值為“foo.a”。如果目標不是函數(shù)庫文件,其值為空自動化變量$@----代表規(guī)則中的目標文件名85謝謝謝謝86第5章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第5章Make及makefile文件的編寫 1.87Linux系統(tǒng)下的文件編譯程序的編譯和鏈接源程序(.c)編譯(compile)鏈接(linker)形成目標文件形成可執(zhí)行程序(1)預編譯(2)匯編階段Linux系統(tǒng)下的文件編譯程序的編譯和鏈接源程序(.c)編譯88什么是make?Make是大型程序維護工具Make工作時,需要名字為“makefile”的makefile文件。根據(jù)依賴關系自動決定項目的那些部分需要重新編譯?;驹恚喝绻硞€源程序文件被修改,那么依賴這個源程序文件的所有目標文件,都需要重新編譯。什么是make?Make是大型程序維護工具89MakefileRuleRule的格式為:target…:prerequisites… command … …Target依賴prerequisites的目標Prerequisites被依賴的源程序,例如c文件或h文件Command需要執(zhí)行的命令當prerequisites任何一個文件的時戳新于target的時戳時,就執(zhí)行command。MakefileRuleRule的格式為:90makefile規(guī)則介紹一個簡單的Makefile描述規(guī)則組成:TARGET...:PREREQUISITES... <tab>COMMAND ...--target:規(guī)則的目標。--通常是程序中間文件(.o)或者最后可執(zhí)行文件名--目標也可以是一個make執(zhí)行的動作的名稱,如目標“clean”,這樣的目標是“偽目標--prerequisites:規(guī)則的依賴。--生成規(guī)則目標所需要的文件名列表。通常一個目標依賴于一個或者多個文件。--command:規(guī)則的命令行--是make程序所有執(zhí)行的動作(任意的shell命令或者可在shell下執(zhí)行的程序)--一個規(guī)則可以有多個命令行,每一條命令占一行。注意:每一個命令行必須以[Tab]字符開始makefile規(guī)則介紹一個簡單的Makefile描述規(guī)則組91makefile文件在makefile(Makefile)文件中,采用自頂向下到的方法來說明依賴關系network:network.osubrs.o(1)gccnetwork.osubrs.o–onetwork(2)network.o:etdefs.h(3)gcc–cnetwork.c-onetwork.o(4)subrs.o:etdefs.h(5)gcc–csubrs.c.PHONYcleanclean:rm-r*.o(6)makefile文件在makefile(Makefile)文92執(zhí)行make在makefile(Makefile)文件所在的目錄中,執(zhí)行make命令語法:make[選項][宏定義][目標文件]執(zhí)行make在makefile(Makefile)文件所在的93Make的工作過程1.make在當前目錄下找名字叫“Makefile”或“makefile”的文件2.如果找到,它會找文件中的第一個目標文件(target),比如找到“network”這個文件,并把這個文件作為最終的目標文件。3.如果network文件不存在,或是network所依賴的后面的.o文件的文件修改時間要比network這個文件新,那么,他就會執(zhí)行后面所定義的命令來生成network這個文件。4.如果network所依賴的.o文件也存在,那么make會在當前文件中找目標為.o文件的依賴性,如果找到則再根據(jù)那一個規(guī)則生成.o文件(使用源文件和.h文件)。(這有點像一個堆棧的過程)Make的工作過程1.make在當前目錄下找名字叫“Make94make時,哪些文件被重新編譯1.所有的源文件沒有被編譯過,則對各個C源文件進行編譯并進行鏈接,生成最后的可執(zhí)行程序;2.每一個在上次執(zhí)行make之后修改過的C源代碼文件在本make時將會被重新編譯;3.頭文件在上一次執(zhí)行make之后被修改。則所有包含此頭文件的C源文件在本次執(zhí)行make時將會被重新編譯。make時,哪些文件被重新編譯1.所有的源文件沒有被編譯95關于Makefile文件名默認的情況下,make命令會在當前目錄下按順序找尋文件名為“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解釋這個文件。也可以使用別的文件名來書寫Makefile,這是執(zhí)行Make命令時,需使用“-f”和“--file”參數(shù)。如:make-fMake.Linux或make--fileMake.AIX關于Makefile文件名默認的情況下,make命令會在當前96對“規(guī)則”的再認識在Makefile中“規(guī)則”就是描述在什么情況下、如何重建規(guī)則的目標文件,通常規(guī)則中包括了目標的依賴關系(目標的依賴文件)和重建目標的命令。make執(zhí)行重建目標的命令,來創(chuàng)建或者重建規(guī)則的目標(此目標文件也可以是觸發(fā)這個規(guī)則的上一個規(guī)則中的依賴文件)。規(guī)則包含了目標和依賴的關系以及更新目標所要求的命令。對“規(guī)則”的再認識在Makefile中“規(guī)則”就是描述在97一個簡單的例子1.注釋以#開頭2.一個較長行可以使用反斜線(\)分解為多行,\后不能有空格3.目標“clean”不是一個文件,它僅僅代表了執(zhí)行一個動作的標識。Makefile中把那些沒有任何依賴只有執(zhí)行動作的目標稱為“偽目標”在執(zhí)行make時,它所指定的動作不會被執(zhí)行。除非執(zhí)行make時明確地指定它作為重建目標。而且目標“clean”沒有任何依賴文件,它只有一個目的,就是通過這個目標名來執(zhí)行它所定義的命令。Makefile中把執(zhí)行“clean”目標所定義的命令,可在shell下輸入:makeclean。
一個簡單的例子1.注釋以#開頭98使用變量在上例的Makefile中可是添加這樣一行:objects=main.okbd.ocommand.odisplay.oinsert.o\search.ofiles.outils.o“objects”作為一個變量,它代表所有的.o文件的列表,在需要使用這些.o文件列表的地方使用“$(objects)”來表示它objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.oedit:$(objects)gcc$(objects)-oedit…….…….clean:rmedit$(objects)使用變量在上例的Makefile中可是添加這樣一行:99使用變量的例子exe:main.oio.ogccmain.oio.o-oexemain.o:main.c
gcc-g-cmain.c–omain.oio.o:io.c
gcc-g-cio.c-oio.oOBJS=main.oio.oexe:$(OBJS)
gcc$(OBJS)-oexemain.o:main.cCFLAGS=-g
gcc$(CFLAGS)–cmain.c-omain.oio.o:io.cgcc$(CFLAGS)-cio.c-oio.o使用變量的例子exe:main.oio.oOBJS=100自動推導規(guī)則(隱含規(guī)則)make中,編譯.o文件時,make會認為其源程序就是同文件名的.c源文件,因此依賴列表中可以省略.c文件,這是make的隱含規(guī)則書寫Makefile時,對于一個.c文件如果使用make的隱含規(guī)則,那么它會被自動作為對應.o文件的一個依賴文件(對應是指:文件名除后綴外,其余都相同的兩個文件)。因此可以在規(guī)則中省略目標的倚賴.c文件。自動推導規(guī)則(隱含規(guī)則)make中,編譯.o文件時,make101清洗工作目錄過程文件clean:rmedit$(objects)一般寫為:.PHONY:cleanclean:-rmedit$(objects)兩個實現(xiàn)有兩點不同:
1.通過“.PHONY”特殊目標將“clean”目標聲明為偽目標。防止當磁盤上存在一個名為“clean”文件時,“clean”所在規(guī)則的命令無法執(zhí)行。2.在命令行之前使用“-”,意思是忽略命令“rm”的執(zhí)行錯誤清洗工作目錄過程文件clean:兩個實現(xiàn)有兩點不同:102第7章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第7章Make及makefile文件的編寫 1.103Makefile的內容在一個完整的Makefile中,包含了5個東東:顯式規(guī)則隱含規(guī)則變量的定義指示符注釋它描述了在何種情況下如何更新一個或者多個被稱為目標的文件。在書寫Makefile是需要明確地給出目標文件、目標的依賴文件列表以及更新目標文件所需要的命令。它是make根據(jù)此類目標文件的命名(典型的是文件名的后綴)而自動推導出來的規(guī)則。make根據(jù)目標文件的名字,自動產(chǎn)生目標的依賴文件并使用默認的命令來對目標進行更新。就是使用一個字符串代表一段文本串,當定義了變量以后,Makefile后續(xù)在需要使用此文本串的地方,通過引用這個變量來實現(xiàn)對文本串的使用指明在make程序讀取makefile文件過程中所要執(zhí)行的一個動作。包括:1.讀取給定文件名的文件。2.決定(通常是根據(jù)一個變量的得值)處理或忽略Makefile中的某一特定部分3.定義一個多行變量。Makefile中“#”字符后的內容被作為是注釋內容注釋行的結尾如果存在反斜線(\),那么下一行也被作為注釋行當在Makefile中需要使用字符“#”時,可以使用反斜線加“#”(\#)來實現(xiàn)Makefile的內容在一個完整的Makefile中,包104makefile文件的命名執(zhí)行make命令時,默認的情況下,make會在工作目錄(執(zhí)行make的目錄)下按照文件名順序尋找makefile文件讀取并執(zhí)行,查找的文件名順序為:“GNUmakefile”、“makefile”、“Makefile”。通常應該使用“makefile”或者“Makefile”作為一個makefile的文件名,“GNUmakefile”不推薦使用,因為以此命名的文件只有“GNUmake”才可以識別。當makefile文件的命名不是這三個任何一個時,需要通過make的“-f”或者“--file”選項來指定make讀取的makefile文件。makefile文件的命名執(zhí)行make命令時,默認的情況下,105包含其它的MakefileincludeFILENAMES...make暫停讀取當前的Makefile,轉而去讀取include下的Makefile,結束后,繼續(xù)當前的Makefile書寫在獨立的一行,不可以tab開頭可使用“-include”來代替“include”,忽略由于包含文件不存在或者無法創(chuàng)建時的錯誤提示(“-”的意思是告訴make,忽略此操作的錯誤。make繼續(xù)執(zhí)行)包含其它的MakefileincludeFILENAMES106MAKEFILES變量如果當前環(huán)境定義了一個“MAKEFILES”的環(huán)境變量,make執(zhí)行時首先將此變量的值作為需要讀入的Makefile文件,多個文件之間使用空格分開。類似使用指示符“include”包含其它Makefile文件一樣變量“MAKEFILES”主要用在“make”的遞歸調用過程中的的通信,實際應用中很少設置此變量。MAKEFILES變量如果當前環(huán)境定義了一個“MAKEFIL107MAKEFILE_LIST變量make程序在讀取多個makefile文件時,在對這些文件進行解析執(zhí)行之前,將會被自動的追加到變量“MAKEFILE_LIST”的定義域中。MAKEFILE_LIST變量make程序在讀取多個mak108make如何解析Makefile分為兩個階段第1階段:讀取所有的Makefile文件,內建所有的變量、明確規(guī)則和隱含規(guī)則,并建立所有目標和依賴之間的依賴關系結構鏈表。第2階段:根據(jù)第1階段建立的目標和依賴之間的依賴關系結構鏈表決定哪些目標需要更新,并使用響應的規(guī)則,對該目標進行更新。理解make執(zhí)行過程的兩個階段是很重要的。它能幫助我們更深入的了解執(zhí)行過程中變量以及函數(shù)是如何被展開的。在make的第1階段,變量和函數(shù)被展開的,稱為立即展開,否則為延后展開。make如何解析Makefile分為兩個階段109第7章Make及makefile文件的編寫
1.概述2.Makefile3.Makefile的規(guī)則4.規(guī)則的命令5.Makefile中的變量6.執(zhí)行make第7章Make及makefile文件的編寫 1.110Makefile規(guī)則Makefile中,規(guī)則描述了何種情況下使用什么命令來重建一個特定的文件,此文件被稱為規(guī)則“目標”(通常規(guī)則中的目標只有一個)。規(guī)則所羅列的其他文件稱為“目標”的依賴規(guī)則中的命令是用來更新或者創(chuàng)建此規(guī)則的目標終極目標所在的規(guī)則,應該是Makefile中的第1個規(guī)則,其余規(guī)則不分次序。Makefile規(guī)則Makefile中,規(guī)則描述了何種情況下111終極目標終極目標,就是執(zhí)行make時,沒有指明具體目標時,make默認的那個目標。第1個規(guī)則有多個目標時,第1個目標為終極目標,除非以下兩種情況1.目標名以點號”.”隔開,其后沒有斜線”/”2.作為模式規(guī)則的目標“終極目標“是執(zhí)行make的唯一目的,其所在的規(guī)則作為第一個規(guī)則。終極目標終極目標,就是執(zhí)行make時,沒有指明具體目標時,m112規(guī)則的語法通常規(guī)則的語法格式如下:TARGETS:PREREQUISITESCOMMAND...或者是這樣:TARGETS:PREREQUISITES;COMMANDCOMMAND...規(guī)則的語法通常規(guī)則的語法格式如下:113規(guī)則的核心思想規(guī)則的中心思想就是:目標文件的內容是由依賴文件決定,依賴文件的任何一處改動,將導致目前已經(jīng)存在的目標文件的內容過期。規(guī)則的命令為重建目標提供了方法。這些命令運行在系統(tǒng)shell之上。規(guī)則中的命令被執(zhí)行有兩種情況1.目標文件不存在;2.存在一個依賴的最后修改時間比目標的最后修改時間晚規(guī)則的核心思想規(guī)則的中心思想就是:目標文件的內容是由依賴文件114依賴的類型常規(guī)依賴常規(guī)依賴中的任何一個文件更新,都會導致重建目標。常用的形式order-only依賴在更新目標(目標文件已經(jīng)存在)時,只需要根據(jù)依賴文件中的部分來決定目標是否需要被重建,而不是在依賴文件的任何一個被修改后都重建目標。依賴的改動不會導致目標重建,稱為order-only依賴在書寫規(guī)則時,“order-only”依賴使用管道符號“|”開始,左邊是常規(guī)依賴,管道符右邊的全部是order-only依賴。依賴的類型常規(guī)依賴115舉例LIBS=libtest.afoo:foo.c|$(LIBS)$(CC)$(CFLAGS)$<-o$@$(LIBS)執(zhí)行make時,如果foo.c修改了,目標foo會重建,libtest.a修改了,foo不會重建libtest.a只有在foo不存在的情況下,才會參與規(guī)則的執(zhí)行。舉例LIBS=libtest.a116文件名使用通配符可使用的通配符有:“*”、“?”Makefile中統(tǒng)配符可以出現(xiàn)在以下兩種場合:1.可以用在規(guī)則的目標、依賴中,此時make會自動將其展開;2.可出現(xiàn)在規(guī)則的命令中,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年風電葉片模具競爭格局十年趨勢報告
- 高中教師資格證面試技巧
- 2026年人工智能金融科技報告及未來五至十年智能風控報告
- 保潔綠化員工年終總結(3篇)
- 2025年風電運維機器人五年研發(fā)傳感器技術報告
- 2026年濁度傳感器項目公司成立分析報告
- 2025年風電變槳系統(tǒng)五年技術革新報告
- 2026年航空航天行業(yè)新材料應用報告及全球供應鏈創(chuàng)新報告
- 2025年新能源汽車電池技術研發(fā)行業(yè)創(chuàng)新報告與能量密度報告
- 2026年布蘭迪斯大學國際商學院MBA面試猶太文化商業(yè)智慧含答案
- 主數(shù)據(jù)mdm管理辦法
- 醫(yī)院智慧管理分級評估標準體系(試行)-全文及附表
- DB14∕T 3327-2025 高速公路路基路面探地雷達檢測技術規(guī)程
- 《完整的PMC部作業(yè)流程體系》
- 氨水泄漏應急處置預案
- 心理輔導送教上門教學計劃
- 電商公司費用管理制度
- 2025春季學期國開電大本科《理工英語4》一平臺機考真題及答案(第一套)
- 警察抓捕教學課件
- 汽車4s店管理手冊
- 人教版英語九年級第十單元教案
評論
0/150
提交評論