1. 如果已經有vc6的dsp工程,可直接匯出nmake指令檔(.mak)
“Project - Export Makefile...”
nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Debug"
nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Debug" all
nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Release" clean
註:如果未指定/F選項,則使用目前的目錄下的Makefile
【nmake /?】 擷取更多協助! vc6:【D:\program files\Microsoft Visual Studio\VC98\Bin】
vs2008:【D:\program files\Microsoft Visual Studio 9.0\VC\bin】
2. vs的c++工程沒有提供匯出nmake指令檔的功能,我們只有藉助工具或手動編寫nmake指令檔了
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3. rc.exe 【將.rc資源文本轉變成.res二進位檔案】
/l 0x804 // 預設語言ID(十六進位數表示) 0x804:簡體中文 0x409:美國 更多...
/fo"nMakeTest.res" // 指定rc檔案輸出的res名稱
例:rc.exe /l 0x804 /fo"nMakeTest.res" /d "_DEBUG" /d "_AFXDLL" “nMakeTest.rc”
4. cl.exe 常見選項 【將.c,.cpp,.cxx編譯成obj檔案】
/I "../include" // 添加標頭檔尋找路徑
/D WIN32 // 先行編譯宏定義
/W3 // 設定3級警告層級
/Fp"nMakeTest.pch" // 指定先行編譯檔案名稱
/Yu"stdafx.h" // 在產生期間使用先行編譯標頭檔
/c // 編譯但不連結
/feMyTest // 編譯後,輸出MyTest.exe可執行檔
/LD // 建立動態連結程式庫
/LDd // 建立調試動態連結程式庫
/ML // 使用 libc.lib 建立單線程可執行檔
/MLd // 使用 libcd.lib 建立調試單線程可執行檔
/MT // 使用 libcmt.lib 建立多線程可執行檔
/MTd // 使用 libcmtd.lib 建立調試多線程可執行檔
/MD // 使用 msvcrt.lib/msvcrt.dll 建立多線程可執行檔
/MDd // 使用 msvcrtd.lib/msvcrtd.dll建立調試多線程可執行檔
/Z7 //產生與 C7.0相容的調試資訊
/Zd //產生行號
/Zi //產生完整的調試資訊
/link // 將/link後指定的選項傳遞給link.exe
// 預設情況下,cl.exe編譯完後,會自動調用link.exe進行串連,
// 所以直接用cl.exe編譯帶main函數的.c或.cpp後,會產生obj與exe檔案。
例:cl /c test1.cpp test2.cpp // 編譯test1.cpp,test2.cpp
例:cl *.cpp /MD /c /I"G:\Visual C++\VC98\PlatformSDK\Include"
5. link.exe常見選項 【將obj、lib、res連結成dll或exe等可執行檔】
/dll // 輸出dll檔案
-lib // 產生lib靜態庫檔案 例:link -lib *.obj /out:test.lib
/libpath:"..\PublicSDK\lib" // 指定外部lib尋找路徑
/subsystem:windows[console] // 指定子系統
/machine 指定目標平台{AM33|ARM|EBC|IA64|M32R|MIPS|SH3|SH3DSP|SH4|SH5|THUMB|X86|X64},等
/debug // 產生調試資訊
/pdb:"nMakeTest.pdb" // 重新命名產生的pdb檔案
/map:"nMakeTest.map" // 重新命名產生的map檔案
/out:"nMakeTest.exe" // 重新命名產生的exe檔案
/implib:"test.lib" // 產生名為test.lib的匯出庫
/entry:_DllMainCRTStartup@12 // 指定_DllMainCRTStartup函數dll的起始地址
例:link gdiplus.lib /subsystem:windows /out:test.exe file1.obj file2.lib file3.res // 產生名為test.exe的windows可執行程式
例:link gdiplus.lib /subsystem:console /out:test.exe *.obj file2.lib file3.res // 產生名為test.exe的控制台可執行程式
例:link gdiplus.lib /subsytem:windows /dll /out:test.dll /implib:test.lib /def:test.def *.obj file2.lib file3.res // 產生名為test.dll動態庫
例:link *.obj rc.res /LIBPATH:"G:\Visual C++\lib" /SUBSYSTEM:WINDOWS /MACHINE:X86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib OpenGL32.Lib
6. nmake指令說明
(1) 符號說明
# // 注釋符
^#abc // 表示#abc這個字串
\ // 串連符,用於將兩行合并為一行;在宏中,分多行寫時,一定要用"\"進行串連
% // 檔案說明符
@ // 命令修飾符;防止修飾的命令的結果,被列印出來
$ // 宏引用符
: // 依賴符號
?【*】 // 萬用字元支援
(2) 長檔名用雙引號引起來
例:ALL : nMakeTest.dll // 檔案名稱較短時,可不需要引號
例:ALL : "$(OUTDIR)\nMakeTest.exe" // 檔案名稱較長時,特別是路徑中有空格的情況,一定要用引號
(3) 包含子makefile檔案
include "./dll/makefile"
(4) 條件判斷 - 01
!IF "$(CFG)" == ""
CFG=nMakeTest - Win32 Debug
!MESSAGE No configuration specified. Defaulting to nMakeTest - Win32 Debug.
!ELSE
!MESSAGE Be specified.
!ENDIF
(5) 條件判斷 - 02 【!IFNDEF !IFDEF】
!IFNDEF PRIVATE_RUNTIMEMODE_DEBUG
RUNTIMEMODE_DEBUG = /MDd
!ELSE
RUNTIMEMODE_DEBUG = $(PRIVATE_RUNTIMEMODE_DEBUG)
!ENDIF
(6) 輸出訊息日誌
!MESSAGE Invalid configuration "$(CFG)" specified.
(7) 描述塊 - makefile的核心 【註:在依賴項(或規則)和命令塊之間不能出現空行,commands之前為一個tab字元】
targets... : dependences...
commands...
(8) ALL / CLEAN
OUTDIR=.\Release
INTDIR=.\Release
ALL : "$(OUTDIR)\nMakeTest.exe"
CLEAN :
-@erase "$(INTDIR)\nMakeTest.obj"
-@erase "$(INTDIR)\nMakeTest.pch"
-@erase "$(INTDIR)\nMakeTest.res"
-@erase "$(INTDIR)\nMakeTestDlg.obj"
-@erase "$(INTDIR)\StdAfx.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(OUTDIR)\nMakeTest.exe"
-@erase "$(OUTDIR)\nMakeTest.map"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
(9) 編譯
CPP=cl.exe
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)\nMakeTest.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
(10) 連結
LINK32=link.exe
LINK32_FLAGS=/nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\nMakeTest.pdb" /map:"$(INTDIR)\nMakeTest.map" /machine:I386 /out:"$(OUTDIR)\nMakeTest.exe"
LINK32_OBJS= \
"$(INTDIR)\nMakeTest.obj" \
"$(INTDIR)\nMakeTestDlg.obj" \
"$(INTDIR)\StdAfx.obj" \
"$(INTDIR)\nMakeTest.res"
"$(OUTDIR)\nMakeTest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
(11) 檔案依賴
SOURCE=.\nMakeTest.cpp
"$(INTDIR)\nMakeTest.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\nMakeTest.pch"
SOURCE=.\nMakeTest.rc
"$(INTDIR)\nMakeTest.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
(12) 先行編譯檔案
SOURCE=.\StdAfx.cpp
!IF "$(CFG)" == "nMakeTest - Win32 Release"
CPP_SWITCHES=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)\nMakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
"$(INTDIR)\StdAfx.obj""$(INTDIR)\nMakeTest.pch" : $(SOURCE) "$(INTDIR)"
$(CPP) @<<
$(CPP_SWITCHES) $(SOURCE)
<<
!ELSEIF "$(CFG)" == "nMakeTest - Win32 Debug"
CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)\nMakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
"$(INTDIR)\StdAfx.obj""$(INTDIR)\nMakeTest.pch" : $(SOURCE) "$(INTDIR)"
$(CPP) @<<
$(CPP_SWITCHES) $(SOURCE)
<<
!ENDIF
# 參考
1. http://msdn.microsoft.com/zh-cn/library/dd9y37ha(v=vs.80).aspx
2. http://c2.com/cgi/wiki?UsingNmake
3. http://zh.wikipedia.org/wiki/Make
4. cl.exe link.exe用法詳解
5. http://blog.codingnow.com/2008/09/replacement_of_ide_1.html
6. http://blog.codingnow.com/2008/09/replacement_of_ide_2
7. http://blog.codingnow.com/2008/09/replacement_of_ide_3
8. http://blog.codingnow.com/2008/09/replacement_of_ide_4