makefile教程---nmake命令編譯器的使用
簡介
大家已經習慣於微軟提供的功能強大的IDE,已經很少考慮手動編連專案了,所謂技多不壓身,有空的時候還是隨我一塊瞭解一下命令列編譯。
C/C++/VC++程式設計師或有Unix/Linux程式設計經驗應該很熟悉,以前我曾寫過一篇文章描述用csc/vbc來進行命令列編譯,今天再介紹一下MS提供的更加快捷有效的編譯工具NMake。
MSDN的描述: Microsoft 程式維護實用工具 (NMAKE.EXE) 是一個 32 位,基於說明檔案中包含的命令生成專案的工具。
NMake具有豐富的選項,可以完成複雜編譯操作。它可以辨別原始碼的改動,並選擇性的編譯,為你節省大量不必要的編譯時間。
使用NMAKE
語法:NMAKE [options] [macros] [targets] [@commandfile]
說明:其中,options是NMAKE的選項,macros是在命令列中的巨集定義,targets是NMAKE的目標檔案列表,commandfile是包含命令列輸入的文字檔案(或響應檔案)。
NMAKE 使用指定 /F 選項的Makefile(生成檔案,通常名字是makefile);如果未指定 /F 選項,則使用當前目錄下的Makefile。如果未指定Makefile,則 NMAKE 使用推理規則生成命令列 targets。
NMake本身很簡單,與NMAKE配合的是Makefile。Makefile的語法比較複雜,通常需要開發者自己手動編寫Makefile,下一節我們詳細講解Makefile。
上面的options和macros做了MSDN的連結,內容較多,請自己查詢相關頁,可以從這裡進入NMake的MSDN幫助頁面,線上幫助點這裡。
編寫MAKEFILE
注:本節內容來自MSDN,熟悉此節的朋友可以直接跳過
Makefile的組成部分包括:成檔案包含:
a.描述塊
描述塊是後面可跟有命令塊的依賴項行:
targets... : dependents...
commands...
依賴項行指定一或多個目標以及零或多個依賴項。目標必須位於行首。用冒號 (:) 將目標和依賴項分開;允許使用空格或製表符。若要拆分行,請在目標或依賴項後面使用反斜槓 (\ )。如果目標不存在、目標的時間戳比依賴項早或者目標是偽目標,則 NMAKE 執行命令。如果某依賴項是其他地方的目標,並且不存在或對於自己的依賴項已過期,則 NMAKE 在更新當前依賴項之前更新該依賴項。
如果依賴項已過期,則描述塊或推理規則指定要執行的命令塊。NMAKE 在執行命令之前顯示每個命令,除非使用了 /S 選項、.SILENT、!CMDSWITCHES 或 @。如果描述塊後面沒有緊跟命令塊,NMAKE 將查詢匹配的推理規則。
命令塊包含一個或多個命令,每個命令位於各自的命令列上。在依賴項(或規則)和命令塊之間不能出現空行。但是可以出現只包含空格或製表符的行;該行被解釋為空命令,並且不出現錯誤。命令列之間允許有空行。
命令列以一個或多個空格或製表符開始。後面緊跟著換行符的反斜槓 ( \ ) 在命令中被解釋為空格;在行尾使用反斜槓繼續下一行命令。如果反斜槓後緊跟有其他任何字元(包括空格或製表符),則 NMAKE 按原義解釋反斜槓。
無論後面是否緊跟有命令塊,前面帶分號 (;) 的命令可以出現在依賴項行上或推理規則中:
project.obj : project.c project.h ; cl /c project.c
c.巨集
巨集用另一個字串替換生成檔案中的特定字串。使用巨集可以:
- 建立可生成不同專案的生成檔案。
- 指定命令選項。
- 設定環境變數。
可以定義您自己的巨集或使用 NMAKE 的預定義巨集。
d.推理規則
推理規則提供命令來更新目標並推理目標的依賴項。推理規則中的副檔名與具有相同基名稱的單個目標和依賴項匹配。推理規則是使用者定義的,或預定義的;預定義的規則可以重新定義。
如果過期的依賴項沒有命令,並且如果 .SUFFIXES 包含依賴項的副檔名,則 NMAKE 使用其副檔名與當前或指定目錄中的目標和現有檔案匹配的規則。如果有多個規則與現有檔案匹配,.SUFFIXES 列表將確定使用哪一個規則;列表優先順序從左向右按降序排列。如果依賴檔案不存在,並且未在另一個描述塊中作為目標列出,則推理規則可以從具有相同基名稱的另一個檔案建立缺少的依賴項。如果描述塊的目標沒有依賴項或命令,推理規則可以更新目標。即使不存在描述塊,推理規則也可以生成命令列目標。即使指定了顯式依賴項,NMAKE 也可以呼叫推理依賴項的規則。
e.點指令
在描述塊之外的行首指定點指令。點指令以句點 ( . ) 開始,後面跟一個冒號 (:)。允許使用空格或製表符。點指令名區分大小寫並且應為大寫。
指令 | 作用 |
---|---|
.IGNORE : | 忽略從指定該指令的位置到生成檔案末尾之間,由命令返回的非零退出程式碼。預設情況下,如果命令返回非零退出程式碼,NMAKE 將暫停。若要還原錯誤檢查,請使用 !CMDSWITCHES。若要忽略單個命令的退出程式碼,請使用短劃線 (-) 修飾符。若要忽略整個檔案的退出程式碼,請使用 /I 選項。 |
.PRECIOUS : targets | 若更新 targets 的命令暫停,則將 targets 保留在磁碟上;若命令通過刪除檔案處理中斷,則該指令無效。用一或多個空格或製表符分隔目標名稱。預設情況下,如果通過使用 CTRL+C 或 CTRL+BREAK 組合鍵中斷生成,NMAKE 將刪除目標。.PRECIOUS 的每一次使用都應用於整個生成檔案;多次指定是累計的。 |
.SILENT : | 取消從指定該指令的位置到生成檔案末尾之間的已執行命令的顯示。預設情況下,NMAKE 顯示它呼叫的命令。若要還原回顯,請使用!CMDSWITCHES。若要取消單個命令的回顯,請使用 @ 修飾符。若要取消整個檔案的回顯,請使用 /S 選項。 |
.SUFFIXES : list | 列出推理規則匹配的副檔名;預定義為:.exe .obj .asm .c .cpp .cxx .bas .cbl .for .pas .res .rc。 |
若要更改 .SUFFIXES 列表順序或指定新列表,請清除此列表並指定新的設定。若要清除此列表,請不要在冒號後指定副檔名:
.SUFFIXES :
若要將其他字尾新增到列表的末尾,請指定
.SUFFIXES : suffixlist
其中 suffixlist 是附加字尾的列表,由一或多個空格或製表符分隔。若要檢視 .SUFFIXES 的當前設定,請執行選項為 /P 的 NMAKE。
f.預處理指令
可以通過使用預處理指令和表示式控制 NMAKE 會話。預處理指令可以放置在生成檔案或 Tools.ini 檔案中。使用指令可以有條件地處理生成檔案,顯示錯誤資訊,包括其他生成檔案,取消定義巨集以及開啟或關閉某些選項。
Makefile示例
看了一堆理論,很累了吧?下面看一段簡單的MakeFile
# 巨集定義 SOURCES=AssemblyInfo.cs \ Form1.cs \ Form2.cs \ Form3.cs \ HelloWorld.cs # 引用規則 # 目標: CLRProfiler.exe : $(SOURCES) #<--依賴項 # 標誌 # 下面是命令 csc /t:winexe /out:HelloWorld.exe /r:System.Windows.Forms.dll $(SOURCES) clean: del HelloWorld.exe |
將上述程式碼儲存為Makefile(沒有字尾)放在你的專案資料夾下, 然後開啟VS2003.NET命令列視窗,進入專案夾所在路徑,打入NMake回車, ok
示例2
下面演示一下多個專案時的編譯,每個單獨的專案建立單獨的makefile,解決方案下放一個總的makefile
all: # 分別對專案進行編譯 cd project1 nmake cd .. cd project2 nmake cd .. cd project3 nmake cd .. # 將編譯結果彙總到當前路徑 copy project1\project1.dll copy project2\project2.dll copy project3\project3.exe clean: # 清除編譯結果 del project1.dll del project2.dll del project3.exe cd project1 nmake clean cd .. cd project2 nmake clean cd .. cd project3 nmake clean cd .. |
小節
本文簡單介紹了NMAKE的用法,並對Makefile的語法做了介紹。篇幅所限,既不能面面俱到,又不能深入剖析,只希望能夠讓更多人瞭解此工具。筆者也是剛剛接觸,經驗不多,還請各位網友多多拍磚!
附表(makefile中常用的幾個符號)
符合 | 作用 |
---|---|
^ (caret) | 用於關閉某些字元所具有的特殊意義,使其只表示字面上的意義。例如:^#abc表示#abc這個字串,而#abc則用於在makefile中加入註釋,#在這裡為註釋標誌,就像C++中的//。另外,在一行的末尾加上^,可以使行尾的回車換行符成為字串的一部分。 |
# (number sign) | 註釋標誌,NMAKE會忽略所有從#開始到下一個換行符之間的所有文字。這裡要注意的是:在command lines中不能存在註釋。因為對於command lines,NMAKE是將其整行傳遞給OS的。通常對於command lines的註釋都是放在行與行之間。 |
\ (backslash) | 用於將兩行合併為一行。將其放在行尾,NMAKE就會將行尾的回車換行符解釋為空格(space)。 |
% (percent symbol) | 表示其後的字串為一檔名。 |
( (left parentheses) | |
) (right parentheses) | |
{ | |
} | |
! (exclamation symbol) | 命令修飾符 |
@ (at sign) | 命令修飾符 |
- (hyphen) | |
: (colon) | 用於dependent lines和inference rules中,用於分隔target和dependent。 |
; (semicolon) | 如果對於一個dependent line只有一條命令,則可以將該命令放在dependent line的後面,二者之間用“;”分隔。 |
$ (dolor sign) | 用於呼叫巨集 |
相關文章
- 使用makefile編譯編譯
- 使用makefile編譯c程式編譯C程式
- 編譯器有關的Makefile語法編譯
- makefile檔案及VC++自帶的NmakeC++
- 如何在Windows下使用make編譯MakefileWindows編譯
- 在命令列下使用vs的編譯器命令列編譯
- C編譯: makefile基礎編譯
- C 編譯: makefile 基礎編譯
- 前端工具 | JS編譯器Monaco使用教程前端JS編譯
- Makefile使用教程1
- GCC編譯器的使用GC編譯
- 如何用在命令列下使用VS編譯器命令列編譯
- Android Makefile 編譯過程分析Android編譯
- 在Ubuntu環境下用gcc命令執行c程式以及Makefile編譯UbuntuGCC程式編譯
- 配置C#命令列編譯器C#命令列編譯
- # Xcode 編譯器除錯命令(所有)XCode編譯除錯
- 使用C編譯器編寫shellcode編譯
- 編譯器的編譯基本過程編譯
- 用命令編譯編譯
- Rust 編譯器探索使用 PGORust編譯Go
- cmake使用教程(九)-關於安卓的交叉編譯安卓編譯
- GNU工程管理器make與Makefile教程
- Openwrt編譯教程編譯
- gcc 編譯器與 clang 編譯器GC編譯
- 使用CMake命令編譯Android平臺下的包編譯Android
- 【譯】使用 Python 編寫虛擬機器直譯器Python虛擬機
- 富文字編譯器UEditor+SSM的使用編譯SSM
- 編寫VCS執行使用的makefile遇到的問題
- Maven命令列使用:mvn clean compile(編譯)Maven命令列Compile編譯
- clang++編譯命令編譯
- 淺談彙編器、編譯器和直譯器編譯
- [譯]iOS編譯器iOS編譯
- makefile 簡明教程
- 編譯器的自展和自舉、交叉編譯編譯
- FreeBSD中的GNU C編譯器--編譯器GCC(轉)編譯GC
- android編譯系統makefile(Android.mk)寫法Android編譯
- Java編譯和執行的命令Java編譯
- Linux下使用make命令編譯c原始檔Linux編譯