乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      NMAKE 詳解(整理轉(zhuǎn)載)

       量子記憶 2020-02-24
      另外,makefile中使用以下幾個具有特殊意義的符號:
        ^ # / ( ) { } ! @ - : ; $
        ^(caret):用于關(guān)閉某些字符所具有的特殊意義,使其只表示字面上的意義。例如:^#abc表示#abc這個字符串,而#abc則用于在makefile中加入注釋,#在這里為注釋標(biāo)志,就像C++中的//。另外,在一行的末尾加上^,可以使行尾的回車換行符成為字串的一部分。
        #(number sign):為注釋標(biāo)志,NMAKE會忽略所有從#開始到下一個換行符之間的所有文本。這里要注意的是:在command lines中不能存在注釋。因?yàn)閷τ赾ommand lines,NMAKE是將其整行傳遞給OS的。通常對于command lines的注釋都是放在行與行之間。
        /(backslash):用于將兩行合并為一行。將其放在行尾,NMAKE就會將行尾的回車換行符解釋為空格(space)。
        %(percent symbol):表示其后的字符串為一文件名。用法較復(fù)雜,在講dependent lines的時候再詳細(xì)討論。
       ?。。╡xclamation symbol):命令修飾符,在下面會有詳細(xì)的討論。
        @(at sign):命令修飾符,在下面會有詳細(xì)的討論。
        :(colon):用于dependent lines和inference rules中,用于分隔target和dependent。
        ;(semicolon):如果對于一個dependent line只有一條命令,則可以將該命令放在dependent line的后面,二者之間用“;”分隔。
        $(dolor sign):用于調(diào)用宏,在下面講宏的時候再詳細(xì)討論。
        在makefile中還可以使用DOS通配符(wildcard)來描述文件:*和?。作用相信大家都很熟悉了,在此就不再浪費(fèi)口水了。
        如果要將中間有空格或制表符的字符串作為整體對待,則應(yīng)該用雙引號將之括起來,例如,在指定一個中間有空格的長文件名的時候:
        “My Document”
        或在定義一個宏的時候:
         MYMACRO=”copy a:/foo.exe c:/”
        描述語句塊(Description Blocks)
         描述語句塊為makefile主體的基本組成單元,其典型結(jié)構(gòu)如下:
         target : dependents
         commands block
        Dependent Line
         每一個描述語句塊中只有一個dependent line,其定義了一個依賴關(guān)系。該行的開頭不能有任何空白(空格或制表符)。冒號兩邊的target和dependent都可以有多個,之間以空格分隔。NMAKE在分析makefile時首先會從頭到尾掃描每一個dependent line,然后根據(jù)依賴關(guān)系建立起一棵依賴關(guān)系樹(dependent tree)。例如對于依賴關(guān)系:
         foo.exe : first.obj second.obj
         first.obj : first.cpp
         second.obj : second.cpp
        則在其依賴關(guān)系樹中,foo.exe為first.obj和second.obj的父親,而first.obj則是first.cpp的父親,second.obj是second.cpp的父親。如果second.cpp被更新了,則second.obj會被重新構(gòu)造,從而導(dǎo)致foo.exe被重新構(gòu)造。NMAKE就是這樣由下而上地對整棵樹中的結(jié)點(diǎn)進(jìn)行評估的。
         雖然makefile中可以有很多的dependent lines,但NMAKE只會構(gòu)造出現(xiàn)在它的命令行中的targets,或者,如果命令行中沒有給出targets,就構(gòu)造第一個dependent line中的第一個target。其他所有無關(guān)的targets都不會被構(gòu)造。例如:
         foo1.exe foo2.exe : first.obj
         first.obj : first.cpp
         second.obj : second.cpp
        假設(shè)上面的第一行語句為makefile中出現(xiàn)的第一個dependent line,且命令行中沒有給出target。當(dāng)first.cpp被更新后,first.obj和foo1.exe都會被重新構(gòu)造,而foo2.exe和second.obj則不會。
         當(dāng)在一個dependent line中出現(xiàn)多個target時,例如:
         boy.exe girl.exe : first.obj
         echo Hello
         該語句相當(dāng)于:
         boy.exe : first.obj
         echo Hello
         girl.exe : first.obj
         echo Hello
       ?。ㄗⅲ篹cho是一條控制臺命令,用于在STDOUT上顯示一行信息)
         同一個target也可以出現(xiàn)在多個dependent lines中。在這種情況下,如果只有一個dependent line后跟有command line,則它們會被合并為一個描述語句塊,例如:
         foo.exe : first.obj
         echo Building foo.exe…
         …
         foo.exe : second.obj
        NMAKE會將其處理為:
         foo.exe : first.obj second.obj
         echo Building foo.exe…
         如果每一個dependent line后都有command line,則它們會被作為兩個描述語句塊處理。
        如果在dependent line中使用雙冒號(::)來分隔target和dependent,并且同一個target出現(xiàn)在多個描述語句塊中,此時,NMAKE將會匹配最合適的語句塊,以構(gòu)造該target。
        例如:
         target.lib :: one.asm two.asm three.asm
        ML one.asm two.asm three.asm
        LIB target -+one.obj -+two.obj -+three.obj;
        target.lib :: four.c five.c
        CL /c four.c five.c
        LIB target -+four.obj -+five.obj;
        Target.lib同時出現(xiàn)在兩個描述語句塊中,此時,NMAKE在處理該makefile時,將會選擇其中一個描述語句塊中的命令來執(zhí)行。如果任何asm文件被更新了,NMAKE就調(diào)用ML重新編譯之,然后再調(diào)用LIB(但CL以及之后的命令都不會被調(diào)用);類似地,如果任何C文件被更新了,NMAKE就會調(diào)用CL。
         在通常情況下,target和dependent都是文件名。NMAKE會首先在當(dāng)前目錄下搜索dependent,如果沒有找到,就到用戶指定的目錄下搜索。指定搜索路徑的語法如下:
         {directory1;directory2;…}dependent
        搜索路徑放在{}之中,如果有多個,就用“;”分開。注意,在各個語法成分之間是不能有空白的。
         Target和dependent也可以不是一個文件,而是一個標(biāo)號(label)。這時,就稱之為pseudotarget(偽文件)。Pseudotarget的名字不能與當(dāng)前目錄下的任何文件名相同。一個pseudotarget如果要作為dependent,那么它必須要作為target出現(xiàn)在某個dependent line中。當(dāng)使用pseudotarget作為target時,與之關(guān)聯(lián)的commands block一定會被執(zhí)行,同時NMAKE會賦予它一個假想的time stamp。該time stamp等于它的dependents中最大的time stamp,或者,如果它沒有dependent,就等于當(dāng)前時間。該假想的time stamp在pseudotarget作為dependent時會被用來進(jìn)行有效性評估。這個特性最大的好處就是,你可以讓NMAKE構(gòu)造多個target,而不用將每個target都在NMAKE的命令行中列出來,例如:
         all : setenv project1.exe project2.exe
        project1.exe : project1.obj
        LINK project1;
        project2.exe : project2.obj
        LINK project2;
        setenv :
        set LIB=/project/lib
        上例中有兩個pseudotarget,一個是all,另一個是setenv。首先是setenv被評估,其作用是設(shè)置環(huán)境變量LIB,然后project1.exe和project2.exe依次被更新.
        Commands Block
         第二行開始到下一個dependent line之間為commands block,其給出了當(dāng)dependents中的任何一個的time stamp大于target時,需要執(zhí)行的指令序列(commadns block也可以為空,此時,NMAKE什么也不干)。command line必須以空白開頭(剛好與dependent line相反,NMAKE就是通過該特征來分辨二者的),并且在dependent line和commands block中的第一條語句之間不能有空白行(就是除了一個換行符,什么也沒有的行。所以只有一個空格或制表符的行是合法的,此時NMAKE將其解釋為一個null command),但在command lines之間可以有空白行。Commands block中的每一條命令可以是在控制臺中合法的任何命令。事實(shí)上大可將commands block當(dāng)成一個由控制臺命令序列組成的批處理文件。
         此外,對commands block中的命令,還可以在其前面添加一個或多個所謂的命令修飾符(command modifier),以實(shí)現(xiàn)對命令的一些額外的控制。命令修飾符有以下3種:
        1) @command
        消除該命令的所有到STDOUT的輸出。
        2) –[number]command
        關(guān)掉對該命令返回值的檢測。在默認(rèn)的情況下,如果一條命令返回非0值,則NMAKE將會停止執(zhí)行。但如果在命令前加上一“-”,則NMAKE將會忽略該命令的返回值。如果“-”緊接著一個整數(shù),則NMAKE會忽略掉任何大于該整數(shù)的返回值。
        3) !command
        如果該命令的執(zhí)行對象為$**或$?(這兩個都是預(yù)定義的宏,前者表示相應(yīng)的dependent line中所有的dependent,后者表示所有比target具有更大的time stamp的dependent),則該“!”修飾符將會使該命令施行于這兩個宏所描述的每一個獨(dú)立的文件上。
         NMAKE還提供了一些語法可以在commands block中表示相應(yīng)的dependent line中第一個dependent的文件名組成。例如:
         foo.exe : c:/sample/first.obj c:/sample/second.obj
         link %s
        NMAKE將“l(fā)ink %s”解釋為:
         link c:/sample/first.obj
        如果將命令改為“l(fā)ink %|pfF.exe”,則NMAKE將之解釋為:
         link c:/sample/first.exe
        %s表示全文件名,%|[part]F表示文件名中的某個部分,part可以是下列字符中的一個或多個,如果part為空,%|F與%s的意思相同:
        1) d:盤符;
        2) p:路徑;
        3) f:文件基本名;
        4) e:文件擴(kuò)展名;
      Inference Rules(推導(dǎo)規(guī)則)
         Inference rules(下文簡稱IR)是一個模板,它用于決定如何從一個具有某種擴(kuò)展名的文件構(gòu)造出一個具有另一種擴(kuò)展名的文件。NMAKE通過IR來確定用來更新target的命令以及推導(dǎo)target的dependents。IR的好處在于它滿足了像我這樣的懶人的需要。只要提供了正確的IR,則描述語句塊就可以極大地化簡。請看下面的例子:
         foo.obj :
        上面的語句將會運(yùn)作得很好。是不是覺得很吃驚呢?事實(shí)上,NMAKE在處理該語句的時候,它首先在當(dāng)前目錄下搜索基本名為foo的文件(假設(shè)當(dāng)前目錄下有一個foo.c文件)。然后它查找一個后綴列表(suffix list),里面的每一項包含了從一種類型的文件構(gòu)造另一種類型的文件需要調(diào)用的命令和參數(shù)的相關(guān)信息。在NMAKE預(yù)定義的列表中,foo.c到foo.obj的構(gòu)造命令為CL。最后NMAKE調(diào)用CL,編譯foo.c。呵呵,這么一長串的操作一條簡單的語句就搞定了,是不是很方便呢!
         當(dāng)出現(xiàn)下列情況之一時,NMAKE就會嘗試使用IR:
        l NMAKE遇到一個沒有任何命令的描述語句塊。此時NMAKE就會搜索后綴列表,試圖找到一個匹配的命令來構(gòu)造target。
        l 無法找到某個dependent,并且該dependent沒有作為target出現(xiàn)在其它dependent line中(即它不是一個pseudotarget)。此時NMAKE就會搜索給定的目錄以及后綴列表,試圖找到一個IR來構(gòu)造出該dependent。
        l 一個target沒有dependent,并且描述語句塊中沒有給出指令。此時NMAKE就會試圖找出一個IR來構(gòu)造出該target。
        l 一個target在NMAKE的命令行中給出,但在makefile里沒有該target的相關(guān)信息(或根本就沒有makefile)。此時NMAKE就會試圖找出一個IR來構(gòu)造出該target。
        定義一個IR的語法如下:
         [{frompath}].fromext[{topath}].toext;
         commands
        注意,各語法元素之間不能有任何空格。Dependent的后綴名在fromext中給出,target的后綴名在toext中給出。Frompath和topath是可選的,分別給出了搜索的路徑。在每個IR的定義中只能分別為每一個后綴名給出一個搜索路徑。如果想要指定多個搜索路徑,就必須定義多個IR。并且,如果你為一個后綴指定了搜索路徑,那么你也必須為另一個后綴指定搜索路徑。即是說,fromext和topath只要有一個存在,則另一個也必須存在。你可以使用{.}或{}來表示當(dāng)前目錄。
        另外,要注意的是,如果你在IR中指定了搜索路徑,則在dependent lien中也必須指定同樣的路徑,否則IR將不會應(yīng)用于dependent line上,例如:
         {../proj}.exe{../proj}.obj:
        該IR不會用于下列語句上:
        project1.exe : project1.obj
        但會用于下列語句上:
        {../proj}project1.exe : {../proj}project1.obj
        NMAKE本身提供了一個預(yù)定義的后綴列表,內(nèi)容如下:
         Rule Command Default Action
         .asm.exe $(AS)$(AFLAGS) $*.asm ML $*.ASM
        .asm.obj $(AS)$(AFLAGS) /c $*.asm ML /c $*.ASM
        .c.exe $(CC)$(CFLAGS) $*.c CL $*.C
        .c.obj $(CC)$(CFLAGS) /c $*.c CL /c $*.C
        .cpp.exe $(CPP)$(CPPFLAGS) $*.cpp CL $*.CPP
         .cpp.obj $(CPP)$(CPPFLAGS) /c $*.cpp CL /c $*.CPP
        .cxx.exe $(CXX) $(CXXFLAGS) $*.cxx CL $*.CXX
        .cxx.obj $(CXX) $(CXXFLAGS) /c $*.cxx CL /c $*.CXX
        .bas.obj $(BC) $(BFLAGS) $*.bas; BC $*.BAS;
        .cbl.exe $(COBOL) $(COBFLAGS) $*.cbl, $*.exe; COBOL $*.CBL, $*.EXE;
        .cbl.obj $(COBOL) $(COBFLAGS) $*.cbl; COBOL $*.CBL;
        .for.exe $(FOR) $(FFLAGS) $*.for FL $*.FOR
        .for.obj $(FOR) /c $(FFLAGS) $*.for FL /c $*.FOR
        .pas.exe $(PASCAL) $(PFLAGS) $*.pas PL $*.PAS
        .pas.obj $(PASCAL) /c $(PFLAGS) $*.pas PL /c $*.PAS
        .rc.res $(RC) $(RFLAGS) /r $* RC /r $*
         在上表中,類似AFLAG和CFLAG這種被包含在括號里面的是未定義的宏,通過在makefile中對這些宏給出定義,可以為這些命令指定編譯器和參數(shù)。例如:
         $(AS)$(AFLAGS) $*.asm
        AS宏用于指定編譯器,NMAKE中默認(rèn)為ML;AFLAGS宏用于給出編譯器參數(shù),NMAKE將之留給用戶定義,默認(rèn)為空。所以默認(rèn)的操作為:
        ML $*.asm
        這里可以看到將宏展開的語法,就是將宏的名字用圓括號括起來,然后在前面加上一個美元符號。另外需要說明的是,”$*”是NMAKE預(yù)定義的一個特殊的宏,其等于target的路徑加上target的基本名。
        宏(MARCRO)
         這個相信大家都十分熟悉了。在makefile中通過使用宏將可以獲得很大的靈活性。下面就是在makefile中定義宏的語法:
         macroname=string
        在makefile中,macroname是宏的名字,其可以是任何字母,數(shù)字和下劃線的組合,最多可以有1024個字符。另外要注意的是,macroname是大小寫敏感的。string是宏的定義體,可以有高達(dá)65510個字符。任何包含0個字符或只包含空白的字符串都被視為空字串(null string),此時,該宏也被視為NULL,任何其出現(xiàn)的地方,都會被替換為空白。
         在使用宏時,還應(yīng)知道以下幾個具有特殊意義的符號:
        l # 用于注釋,例如:
        command=ML # compile asm file
        l / 將宏定義分作多行來寫,例如:
        LINKCMD = link myapp
        another, , NUL, mylib, myapp
        “/”后面的回車換行符會被空格替換,上面兩行相當(dāng)于:
        LINKCMD = link myapp another, , NUL, mylib, myapp
        l $ 將宏展開,用法在后面介紹。
        l ^ 如果要在宏中包含以上符號,但又不使用它們的特殊語義,則可以這樣:
        dir=c:/windows^
        此時,dir相當(dāng)于字符串”c:/windows/”。
         以下是一些語法上的細(xì)節(jié):
        1) 在定義宏時,宏名字的第一個字符必須是該行的第一個字符;
        2) 每行只能定義一個宏;
        3) 在”=”兩邊可以有空格,但它們都會被忽略;
        4) 在宏定義體中可以有空格,它們都會被視為宏的一部分;
        除了可以在makefile中定義宏之外,宏定義也可以出現(xiàn)在NMAKE命令行中。此時,如果在宏定義中有任何空白,則必須用雙引號將之括起來,例如:
        NMAKE "LINKCMD = LINK /MAP"
        NMAKE LINKCMD="LINK /MAP"
        而像下面這樣則是不允許的(等號兩邊有空格):
         NMAKE LINKCMD = "LINK /MAP"
         使用宏的語法如下(注意,整個語句中不能有任何空格):
         $(macroname)
         NMAKE會將整個語句用宏替換掉。如果宏未定義,NMAKE會用空白替換之,不會產(chǎn)生任何錯誤。如果宏的名字只有一個字符,則括號可以省略,例如:$L和$(L)是等價的。
         NMAKE為宏的使用還提供了一個很有用的特性,那就是substitution(子替換)。即是在展開宏的時候,你還可以指明將展開的宏中的某部分文本用另外的文本替換掉。例如:
         SOURCE=one.c two.c
        foo.exe : $(SOURCE:.c=.obj)
         LINK $**;
        展開來就是這樣:
        SOURCE=one.c two.c
        foo.exe : one.obj two.obj
         LINK one.obj two.obj;
        語句$(SOURCE:.c=.obj)表示將SOURCE中出現(xiàn)的所有”.c”替換為”.obj”。
        由以上的例子可以看出,substitution的語法如下(注意,沒有空格):
        $(macroname:str1=str2)
         此外,NMAKE還提供了4組預(yù)定義的宏,它們分別是文件名宏,遞歸宏,命令宏和參數(shù)宏。它們都可以被重新定義,但可能會引起一些不必要的麻煩,因?yàn)樗鼈儽粡V泛使用。正所謂“動一發(fā)而牽全身”,一個小小的改動,甚至有可能會影響到太陽黑子的運(yùn)動(蝴蝶效應(yīng)),這就是使用宏的最大的弊端。
        文件名宏
        在commands block中使用,以表示特定的文件名,包括:
      1) $@ 用來表示相關(guān)聯(lián)的dependent line中第一個target的全名(包括路徑)。
        2) $$@ 同上,但只能用在dependent line中。
        3) $* target的路徑加基本名。
        4) $** 相應(yīng)的dependent line中的所有dependent。
        5) $? 相應(yīng)的dependent line中的所有time stamp大于target的dependent。
        6) $< 同上,但只能用在IR中。
        下面是一個例子:
        DIR = c:/objects
        $(DIR)/a.obj : a.obj
        COPY a.obj $@
      最后一句展開來就相當(dāng)于:copy a.obj c:/objects/a.obj
         另外,在使用以上這些宏的時候,還可以通過以下的字符來提取文件名中的某一個部分:
         D 路徑
         B 基本名
         F 基本名加擴(kuò)展名
         R 路徑加基本名
         例如:如果$@表示c:/objects/a.object,則
         $(@D) c:/objects
         $(@B) a
         $(@F) a.obj
         $(@R) c:/objects/a
        遞歸宏
         有3個,它們都是用來在makefile中方便地進(jìn)行NMAKE的遞歸調(diào)用,它們分別是:
        1) MAKE
        表示運(yùn)行當(dāng)前makefile的NMAKE程序的名字。例如,如果你在控制臺用以下語句運(yùn)行makefile:
        NMAKE her.mak
        則MAKE就等于NMAKE。
        但如果你將NMAKE.EXE改名為FUCK.EXE,那么你運(yùn)行makefile的命令就應(yīng)該改為:
        FUCK her.mak
        此時,MAKE就等于FUCK。
        2) MAKEDIR
        表示你調(diào)用NMAKE時所在的目錄。
        3) MAKEFLAGS
        表示你運(yùn)行當(dāng)前makefile時使用的NMAKE參數(shù)。
         這幾個宏在build程序的不同版本時特別有用,例如:
         all : vers1 vers2
        vers1 :
        cd /vers1
        $(MAKE)
        cd ..
        vers2 :
        cd /vers2
        $(MAKE) /F vers2.mak
        cd ..
         NMAKE會分別在./vers1和./vers2目錄下運(yùn)行vers1.mak和vers2.mak。
        命令宏和參數(shù)宏
         命令宏表示Microsoft的編譯程序(真的很會做生意,任何時候都不忘自己的產(chǎn)品),而參數(shù)宏則是表示傳遞給這些編譯器的參數(shù),在默認(rèn)情況下,參數(shù)宏都是未定義的。當(dāng)然,你可以重新定義它們,讓它們表示Boland的編譯程序和參數(shù)。
         命令宏 對應(yīng)的參數(shù)宏
        1) AS ml,M的匯編編譯器。 AFLAGS
        2) BC bc,M的BASIC編譯器。 BFLAGS
        3) CC cl,M的C編譯器。 CFLAGS
        4) COBOL cobol,M的COBOL編譯器。 COBFLAGS
        5) CPP cl,M的C++編譯器。 CPPFLAGS
        6) CXX cl,M的C++編譯器。 CXXFLAGS
        7) FOR fl,M的FORTRAN編譯器。 FFLAGS
        8) PASCAL pl,M的PASCAL編譯器。 PFLAGS
        9) RC rc,M的資源編譯器。 RFLAGS

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多