在windows里写NMake makefile,编译时遇到的cl.exe command line : error D8003 missing source filename(缺少源文件名)

       想直接寻找答案的可跳过NMake makefile预备知识。

NMake makefile预备知识

        虽然在windows下使用VS开发已经好几年了,一直使用的VS可视化工具开发,从来没有写过makefile。现在因为公司项目需要和自身的发展需要,逐渐要进行跨平台开发了。因为这段时间正在研究Delaunay Triangulation,这几周准备自己动手实现这个算法。昨天写了一个欧几里得相关的数学方法,主要是判断一个顶点是否在指定的三角形内,一个顶点是否在制定的三角形的外接圆内,还有判断顶点是否在某条线段上和以某条线段为直径此条线段中点为圆心的园内,程序文件时euclideantools.h和euclideantools.cpp(这里欧几里得的相关函数我并没有作为lib输出),在源文件中因为要用到线性代数中点和向量的相关运算,所以我需要链接一个线性代数的运算库GTMath.lib;然偶我写了一个测试这个欧几里得的数学方法的程序test.cpp,也就是test.cpp是整个工程的main函数入口。

       代码都实现了之后,我决定编写NMake makefile在windows下来编译这个工程。在参照网上的一些对makefile的介绍我就开始写makefile语句了。在编译的过程中遇到了相当多的问题,我在网上找了很多的资料,都没有一个明确的答案来解释这些错误(可能是很多人都没有遇到过这个问题),下面我把我的理解和解决办法记录下来,希望以后有跟我一样不了解NMake makefile时遇到了这个问题可以快速解决。

        首先编译NMake makefile文件是使用VS中的cl.exe和link.exe。VS编译工程分为两步,第一步是compiler(编译),使用cl.exe,将工程源文件生成中间文件.obj;第二步是linker(链接),使用link.exe,将由编译阶段生成的中间文件.obj链接生成目标文件dll/lib/exe,其中工程中引用的外部的lib库也是在链接阶段进行链接的。

        要编译NMake makefile,可使用VS的工具命令提示(tool command promt),在开始-所有程序-VS的目录下的一个Visual stuido tools目录里可以打开,也可以直接打开cmd.exe,然后执行VS的安装目录下-vc文件夹-vcvarsall.bat,然后用法就跟工具命令提示一样用了:定位到要编译的NMake makefile目录下,输入命令:

nmake [/FILE makefilename]
假如要编译的makefile文件名称就是"makefile",那么上面命令中括号中的语句可以省略,直接输入"nmake"就可以编译连接了! (在这个过程中可能会遇到一个问题,就是在定位到要编译的NMake makefile目录是可能会出现的:在打开VS的工具命令提示或者cmd.exe后,如果窗口显示的当前的目录是"C:/some direction",makefile的路径为"D:/program",那么 直接输入命令"cd d:/program"可能并不能直接定位到makefie的路径下,这时候需要先输入"D:",先到D的盘符目录下,然后再输入"cd program"定位到"D:/program")。
        已经知道如何编译NMake makefile后,那么现在所关心的问题就是makefile命令的书写了。makefile的书写格式是这样的:

target file : dependence file1 [dependence2 ....]
	command line
其中command line必须与抬头相隔至少1个tab空间。具体的一些规则可见: Guide:Makefiles

cl.exe command line : error D8003 missing source filename(缺少源文件)

       最开始我的makefile的内容是这样的:

CC = cl
CFLAGS = -I/dlltools/include /link -LIBPATH:/dlltools/lib GTMath.lib
test.exe : test.obj euclideantools.obj
	$(CC) $(CFLAGS) test.obj

test.obj : test.cpp
	$(CC) $(CFLAGS) test.cpp

euclideantools.obj : euclideantools.cpp
	$(CC) $(CFLAGS) euclideantools.cpp
       使用"nmake"命令编译时,出现错误:

        cl -I/dlltools/include /link -LIBPATH:/dlltools/lib GTMath.lib test.obj
euclideantools.obj
用于 x86 的 Microsoft (R) C/C++ 优化编译器 18.00.21005.1 版版权所有(C) Microsoft
 Corporation。  保留所有权利。

cl: 命令行 error D8003 :缺少源文件名
       现在我来分析下出现这个错误的原因,在这写命令行中, 我开头都是使用的cl,最开始的cl就已经指明了后面应该跟的是c/c++编译选项(可参照vs工程属性中c/c++编译选项设置),而在这条语句中cl后面跟的是linker的编译选项(可参照vs工程属性中linker编译选项设置),所以cl.exe一直会报缺少源文件名的错误。那么知道这个错误之后,我们应该很清楚,编译阶段和链接阶段应该是分开来的:

test.obj : test.cpp
	$(CC) $(CFLAGS) test.cpp

这个链接阶段的,应该是用link;下面的是编译阶段,应该使用cl,而且在以cl开头的命令行中不应该出现包含link的编译选项,如果包含了link的编译选项,那么就意味着cl开头的命令到有link标识的部分是cl的编译选项而且,而这段命令中并没有要编译的源文件,所以cl.exe会报error D8003:
test.obj : test.cpp
	$(CC) $(CFLAGS) test.cpp

euclideantools.obj : euclideantools.cpp
	$(CC) $(CFLAGS) euclideantools.cpp
拿命令行:“$(CC) $(CFLAGS) test.cpp”来分析,将其展开就是"cl -I/dlltools/include /link -LIBPATH:/dlltools/lib GTMath.lib test.cpp",这段命令行中属于c/c++编译选项的是:“cl -I/dlltools/include”,而后面则属于链接的编译选项的:“/link -LIBPATH:/dlltools/lib GTMath.lib test.cpp”,所以cl.exe找不到要编译的源文件。知道了这个原因后,我讲makefile改写成这样:
CC = cl
LINK = link
LINKFLAGS = -LIBPATH:/dlltools/lib GTMath.lib
CPPFLAGS = -I/dlltools/include

euclideantools.exe : test.obj euclideantools.obj
	$(LINK) $(LINKFLAGS) test.obj euclideantools.obj
	
test.obj : test.cpp
	$(CC) $(CPPFLAGS) /c test.cpp
	
euclideantools.obj : euclideantools.cpp
	$(CC) $(CPPFLAGS) /c euclideantools.cpp
	
clean:
	del *.obj, *.exe
编译成功!

  • 可参考的资料:Compilingwith VC++ from the command line
  • 收藏资料(以后用得到):CSDN: 分享NMake模板,全自动化的makefile

你可能感兴趣的:(cross-platform,development)