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的部分区别:
THE END!
来源:oschina
链接:https://my.oschina.net/u/4349518/blog/4479711