DATE: 2018.12.21
1、參考:
https://blog.csdn.net/bytxl/article/details/46315131
https://blog.csdn.net/mini92/article/details/77374577
https://www.cnblogs.com/kekec/archive/2013/04/21/3007277.html
https://blog.csdn.net/SoaringLee_fighting/article/details/85158835
https://cognitivewaves.wordpress.com/makefiles-windows/
https://cognitivewaves.wordpress.com/makefiles/
2、前言
前面講述過Windows下gnu makefile的編寫以及對應編譯方法(參考:GnuWin32使用以及windows下gnu makefile編寫),本文講述的是Windows下符合Nmake編譯規則的VC makefile.vc的編寫方法,由於nmake和gmake兩者存在不同,造成這兩種makefile之間句法存在差異,主要是預處理宏、內置宏和變量使用方面的差異。
3、Nmake基本語法
3.1、Nmake簡介
Nmake同GNU make類似,屬於make的變種,是一種用於自動化編譯的工具,Nmake通過解析makefile來實現自動化編譯,在makefile中定義了編譯規則,並且通過推導規則實現選擇性編譯,節省編譯時間。
MSDN的描述: Microsoft 程序維護實用工具 (NMAKE.EXE) 是一個 32 位,基於說明文件中包含的命令生成項目的工具。
語法:
NMAKE [options] [macros] [targets] [@commandfile]
說明:其中,options是NMAKE的選項,macros是在命令行中的宏定義,targets是NMAKE的目標文件列表,commandfile是包含命令行輸入的文本文件(或響應文件)。
選項options:
/A Build all evaluated targets
/B Build if time stamps are equal
/C Suppress output messages
/D Display build information
/E Override env-var macros
/HELP Display brief usage message
/I Ignore exit codes from commands
/K Build unrelated targets on error
/N Display commands but do not execute
/NOLOGO Suppress copyright message
/P Display NMAKE information
/Q Check time stamps but do not build
/R Ignore predefined rules/macros
/S Suppress executed-commands display
/T Change time stamps but do not build
/U Dump inline files
/Y Disable batch-mode
/? Display brief usage message
3.2、Nmake基本語法
當用戶輸入nmake命令后,首先nmake會讀取makefile,然后解析makefile,並根據makefile的規則來確定要編譯哪些代碼。然后nmake會調用編譯器、鏈接器等一些開發工具,完成對代碼的編譯鏈接。最終會生成可執行文件。
(1)描述塊(推導規則)
targets... : dependents...
commands...
nmake的描述塊的規則和用法同gmake的推導規則,targets也就是一個目標文件,可以是Object File,也可以是可執行文件。還可以是一個標簽(Label)。targets必須在一行的頂格寫,前面不能有空格。
dependents就是要生成target所需要的文件或是目標依賴項。dependents與targets之間用冒號間隔。一個targets可以有多個dependents。
command也就是NMake需要執行的命令。其中commands可以是任意的Windows命令行命令。
這是一個文件的依賴關系,也就是說,target這一個或多個的目標文件依賴於dependents中的文件,其生成規則定義在command中。也就是說,dependents中如果有一個以上的文件比targets文件要新的話,command所定義的命令就會被執行。這就是makefile的規則。也就是Makefile中最核心的內容。
更多可參考:https://docs.microsoft.com/en-us/cpp/build/inference-rules?view=vs-2017
(2)使用變量
CC=cl.exe
LINK=link.exe
LIB=lib.exe
注意:
- 在nmake格式的makefile中$(CC)和$(CPP)屬於內置宏,默認值為cl。
- 不支持gnu make中的立即賦值:=,追加賦值+=和條件賦值?=的變量賦值方式。
- nmake中的自動變量使用不同於gnu make。
(3)使用預處理
預處理指令以“!”開頭,必須出現在每行的最開始。最常用的預處理指令是條件處理。
條件處理:
Nmake支持如下的條件預處理指令:
!IF
!IFDEF
!IFNDEF
!ELSE
!ELSEIF
!ELSEIFDEF
!ELSEIFNDEF
!ENDIF
文件包含:
! INCLUDE [<] 文件名 [>]
顯示錯誤信息:
!MESSAGE <內容>
!ERROR message
參考網址:http://www.cnblogs.com/end/articles/698432.html
更多知識可參考MSDN:https://docs.microsoft.com/en-us/cpp/build/nmake-reference?view=vs-2017
4、Windows下VC makefile.vc編寫demo
簡單demo1:
#宏定義
EXE = test.exe #指定輸出文件名
OBJS = main.obj #需要的目標文件
RES = #需要的資源文件
LINK_FLAG = /DEBUG /subsystem:console #連接選項;啟用DEBUG模式;使用控制台。
CL_FLAG = /EHsc /c /Zi /Tp #編譯選項,選了部分必要的CL選項
#顯式規則
$(EXE): $(OBJS) $(RES)
link $(LINK_FLAG) $(OBJS) $(RES) $(LIBS) /OUT:$(EXE)
#隱含規則
.cpp.obj:
cl $(CL_FLAG) $<
.rc.res:
rc $<
#清臨時文件
clean:
del *.obj
del *.exe
# del *.res
簡單Demo2:
引用自:https://docs.microsoft.com/en-us/cpp/build/sample-makefile?view=vs-2017
# Sample makefile
!include <win32.mak>
all: simple.exe challeng.exe
.c.obj:
$(cc) $(cdebug) $(cflags) $(cvars) $*.c
simple.exe: simple.obj
$(link) $(ldebug) $(conflags) -out:simple.exe simple.obj $(conlibs) lsapi32.lib
challeng.exe: challeng.obj md4c.obj
$(link) $(ldebug) $(conflags) -out:challeng.exe $** $(conlibs) lsapi32.lib
Linux makefile與Windows VC makefile的部分區別: