一直想对编译命令进行了解,正好看到两篇博客:Windows平台下Makefile学习笔记(一)和Windows平台下Makefile学习笔记(二)。感觉写的很基础,所以打算以之为参考自己作为入门资料学习学习。讲述的语法内容在此就不赘述了,大神的文章里已经解释过了,我只是写下自己的学习过程,期间也碰到一些问题,也作为以后一个标记,提醒自己。
Test1
Test.exe:main.obj
link /machine:x86 /subsystem:console /out:Test.exe main.obj kernel32.lib
main.obj:main.cpp main.h
cl -c -DWIN32 -D_DEBUG -DCONSOLE main.cpp
如果link命令后面不加main.obj会报lnk2001错误,编译没有错误
Test2 测试第一个target描述块
all:main.obj
link /machine:x86 /subsystem:console /out:Test.exe main.obj kernel32.lib
main.obj:main.cpp main.h
cl -c -DWIN32 -D_DEBUG -DCONSOLE main.cpp
Test3 测试copy等命令,如果命令没有执行说明写的有问题
all:main.obj
link /machine:x86 /subsystem:console /out:Test.exe main.obj kernel32.lib
if not exist ".\\release" mkdir release
copy test.exe .\release
main.obj:main.cpp main.h
cl -c -DWIN32 -D_DEBUG -DCONSOLE main.cpp
Test4 增加clean
all:main.obj
link /machine:x86 /nologo /subsystem:console /out:Test.exe main.obj kernel32.lib
if not exist ".\\release" mkdir release
copy test.exe .\release
echo no problem!
<span style="white-space: pre;"> </span>echo $@ 当前目标的全名
<span style="white-space:pre"> </span>echo $* 当前目标的路径和基名称
<span style="white-space:pre"> </span>echo $** 当前目标的所有依赖项
<span style="white-space:pre"> </span>echo $? 时间戳比当前目标的时间戳晚的所有依赖项
<span style="white-space:pre"> </span>echo $< 推理中用
main.obj:main.cpp main.h
cl -c -DWIN32 -D_DEBUG -DCONSOLE main.cpp
clean:
del *.obj
del *.ilk
del *.exe
if exist ".\\release" rd/s/q .\release
最后附上完整的例子,是摘自那两篇blog的,当然,为了方便,我做了些许修改
#设置编译标记,初始化为FALSE
CFGSET = FALSE
#定义debug版本的预处理器
CCDEBUG = -DWIN32 -D_DEBUG -D_CONSOLE
#定义release版本的预处理器
CCNODBG = -DWIN32 -D_NODEBUG -D_CONSOLE
!IFDEF debug
CC = $(CCDEBUG)
OUTDIR = .\Debug
CFGSET = TRUE
!ELSE IFDEF release
CC = $(CCNODBG)
OUTDIR = .\Release
CFGSET = TRUE
!ENDIF
!IF "$(CFGSET)" == "FALSE"
!MESSAGE Usage: nmake /f Makefile.vc [<config>] [<target>]
!MESSAGE
!MESSAGE where <config> is one of:
!MESSAGE - release=1 - build release version
!MESSAGE - debug=1 - build debug version
!MESSAGE
!MESSAGE <target> may be:
!MESSAGE - clean - clear output file
!MESSAGE
!MESSAGE
!ERROR please choose a valid configuration instead"
!ENDIF
all: $(OUTDIR) $(OUTDIR)\test.exe
$(OUTDIR):
if not exist "$(OUTDIR)" mkdir $(OUTDIR)
$(OUTDIR)\main.obj:main.cpp
cl -c $(CC) /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\" main.cpp
$(OUTDIR)\test.exe:$(OUTDIR)\main.obj
link /machine:x86 /INCREMENTAL:YES /NOLOGO /subsystem:console /out:$(OUTDIR)\test.exe $(OUTDIR)\main.obj kernel32.lib
clean:
if exist $(OUTDIR) del $(OUTDIR)\*.ilk
if exist $(OUTDIR) del $(OUTDIR)\*.obj
if exist $(OUTDIR) del $(OUTDIR)\*.exe
这样,一个简版的makefile就做好了。来说说自己遇到的问题:
自己测试的时候一直报定义的错误信息,开始始终不得解,后来发现是在命令行中输入命令时没有区分大小写导致的。比如nmake /f makefile debug=1,开始的时候原文用if else定义的是大写的。由于自己很少使用命令行,也没有注意大小写的区别,始终不能执行后面的代码,还以为是之前哪里的语法问题,专门看了下NMake参考(整理自MSDN).pdf文章介绍,很纠结的没找到问题,后来猜测才试出来。