簡介
大家已經(jīng)習(xí)慣于微軟提供的功能強(qiáng)大的IDE,已經(jīng)很少考慮手動(dòng)編連項(xiàng)目了,所謂技多不壓身,有空的時(shí)候還是隨我一塊了解一下命令行編譯。
C/C++/VC++程序員或有Unix/Linux編程經(jīng)驗(yàn)應(yīng)該很熟悉,以前我曾寫過一篇文章描述用csc/vbc來進(jìn)行命令行編譯,今天再介紹一下MS提供的更加快捷有效的編譯工具NMake。
MSDN的描述: Microsoft 程序維護(hù)實(shí)用工具 (NMAKE.EXE) 是一個(gè) 32 位,基于說明文件中包含的命令生成項(xiàng)目的工具。
NMake具有豐富的選項(xiàng),可以完成復(fù)雜編譯操作。它可以辨別源代碼的改動(dòng),并選擇性的編譯,為你節(jié)省大量不必要的編譯時(shí)間。
使用NMAKE
語法:NMAKE [options] [macros] [targets] [@commandfile]
說明:其中,options是NMAKE的選項(xiàng),macros是在命令行中的宏定義,targets是NMAKE的目標(biāo)文件列表,commandfile是包含命令行輸入的文本文件(或響應(yīng)文件)。
NMAKE 使用指定 /F 選項(xiàng)的Makefile(生成文件,通常名字是makefile);如果未指定 /F 選項(xiàng),則使用當(dāng)前目錄下的Makefile。如果未指定Makefile,則 NMAKE 使用推理規(guī)則生成命令行 targets。
NMake本身很簡單,與NMAKE配合的是Makefile。Makefile的語法比較復(fù)雜,通常需要開發(fā)者自己手動(dòng)編寫Makefile,下一節(jié)我們?cè)敿?xì)講解Makefile。
上面的options和macros做了MSDN的鏈接,內(nèi)容較多,請(qǐng)自己查詢相關(guān)頁,可以從這里進(jìn)入NMake的MSDN幫助頁面,在線幫助點(diǎn)這里。
編寫MAKEFILE
注:本節(jié)內(nèi)容來自MSDN,熟悉此節(jié)的朋友可以直接跳過
Makefile的組成部分包括:成文件包含:
a.描述塊
描述塊是后面可跟有命令塊的依賴項(xiàng)行:
targets... : dependents... commands...
依賴項(xiàng)行指定一或多個(gè)目標(biāo)以及零或多個(gè)依賴項(xiàng)。目標(biāo)必須位于行首。用冒號(hào) (:) 將目標(biāo)和依賴項(xiàng)分開;允許使用空格或制表符。若要拆分行,請(qǐng)?jiān)谀繕?biāo)或依賴項(xiàng)后面使用反斜杠 (\ )。如果目標(biāo)不存在、目標(biāo)的時(shí)間戳比依賴項(xiàng)早或者目標(biāo)是偽目標(biāo),則 NMAKE 執(zhí)行命令。如果某依賴項(xiàng)是其他地方的目標(biāo),并且不存在或?qū)τ谧约旱囊蕾図?xiàng)已過期,則 NMAKE 在更新當(dāng)前依賴項(xiàng)之前更新該依賴項(xiàng)。
如果依賴項(xiàng)已過期,則描述塊或推理規(guī)則指定要運(yùn)行的命令塊。NMAKE 在運(yùn)行命令之前顯示每個(gè)命令,除非使用了 /S 選項(xiàng)、.SILENT、!CMDSWITCHES 或 @。如果描述塊后面沒有緊跟命令塊,NMAKE 將查找匹配的推理規(guī)則。
命令塊包含一個(gè)或多個(gè)命令,每個(gè)命令位于各自的命令行上。在依賴項(xiàng)(或規(guī)則)和命令塊之間不能出現(xiàn)空行。但是可以出現(xiàn)只包含空格或制表符的行;該行被解釋為空命令,并且不出現(xiàn)錯(cuò)誤。命令行之間允許有空行。
命令行以一個(gè)或多個(gè)空格或制表符開始。后面緊跟著換行符的反斜杠 ( \ ) 在命令中被解釋為空格;在行尾使用反斜杠繼續(xù)下一行命令。如果反斜杠后緊跟有其他任何字符(包括空格或制表符),則 NMAKE 按原義解釋反斜杠。
無論后面是否緊跟有命令塊,前面帶分號(hào) (;) 的命令可以出現(xiàn)在依賴項(xiàng)行上或推理規(guī)則中:
project.obj : project.c project.h ; cl /c project.c
c.宏
宏用另一個(gè)字符串替換生成文件中的特定字符串。使用宏可以:
- 創(chuàng)建可生成不同項(xiàng)目的生成文件。
- 指定命令選項(xiàng)。
- 設(shè)置環(huán)境變量。
可以定義您自己的宏或使用 NMAKE 的預(yù)定義宏。
d.推理規(guī)則
推理規(guī)則提供命令來更新目標(biāo)并推理目標(biāo)的依賴項(xiàng)。推理規(guī)則中的擴(kuò)展名與具有相同基名稱的單個(gè)目標(biāo)和依賴項(xiàng)匹配。推理規(guī)則是用戶定義的,或預(yù)定義的;預(yù)定義的規(guī)則可以重新定義。
如果過期的依賴項(xiàng)沒有命令,并且如果 .SUFFIXES 包含依賴項(xiàng)的擴(kuò)展名,則 NMAKE 使用其擴(kuò)展名與當(dāng)前或指定目錄中的目標(biāo)和現(xiàn)有文件匹配的規(guī)則。如果有多個(gè)規(guī)則與現(xiàn)有文件匹配,.SUFFIXES 列表將確定使用哪一個(gè)規(guī)則;列表優(yōu)先級(jí)從左向右按降序排列。如果依賴文件不存在,并且未在另一個(gè)描述塊中作為目標(biāo)列出,則推理規(guī)則可以從具有相同基名稱的另一個(gè)文件創(chuàng)建缺少的依賴項(xiàng)。如果描述塊的目標(biāo)沒有依賴項(xiàng)或命令,推理規(guī)則可以更新目標(biāo)。即使不存在描述塊,推理規(guī)則也可以生成命令行目標(biāo)。即使指定了顯式依賴項(xiàng),NMAKE 也可以調(diào)用推理依賴項(xiàng)的規(guī)則。
e.點(diǎn)指令
在描述塊之外的行首指定點(diǎn)指令。點(diǎn)指令以句點(diǎn) ( . ) 開始,后面跟一個(gè)冒號(hào) (:)。允許使用空格或制表符。點(diǎn)指令名區(qū)分大小寫并且應(yīng)為大寫。
指令 | 作用 |
---|---|
.IGNORE : | 忽略從指定該指令的位置到生成文件末尾之間,由命令返回的非零退出代碼。默認(rèn)情況下,如果命令返回非零退出代碼,NMAKE 將暫停。若要還原錯(cuò)誤檢查,請(qǐng)使用 !CMDSWITCHES。若要忽略單個(gè)命令的退出代碼,請(qǐng)使用短劃線 (-) 修飾符。若要忽略整個(gè)文件的退出代碼,請(qǐng)使用 /I 選項(xiàng)。 |
.PRECIOUS : targets | 若更新 targets 的命令暫停,則將 targets 保留在磁盤上;若命令通過刪除文件處理中斷,則該指令無效。用一或多個(gè)空格或制表符分隔目標(biāo)名稱。默認(rèn)情況下,如果通過使用 CTRL+C 或 CTRL+BREAK 組合鍵中斷生成,NMAKE 將刪除目標(biāo)。.PRECIOUS 的每一次使用都應(yīng)用于整個(gè)生成文件;多次指定是累計(jì)的。 |
.SILENT : | 取消從指定該指令的位置到生成文件末尾之間的已執(zhí)行命令的顯示。默認(rèn)情況下,NMAKE 顯示它調(diào)用的命令。若要還原回顯,請(qǐng)使用 !CMDSWITCHES。若要取消單個(gè)命令的回顯,請(qǐng)使用 @ 修飾符。若要取消整個(gè)文件的回顯,請(qǐng)使用 /S 選項(xiàng)。 |
.SUFFIXES : list | 列出推理規(guī)則匹配的擴(kuò)展名;預(yù)定義為:.exe .obj .asm .c .cpp .cxx .bas .cbl .for .pas .res .rc。 |
若要更改 .SUFFIXES 列表順序或指定新列表,請(qǐng)清除此列表并指定新的設(shè)置。若要清除此列表,請(qǐng)不要在冒號(hào)后指定擴(kuò)展名:
.SUFFIXES :
若要將其他后綴添加到列表的末尾,請(qǐng)指定
.SUFFIXES : suffixlist
其中 suffixlist 是附加后綴的列表,由一或多個(gè)空格或制表符分隔。若要查看 .SUFFIXES 的當(dāng)前設(shè)置,請(qǐng)運(yùn)行選項(xiàng)為 /P 的 NMAKE。
f.預(yù)處理指令
可以通過使用預(yù)處理指令和表達(dá)式控制 NMAKE 會(huì)話。預(yù)處理指令可以放置在生成文件或 Tools.ini 文件中。使用指令可以有條件地處理生成文件,顯示錯(cuò)誤信息,包括其他生成文件,取消定義宏以及打開或關(guān)閉某些選項(xiàng)。
Makefile示例
看了一堆理論,很累了吧?下面看一段簡單的MakeFile
# 宏定義 SOURCES=AssemblyInfo.cs \ Form1.cs \ Form2.cs \ Form3.cs \ HelloWorld.cs # 引用規(guī)則 # 目標(biāo): CLRProfiler.exe : $(SOURCES) #<--依賴項(xiàng) # 標(biāo)志 # 下面是命令 csc /t:winexe /out:HelloWorld.exe /r:System.Windows.Forms.dll $(SOURCES) clean: del HelloWorld.exe |
將上述代碼保存為Makefile(沒有后綴)放在你的項(xiàng)目文件夾下, 然后打開VS2003.NET命令行窗口,進(jìn)入項(xiàng)目夾所在路徑,打入NMake回車, ok
示例2
下面演示一下多個(gè)項(xiàng)目時(shí)的編譯,每個(gè)單獨(dú)的項(xiàng)目創(chuàng)建單獨(dú)的makefile,解決方案下放一個(gè)總的makefile
all: # 分別對(duì)項(xiàng)目進(jìn)行編譯 cd project1 nmake cd .. cd project2 nmake cd .. cd project3 nmake cd .. # 將編譯結(jié)果匯總到當(dāng)前路徑 copy project1\project1.dll copy project2\project2.dll copy project3\project3.exe clean: # 清除編譯結(jié)果 del project1.dll del project2.dll del project3.exe cd project1 nmake clean cd .. cd project2 nmake clean cd .. cd project3 nmake clean cd .. |
小節(jié)
本文簡單介紹了NMAKE的用法,并對(duì)Makefile的語法做了介紹。篇幅所限,既不能面面俱到,又不能深入剖析,只希望能夠讓更多人了解此工具。筆者也是剛剛接觸,經(jīng)驗(yàn)不多,還請(qǐng)各位網(wǎng)友多多拍磚!
附表(makefile中常用的幾個(gè)符號(hào))
符合 | 作用 |
---|---|
^ (caret) | 用于關(guān)閉某些字符所具有的特殊意義,使其只表示字面上的意義。例如:^#abc表示#abc這個(gè)字符串,而#abc則用于在makefile中加入注釋,#在這里為注釋標(biāo)志,就像C++中的//。另外,在一行的末尾加上^,可以使行尾的回車換行符成為字串的一部分。 |
# (number sign) | 注釋標(biāo)志,NMAKE會(huì)忽略所有從#開始到下一個(gè)換行符之間的所有文本。這里要注意的是:在command lines中不能存在注釋。因?yàn)閷?duì)于command lines,NMAKE是將其整行傳遞給OS的。通常對(duì)于command lines的注釋都是放在行與行之間。 |
\ (backslash) | 用于將兩行合并為一行。將其放在行尾,NMAKE就會(huì)將行尾的回車換行符解釋為空格(space)。 |
% (percent symbol) | 表示其后的字符串為一文件名。 |
( (left parentheses) | |
) (right parentheses) | |
{ | |
} | |
! (exclamation symbol) | 命令修飾符 |
@ (at sign) | 命令修飾符 |
- (hyphen) | |
: (colon) | 用于dependent lines和inference rules中,用于分隔target和dependent。 |
; (semicolon) | 如果對(duì)于一個(gè)dependent line只有一條命令,則可以將該命令放在dependent line的后面,二者之間用“;”分隔。 |
$ (dolor sign) | 用于調(diào)用宏 |