國訊之linux makefile教程跟我一起寫_第1頁
國訊之linux makefile教程跟我一起寫_第2頁
國訊之linux makefile教程跟我一起寫_第3頁
國訊之linux makefile教程跟我一起寫_第4頁
國訊之linux makefile教程跟我一起寫_第5頁
已閱讀5頁,還剩72頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

跟我一起寫 TOC\o"1-2"\h\z\u概 Makefile介 五、讓make自動推 書寫規(guī) 五、偽目 六、多目 書寫命 使用變 五、override指示 一、示 二、語 使用函 四、foreach函 make的運 二、指定 隱含規(guī) —什么是makefile?或許很多WinodwsWindowsIDE這就好像現(xiàn)在有這么多的HTML的編輯器,但如果你想成為一個專業(yè)人士,你還是要了解HTMLUnixmakefile了,會不會寫makefile,從一個側(cè)面說明了一個人是否具備完成大型工程的能力。makefile就像一個Shell腳本一樣,其中也可以執(zhí)行操作系統(tǒng)的命令。C++nmake,LinuxGNUmake。可見,makefile都成為了一種在工程方面的編譯方makefile的文章比較少,這是我想寫這篇文章的原因。當(dāng)然,不同產(chǎn)商的make各不相同,也有不同的語法,但其本質(zhì)都是在“文件依賴性”上做文章,這里,我僅GNUmakeRedHatLinux8.0,make3.80。必竟,這(POSIX.2GCC和CC。C、C++pas,Windows.obj文件,UNIX.o文(compile(link告訴編譯器頭文件的所在位置(C/C++文件中,應(yīng)于一個中間目標(biāo)文件(O文件或是OBJ文件。FileWindows下這種包叫“庫文件”(LibraryFile).libUNIX下,是ArchiveFile,也就是.a文件。警告,但可以生成ObjectFile。而在鏈接程序時,鏈接器會在所有的ObjectFile中找尋函數(shù)ErrorLink2001錯誤,意思說是說,鏈接器未能找到函數(shù)的實現(xiàn)。你需要指定函數(shù)的ObjectFile.MakefilemakeMakefile文件,以告訴make命令需要怎么樣的去編譯和鏈接首先,我們用一個示例來說明Makefile的書寫規(guī)則。以便給大家一個感興認(rèn)識。這個示例我們要寫一個Makefile來告訴make命令如何編譯和鏈接這幾個文件。我們的規(guī)則是:如果這個工程沒有編譯過,那么我們的所有Ctarget...:prerequisitestargetObjectFile,也可以是執(zhí)行文件。還可以是一個標(biāo)(Label這是一個文件的依賴關(guān)系,也就是說,target這一個或多個的目標(biāo)文件依賴于prerequisitestarget文件要新的話,commandMakefile的規(guī)則。也就是Makefile中最核心的內(nèi)容。說到底,Makefile的東西就是這樣一點,好像我的這篇文檔也該結(jié)束了。呵呵。還不盡然,MakefileMakefile還不夠,我會以后面一點一點地結(jié)合)那三個規(guī)則,我們的Makefile應(yīng)該是下面的這個樣子的。edit:main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.occ-oeditmain.okbd.ocommand.odisplay.oinsert.osearch.ofiles.omain.o:main.ccc-ckbd.o:kbd.cdefs.hcommand.hcc-ckbd.ccommand.o:command.cdefs.hcommand.hcc-ccommand.cdisplay.o:display.cdefs.hbuffer.hcc-cdisplay.cinsert.o:insert.cdefs.hbuffer.hcc-cinsert.ccc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.hcc-cfiles.cutils.o:utils.ccc-ccleanrmeditmain.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o反斜杠(\)Makefile的易讀。我們可以把這個內(nèi)容保存在一下“makeclean”就可以了。(*.o件(prerequisites)就是冒號后面的那些.c文件和.h文件。每一個.o文件都有一組依賴文件,而這些.o文件又是執(zhí)行文件edit的依賴文件。依賴關(guān)系的實質(zhì)上就是說明了目標(biāo)比較targets文件和prerequisitesprerequisites文件的日期要比targets文件的日期要新,或者target不存在的話,那么,make就會執(zhí)行后續(xù)定義的命令。這里要說明一點的是,cleanC語言中的lable一樣,其冒號后什么也沒有,那么,make就不會自動去找文件的依賴性,也就不會自makelable(target3editedit.o4edit所依賴的.omake會在當(dāng)前文件中找目標(biāo)為.o文件的依賴性,如果找到則再根據(jù)那一個規(guī)則生成.o文件。(這有點像一個堆棧的過程)這就是整個make的依賴性,make會一層又一層地去找文件的依賴關(guān)系,直到最終編譯出make就會直接退出,并報錯,而對于所定義的命令的錯誤,或是編譯不成功,make根本不file.o會被重編譯(也就是在這個依性關(guān)系后面所定義的命令)file.ofile.oedit要新,所以edit也會被重新鏈接了(詳見edit目標(biāo)文件后定義的命令。edit:main.okbd.ocommand.odisplay.occ-oeditmain.okbd.ocommand.odisplay.oinsert.osearch.ofiles.o那么我們需要在兩個地方加(應(yīng)該是三個地方,還有一個地方在clean中。當(dāng)然,我們的makefilemakefile變得復(fù)雜,那么我們就有可objects,OBJECTS,objsOBJS,obj,OBJ,反正不管什么啦,只要能夠表示obj文件就行了。我們在makefile一開始就這樣定義:objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.o于是我們的改良版makefile就變成下面這個樣子:objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.oedit:cc-oedit$(objects)main.o:main.cdefs.hcc-ckbd.o:kbd.cdefs.hcommand.hcc-ckbd.ccommand.o:command.cdefs.hcommand.hcc-ccommand.cdisplay.o:display.cdefs.hbuffer.hcc-cdisplay.cinsert.o:insert.cdefs.hbuffer.hcc-cinsert.ccc-csearch.cfiles.o:files.cdefs.hbuffer.hcommand.hcc-cfiles.cutils.o:utils.ccc-ccleanrmedit.oobjects變量就可以了。GNUmake很強大,它可以自動推導(dǎo)文件以及文件依賴關(guān)系后面的命令,于是我們就沒必要去在每一個[.o]make會自動識別,并自己推make看到一個[.o]文件,它就會自動的把[.c]make找到一whatever.owhatever.cwhatever.occcwhatever.c也會objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.oedit:cc-oeditmain.o:kbd.o:defs.hcommand.hcommand.o:defs.hcommand.hdisplay.o:defs.hbuffer.hinsert.o:defs.hbuffer.hsearch.o:defs.hbuffer.hfiles.o:defs.hbuffer.hcommand.hutils.o:defs.hclean:rmeditmake可以自動推導(dǎo)命令,那么我看到那堆[.o]和[.h]的依賴就有點不爽,那么多的重復(fù)的[.h]make來說很容易,誰叫它提供了自動推導(dǎo)命令和文件的功能呢?來看看最新風(fēng)格的makefile吧。objects=main.okbd.ocommand.odisplay.o\insert.osearch.ofiles.outils.oedit:cc-oedit$(objects):kbd.ocommand.ofiles.o:command.hdisplay.oinsert.osearch.ofiles.o:buffer.hclean:rmedit二是如果文件一多,要加入幾個新的.o文件,那就理不清楚了。(rmeditclean:-rmedit的意思就是,也許某些文件出現(xiàn)問題,但不要管,繼續(xù)做后面的事。當(dāng)然,clean的規(guī)則不規(guī)矩是——“clean從來都是放在文件的最后”。2make有自動推導(dǎo)的功能,所以隱晦的規(guī)則可以讓我們比較粗糙地簡略地書寫Makefile,這是由make所支持的。3、變量的定義。在Makefile中我們要定義一系列的變量,變量一般都是字符串,這個有點你C語言中的宏,當(dāng)Makefile被執(zhí)行時,其中的變量都會被擴展到相應(yīng)的引用位置上。中的預(yù)編譯#if一樣;還有就是定義一個多行的命令。有關(guān)這一部分的內(nèi)容,我會在后續(xù)的5、注釋。MakefileUNIXShell腳本一樣,其注釋是用“#”字符,這C/C++中的“//Makefile中使用“#”字符,可以用反斜框進行轉(zhuǎn)義,如:“akefile“GNUmakefileGNU的make識別的。有另外一些make只對全小寫的如:make-fMake.Linux或make--fileMake.AIX。被包含的文件會原模原樣的放在當(dāng)前文件的包含位置。include的語法是:件叫foo.make,以及一個變量$(bar),其包含了e.mk和f.mk,那么,下面的語句:includefoo.make*.mkincludefoo.makea.mkb.mkc.mke.mk會在當(dāng)前目錄下首先尋找,如果當(dāng)前目錄下沒有找到,那么,make還會在下面的幾個目錄2、如果目錄<prefix>;/include(一般是:/usr/local/bin或/usr/include)存在的話,make如果有文件沒有找到的話,make會生成一條警告信息,但不會馬上出現(xiàn)致命錯誤。它會繼makefile的讀取,make會再重試這些沒有找到,或是不能讀取的文件,如果還是不行,makemake不理那些無法include前加一個減號“-”。如:include四、MAKEFILES,那么,make會把這個變量中的值做一Makefile的“目標(biāo)”不會起作用,如果環(huán)境變量中定義的文件發(fā)現(xiàn)錯誤,make也會不理。makeMakefile都會受到它的影響,這絕不是你想看到的。在這里提這個事,只Makefile出現(xiàn)了怪事,那么你可以看看當(dāng)前環(huán)境中有沒1-5步為第一個階段,6-7為第二個階段。第一個階段中,如果定義的變量被使用了,那么,make會把其展開在使用的位置。但make并不會完全馬上展開,make使用的是拖延戰(zhàn)術(shù),———Makefile中的目標(biāo)可能會有很多,但是第一條規(guī)則中的目標(biāo)將被確立為最終的目標(biāo)。如果第一條規(guī)則中的目標(biāo)有很多個,那么,第一個目標(biāo)會成為最終的目標(biāo)。make所foo.ofoo.c foocc-c-gfoo.c(期要比foo.o文件日期要新,或是foo.o不存在,那么依賴關(guān)系發(fā)生。個文件。(foo.cincludedefs.h文件)targets:prerequisitestargets:prerequisites;command如果和prerequisites在一行,那么可以用分號做為分隔。(見上)制。規(guī)則告訴make兩件事,文件的依賴關(guān)系和如何成成目標(biāo)文件。如果我們想定義一系列比較類似的文件,我們很自然地就想起使用通配符。make支持三各通配符代替了你一系列的文件,如“*.cc的文件。一個需要我們注意的rm-fprint:lpr-p$?touchprintprint依賴于所有的[.c]文件。objects=開,也就是讓objects的值是所有[.o]的文件名的集合,那么,你可以這樣:objects:=$(wildcard但最好的方法是把一個路徑告訴make,讓make在自動去找。只會在當(dāng)前的目錄中去找尋依賴文件和目標(biāo)文件。如果定義了這個變量,那么,make就會make的“vpath”關(guān)鍵字(注意,它是全小寫的,<3、vpath%.hvpathvpath語句中出現(xiàn)了相同的<pattern>;,或是被重復(fù)了的<pattern>;,那么,makevpath語句的先后順序來執(zhí)vpath%.cfoovpath% vpath%.cbarvpath%.cfoo:barvpath rm*.o供一個清除它們的“目標(biāo)”以備完整地重編譯而用。(以“makeclean”來使用該目標(biāo)).PHONY:rm*.o個Makefile中,那么你可以使用“偽目標(biāo)”這個特性:all:prog1prog2.PHONY:prog1:prog1.occ-oprog1prog1.oprog2:cc-oprog2prog2.oprog3:prog3.osort.outils.occ-oprog3prog3.osort.o.PHONY:cleanallcleanobjcleandiffcleanall:cleanobjcleandiffrmrmrm$@(bigoutputlittleoutput:generatetext.g-$(substoutput,,$@)>;bigoutput:generatetext.g-big>;bigoutputlittleoutput:text.ggeneratetext.g-little>;其中,-$(substoutput,,$@)中的“$Makefilesubst,all:$(objects)$(objects):%.o:$(CC)-c$(CFLAGS)$<-obacofoo.o:$(CC)-c$(CFLAGS)foo.c-ofoo.obar.o:bar.c$(CC)-c$(CFLAGS)bar.c-ofiles=foo.elcbar.o$(filter%.o,$(files)):%.o:$(CC)-c$(CFLAGS)$<-oemacs-fbatch-byte-compile的內(nèi)容。其的它內(nèi)容,我就不用多說了吧。這個例字展示了Makefile中更大的彈性。main.o:main.cdefs.hC文件包含了哪些頭文件,并且,你cc-Mmain.o:main.c而由編譯器自動生成了。需要提醒一句的是,如果你使用GNU的C/C++編譯器,你得用“-MM”參數(shù),不然,“M”參數(shù)會把一些標(biāo)準(zhǔn)庫的頭文件也包含進來。gccMmain.c那么,編譯器的這個功能如何與我們的Makefile聯(lián)系在一起呢。因為這樣一來,我們的Makefile也要根據(jù)這些源文件重新生成,讓Makefile自已依賴于源文件?這個功能并不現(xiàn)實,不過我們可以有其它手段來迂回地實現(xiàn)這一功能。GNU組織建議把編譯器為每一個源的Makefile文件,[.d]文件中就存放對應(yīng)[.c]文件的依賴關(guān)系。%.d:@set-e;rm-f$@;$(CC)-M$(CPPFLAGS)$<>;$@.$$$$;sed's,\($*\)\.o[:]*,\1.o$@:,g'<$@.$$$$>;$@;\rm-f$@.$$$$也就是[.d]文件,第二行的意思是,為每個依賴文件“$”,也就是[.c]文件生成依賴文件,一個替換,關(guān)于sed命令的用法請參看相關(guān)的使用文檔。第四行就是刪除臨時文件。main.o:main.cmain.omain.d:main.csources=foo.cbar.cgunguymadman回復(fù)于:2004-09-16———make會認(rèn)為其是一個空命令。UNIXShellmake的命令默認(rèn)是被“/bin/sh”——UNIX很像C/C++中的“”,其后的本行字符都被注釋。通常,make會把其要執(zhí)行的命令行在命令執(zhí)行前輸出到屏幕上。當(dāng)我們用“@”字符在命@echoXXX模塊 “@,echoXXX模塊當(dāng)依賴目標(biāo)新于目標(biāo)時,也就是當(dāng)規(guī)則的目標(biāo)需要被更新時,make會一條一條的執(zhí)行其后cd/home/hchencd/home/hchen;/hoe/hchen每當(dāng)命令運行完后,makemake會執(zhí)則中的某個命令出錯了(命令退出碼非零make就會終止執(zhí)行當(dāng)前規(guī)則,這將有可mkdir就成功執(zhí)行,萬事大吉,如果目錄存在,那么就出錯了。我們之mkdirmkdir出錯而終止Makefile的命令行前加一個減號“-(-rm-f還有一個全局的辦法是,給make加上“-i”或是“--ignore-errors”參數(shù),那么,Makefile件的編譯規(guī)則。那么我們總控的Makefile可以這樣書寫:cdsubdir&&$(MAKE)-C利于維護。這兩個例子的意思都是先進入“subdir”目錄,然后執(zhí)行make命令。export<variableexportvariable=variable=valueexportvariableexportvariable:=variable:=valueexportvariableexportvariable+=variable+=valueexportvariableexport就行了。后面什么也不用跟,表示傳遞MAKEFILESMakefile中,這是一(cdsubdir&&$(MAKE)MAKEFLAGS,那么你得確信其中的選項是大家都會用到的,如果程中輸出一些信息,讓你看到目前的工作目錄。比如,如果我們的下級make目錄是slient)Makefile中出現(xiàn)一些相同命令序列,那么我們可以為這些相同的命令序列定義一個變definerun-yaccyacc$(firstword$^)mvy.tab.c$@foo.c:foo.c(gunguymadman回復(fù)于:2004-09-16———MakefileC/C++語言中的宏一樣,他代表了一個文本字串,在MakefileC/C++所不同的是,令”或是Makefile的其它部分中。個不同的變量名。傳統(tǒng)的Makefile的變量名是全大寫的命名方式,但我推薦使用大小寫搭(objects=program.ofoo.outils.oprogram:$(objects)cc-oprogram$(objects):foo=cprog.o:$(foo)$(foo)-$(foo)prog.o:cc-cMakefileMakefile中的變量在Makefile中有兩種方式來foo=$(bar)bar=$(ugh)ugh=Huh?echoHuh?(Huh?)CFLAGS=$(include_dirs)-Oinclude_dirs=-Ifoo-IbarCFLAGS=$(CFLAGS)-A=B=make運行時非常慢,更糟糕的是,他會使用得兩個make的函數(shù)“wildcard”和“shell”發(fā)生不可預(yù)知的錯x:=y:=$(x)barx:=latery:=foobarx:=latery:=$(x)barx:=foobarifeq :=$(shellpwd) host-type:=$(shellarch)MAKE:=${MAKE}host-type=${host-type}whoami=${whoami}會記錄了我們的當(dāng)前Makefile的調(diào)用層數(shù)。space:=$(nullstring)#endoftheEmpty變量來標(biāo)明dir:= #directorytoputthefrobsFOO?=ifeq($(originFOO),FOO=barfoo:=a.ob.oc.obar:=foo:=a.ob.obar:=x=yy=a:=x=$(y))x=y=z=a:=x=y=z=a:=“Hellox=variable1y=$(substz=a:=“Helloa=b=all=Helloa_objects:=a.ob.oc.o1_objects:=1.o2.osources:=cfunc:=sortbar:=adbgqfoo:=$($(func)dir=$(dir)_sources:=$(wildcard$(dir)/*.c)define$(dir)_print_objects=main.ofoo.obar.outils.oobjects+=another.oant.(ant.objects=main.ofoo.obar.outils.oobjects:=$(objects)another.o=variable:=valuevariable+=variable:=variable:=$(variable)variable=valuevariable+=如果你想在Makefile中設(shè)置這類參數(shù)的值,那么,你可以使用“override”指示符。其語法override<variable>;=<value>;override<variable>;+=<moreoverridedefinefoogunguymadman回復(fù)于:2004-09-16defineendef關(guān)鍵字結(jié)因為命令需要以[Tab]define定義的命令變量中沒有以[Tab]鍵開頭,那么make就不會把其認(rèn)為是命令。echofoomakemakeMakefile文件中,但是如果Makefilemake命令行帶入,那么系統(tǒng)的環(huán)境變量的因此,如果我們在環(huán)境變量中設(shè)置了“CFLAGS”環(huán)境變量,那么我們就可以在所有的CFLAGSMakefile中的這個變量,如果沒有定義則使用系統(tǒng)環(huán)境變make嵌套調(diào)用時(參見前面的“嵌套調(diào)用”章節(jié)Makefile中定義的變量會以系Makefile中。當(dāng)然,默認(rèn)情況下,只有通過命令行設(shè)置的Makefileexprot當(dāng)然,我并不推薦把許多的變量都定義在系統(tǒng)環(huán)境中,這樣,在我們執(zhí)行不用的ariable<target...>;:<variable-<target...>;:overide<variable-=第二個語法是針對于make命令行帶入的變量,或是系統(tǒng)環(huán)境變量。prog:CFLAGS=-gprog:prog.ofoo.obar.o$(CC)$(CFLAGS)prog.ofoo.oprog.o:foo.o:bar.o:在這個示例中,不管全局的$(CFLAGS)prog目標(biāo),以及其所引發(fā)的所有規(guī)則中(prog.ofoo.obar.o的規(guī)則,$(CFLAGS)的值都是“-g”GNUmake中,還支持模式變量(Pattern-specificariable,通過上面的目標(biāo)變量中,我們知道,make的“模式”一般是至少含有一個“%”的,所以,我們可以以如下方式給%.o:CFLAGS=-<pattern...>;:<variable-<pattern...>;:override<variable-libs_for_gcc=-lgnunormal_libs=foo:$(objects)$(CC)-ofoo$(objects)

$(CC)-ofoo$(objects)我們可以從上面的示例中看到三個關(guān)鍵字:ifeq、elseendif。ifeq的意思表示條件語句的else表示條件表達(dá)式為假的情況。endif表示一個條件語句的結(jié)束,任何一個條件表達(dá)式都應(yīng)該以endif結(jié)束。$(CC)-ofoo$(objects)$(CC)-ofoo$(objects)libs_for_gcc=-lgnunormal_libs=ifeq($(CC),gcc)$(CC)-ofoo$(objects)ifeq(<arg1>;,ifeq'<arg1>;''<arg2>;'ifeq"<arg1>;""<arg2>;"ifeq"<arg1>;"'<arg2>;'ifeq'<arg1>;'"<arg2>;"比較參數(shù)“arg1”和“arg2make的函數(shù)。ifeq($(strip(Emptyifneq(<arg1>;,<arg2>;)ifneq'<arg1>;''<arg2>;'ifneq"<arg1>;"'<arg2>;'ifneq'<arg1>;'"<arg2>;"如果變量<variable-name>;的值非空,那到表達(dá)式為真。否則,表達(dá)式為假。當(dāng)然,<variable-name>;同樣可以是一個函數(shù)的返回值。注意,ifdef只是測試一個變量是否有值,barfoo=$(bar)ifdeffoofooifdeffoono特別注意的是,makeMakefile時就計算條件表達(dá)式的值,并根據(jù)條件表達(dá)式的值gunguymadman回復(fù)于:2004-09-16———Makefile中可以使用函數(shù)來處理變量,從而讓我們的命令或是規(guī)則更為的靈活和具有智能。make所支持的函數(shù)也不算很多,不過已經(jīng)足夠我們的操作了。函數(shù)調(diào)用后,函數(shù)的返這里,<function>;就是函數(shù)名,make支持的函數(shù)不多。<arguments>;是函數(shù)的參數(shù),參數(shù)間為了風(fēng)格的統(tǒng)一,函數(shù)和變量的括號最好一樣,如使用“$(substa,b,$(x))”這樣的形式,而不是“$(substa,b,${x})”的形式。因為統(tǒng)一會更清楚,也會減少一些不必要的麻煩。space:=$(empty)$(empty)foo:=abcbar:=$(substa,b,c$(subst$(substee,EE,feetonthestrEEt<ar>;,<rlaeent>;,$(ar))%eea例如有:objectsfoo.obar.o%.$(strip$(stripabc把字串“abc”去到開頭和結(jié)尾的空格,結(jié)果是“ab$(findstringa,ab$(findstringa,b$(filtersources:=foo.cbar.cbaz.sugh.hfoo:$(sources)cc$(filter%.c%.s,$(sources))-obaz.sobjects=main1.ofoo.omain2.obar.omains=main1.omain2.o)bar.o$(sort示例:$(sortfoobarlose)返回“barfoolose備注:sort函數(shù)會去掉<list>;中相同的單詞。r$(words備注:如果我們要取<text中最后的一個單詞,我們可以這樣:$(wordfoo一個現(xiàn)實中應(yīng)用的例子。我們知道,make使用“VPATH”變量來指定“依賴文件”的搜索overrideCFLAGS+=$(patsubst%,-I%,$(subst:,如果我們的“$(VPATH)”值是“src:../headers”,那么-$(dir“/)之前的部分。如果沒有反斜杠,那么返回“/./“hacks示例:$(suffixsrc/foo.csrc-1.0/bar.chacks)返回值是“.c.c示例:$(basenamesrc/foo.csrc-1.0/bar.chacks)返回值是“src/foosrc-1.0/barhacks.bar.csrc/bargunguymadman回復(fù)于:2004-09-16四、foreachforeach函數(shù)和別的函數(shù)非常的不一樣。因為這個函數(shù)是用來做循環(huán)用的,Makefile中的中的foreach語句而構(gòu)建的。它的語法是:成的整個字符串(以空格分隔)將會是foreach函數(shù)的返回值。names:=abcfiles:=$(foreachd.o注意,foreach中的<var>;參數(shù)是一個臨時的局部變量,foreach函數(shù)執(zhí)行完后,參數(shù)<var>;的變量將不在作用,其作用域只在foreach函數(shù)當(dāng)中。五、if,那么六、callcall函數(shù)是唯一一個可以用來創(chuàng)建新的參數(shù)化的函數(shù)。你可以寫一個非常復(fù)雜的表達(dá)式,這$(call當(dāng)make執(zhí)行這個函數(shù)時,<expression>;參數(shù)中的變量,如$(1),$(2),$(3)reverse= $(1)$(2)foo=$(callreverse,a,b)reverse $(2)foo=$(calla字符。Originorigin函數(shù)的undefined這些信息對于我們編寫Makefile是非常有用的,例如,假設(shè)我們有一個Makefile其包了一Make.defMake.def中定義了一個變量“bletch”,而我們的環(huán)境中也有一個如果來源于Make.def或是命令行等非環(huán)境的,那么我們就不重新定義它。于是,在我們的Makefile中,我們可以這樣寫:ifeq"$(originbletch)""environment"bletch=barf,gag,etc.shellShell的命令。它和反于是,我們可以用操作系統(tǒng)命令以及字符串處理命令awk,sed等等命令來生成一個變量,contents:=$(shellcatfiles:=$(shellechoShell程序來執(zhí)行命令,所以你要注意其運行性能,如果你的Makefileshell函數(shù)執(zhí)行的次數(shù)比你想像的多得多。時信息,并且根據(jù)這些信息來決定,你是讓make繼續(xù)執(zhí)行,還是停止。$(error<text產(chǎn)生一個致命的錯誤,<text...>;是錯誤信息。注意,error函數(shù)不會在一被使用就會產(chǎn)$(errorerroris$(ERROR_001))ERR=$(errorfoundanerr:;ERROR_001error$(warning<texterrormakegunguymadman回復(fù)于:2004-09-16make是講述如何使用make命令的。返回2。make命令指定一個特殊名字的Makefile。要達(dá)到這個功能,我們要使名字是“hchen.mk”,那么,我們可以這樣來讓make來執(zhí)行這個文件:make–fmake的命令行是,你不只一次地使用了“-fmakefile將會被連在一起傳遞給make執(zhí)行。一般來說,makemakefile中的第一個目標(biāo),而其它目標(biāo)一般是由這個目標(biāo)連make,讓其完成你所指定的目標(biāo)。要達(dá)到這一目的很簡單,需在make命令后直接跟目標(biāo)的名字就可以完成(如前面提到的“makeclean”形式)make的終極目標(biāo),也就是說,只要make可以找到其隱含規(guī)則推導(dǎo)sources=foo.cifneq($(MAKECMDGOALS),clean)include$(sources:.c=.d)“foo.d”和“bar.d”這兩個makefile。all:prog1prog2prog3makefile中有四個需要編譯的程序——“prog1”,prog2makefileUnix世界中,軟件能。我們可以參照這種規(guī)則來書寫我們的makefile中的目標(biāo)。我想,GNU搞出這些東西一定有其可取之處(UNIX下的程序文件一多時你就會發(fā)是執(zhí)行的序列。于是我們可以使用make命令的下述參數(shù):“-打印出來,但不執(zhí)行,這些參數(shù)對于我們調(diào)試makefile很有用處。“-這個參數(shù)的意思就是把目標(biāo)文件的時間更新,但不更改目標(biāo)文件。也就是說,make假“-“-WMake它產(chǎn)商的make的具體參數(shù)還是請參考各自的產(chǎn)品文檔?!?Cmakefile的目錄。如果有多個“-C”參數(shù),make的解釋是后面的路徑以前面的作于“make–C~hchen/test/prog“—ebu=a“-I“-j指同時運行命令的個數(shù)。如果沒有這個參數(shù),make運行命令時能運行多少就運行多少。如“-l“-omakefilemakefilemakefile,你可以使用“makeqp”命令。如果你想查看執(zhí)行makefile前的預(yù)設(shè)變量和規(guī)則,你可以使用“make–p–f/dev/nullmakefile文件的文件名和行號,所以,用這個參數(shù)來調(diào)試你的makefile會是很有用的,特別是當(dāng)你的環(huán)境變量很復(fù)雜的時候。取消“-k”選項的作用。因為有些時候,make的選項是從環(huán)境變量“MAKEFLAGS”中繼“-Wgunguymadman回復(fù)于:2004-09-16———在我們使用Makefile時,有一些我們會經(jīng)常使用,而且使用頻率非常高的東西,比如,我C/C++的源程序為中間目標(biāo)文件(Unix下是[.o]文件,Windows下是[.obj]文件。本“隱含規(guī)則”也就是一種慣例,make會按照這種“慣例”心照不喧地來運行,那怕我們的Makefile中沒有書寫這樣的規(guī)則。例如,把[.c]文件編譯成[.o]文件這一規(guī)則,你根本就不用寫出來,make會自動推導(dǎo)出這種規(guī)則,并生成我們需要的[.o]文件。們Makefile的兼容性。makemake可以自動推導(dǎo)生成這個目make事先約定好的一些東西。例如,我們有下面的一個Makefile:foo:foo.occ–ofoofoo.obar.o$(CFLAGS)Makefilefoo.obar.o這兩目標(biāo)的規(guī)則和命make會在自己的“隱含規(guī)則”庫中尋找可以用的規(guī)則,如果找到,那么就會使用。如果找不到,那么就會報錯。在上面的那個例子中,make調(diào)用的隱含規(guī)則是,把[.o]的目標(biāo)的依賴foo.o:bar.o:bar.ccc–cbar.c當(dāng)然,如果我們?yōu)閇.o]文件書寫了自己的規(guī)則,那么make就不會自動推導(dǎo)并調(diào)用隱含規(guī)則,foo.o:foo.p(Pascal因為,在隱含規(guī)則中,PascalC的規(guī)則之后,所以,makefoo.o的C的規(guī)則就不再尋找下一條規(guī)則了。如果你確實不希望任何隱含規(guī)則推導(dǎo),那么,你就則,那么,make就會在這些規(guī)則中尋找所需要規(guī)則和命令。當(dāng)然,我們也可以使用make在目標(biāo).SUFFIXES的依賴目標(biāo)),那么隱含規(guī)則就會生效。默認(rèn)的后綴列表是:.out,a,ln,o,c,.cc,C,.p,.f.F.ry,l,s.Smod,.sym.defh,.info,dvi,textexinfo,.texi,txinfo,wchweb,sh,elc,el。具體的細(xì)節(jié),我們會在后面講述?!?lt;n>;.o”的目標(biāo)的依賴目標(biāo)會自動推導(dǎo)為“<n>;.c”,并且其生成命令是“$(CC)2、編譯C++程序的隱含規(guī)則。)$(CFLAGS)是“.C”)“<n>;.o”的目標(biāo)的依賴目標(biāo)會自動推導(dǎo)為“<n>;.p”,并且其生成命令是“$(PC)$(G) “$(FC) “$(FC) “$(FC) “$(FC)–F$(FFLAGS)且其生成命令是:“$(M2C)$(M2FLAGS)$(MODFLAGS)$(ASFLAGS)一般是“l(fā)d,其生成命令是:“$(CC$(LDFLAGS<n>;.o$(LOADLIBES$(LDLIBS)”。這個規(guī)則對于只有一個源文件的工程有效,同時也對多個Object文件(由不同的源文件生成)的也有效。x:y.occ-cx.c-ox.occ-cy.c-occ-cz.c-occx.oy.oz.o-oxrm-fx.orm-f如果沒有一個源文件(x.c)和你的目標(biāo)名字(x)相關(guān)聯(lián),那么,n.y(acc$(YGS)“accn.l(Lex$(LALGS)n.l(Lex$()在隱含規(guī)則中的命令中,基本上都是使用了一些預(yù)先設(shè)置的變量。你可以在你的makefile例如,第一條隱含規(guī)則——編譯C程序的隱含規(guī)則的命令是“$(CC)–c把變量“$(CFLAGS)”重定義成“-g”,那么,隱含規(guī)則中的命令全部會以“gcc–c-gasccg++

co

)Fortran和Ratfor的編譯器和預(yù)處理程序。默認(rèn)命令是“f77SCCS文件中擴展文件的程序。默認(rèn)命令是“getRatforlexPascal語言編譯程序。默認(rèn)命令是“pcyaccakeinfotextexi2dviweavecweavetanglectanglervSCCS“getld)RatforFortranYacc的[.y]文件先成[.c]C的編譯器生成。我們把這一系列的隱含規(guī)則叫文件,但有一個[.y]Yacc的隱含規(guī)則會被調(diào)用,生成[.c]C我們把這種[.c]的文件(或是目標(biāo),叫做中間目標(biāo)。不管怎么樣,make會努力自動推導(dǎo)生這樣生成?怎么我的makefile發(fā)瘋了?目標(biāo)過程中,所產(chǎn)生的中間目標(biāo)文件會被以“rm-f”刪除。makefile指定成目標(biāo)或是依賴目標(biāo)的文件不能被當(dāng)作中介。然而,你可以明顯(如:.INTERMEDIATEmid:Make會優(yōu)化一些特殊的隱含規(guī)則,而不生成中間文件。如,從文件“foo.c”生成目標(biāo)程序這一動作可以被一條“cc”的命令完成(cc–ofoofoo.c,于是優(yōu)化過的規(guī)則就不會生成gunguymadman回復(fù)于:2004-09-16的長度至少為5。%.o:%.c; b.o",那么"%c"就是"a.cb.c"。一旦依賴目標(biāo)中的"%"模式被確定,那么,make會被要求去匹配當(dāng)前目錄下所有的文件名,一旦找到,make就會規(guī)則下的命令,所以,在模式規(guī)則中,目標(biāo)可能會是多個的,如果有模式匹配出多個目標(biāo),make就會產(chǎn)生所有的模式目標(biāo),此時,make關(guān)心的是依賴的文件名%.o:$(CC)-c$(CFLAGS)$(CPPFLAGS)$<-o%.tab.c%.tab.h:bison-d這條規(guī)則告訴make把所有的[.y]文件都以"bison-d<n>;.y"執(zhí)行,然后生成"<n>;.tab.c"和僅當(dāng)目標(biāo)是函數(shù)庫文件中,表示規(guī)則中的目標(biāo)成員名。例如,如果一個目標(biāo)是下是[.a],Windows下是[.lib],那么,其值為空。式是",那么,"的值就是"。這個變量對于構(gòu)造有關(guān)聯(lián)的文件名是比較有e"eUema

溫馨提示

  • 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)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論