最近在做CUDA在Qt中的混合编程,于是需要修改pro文件,添加一个额外编译器NVCC,来实现。
修改完pro文件,qmake,然后Debug,一切好像理所应当的样子,然后报错
LNK1181:无法打开输入文件"debug\test.obj"
啪的一下,快乐没了。没有办法,查问题,花了一两天的时间,才查清楚。
一、排查
首先看这一段pro文件中的配置项:
# Debug 模式
OBJECTS_DIR = debug/obj
CUDA_OBJECTS_DIR = debug
cuda_d.input = CUDA_SOURCES
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}.obj \ #输出目录
cuda_d.commands = $$CUDA_DIR/bin/nvcc.exe -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$LIBS \
--machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH \
--compile -cudart static -g -DWIN32 -D_MBCS \
-Xcompiler "/wd4819,/EHsc,/W3,/nologo,/Od,/Zi,/RTC1" \
-Xcompiler $$MSVCRT_LINK_FLAG_DEBUG \
-c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
cuda_d.dependency_type = TYPE_C
QMAKE_EXTRA_COMPILERS += cuda_d
仔细的人可能已经发现问题了。但是乍一看确实很难发现问题。先不说问题出在哪儿,来跟着我一步步反推。
- 首先,打开编译结果文件目录,会发现,导致这个问题出现的原因是这个obj文件并没有生成,自然也就无法打开。
- 没有生成obj文件的原因,打开Makefile.Debug,会发现这里面压根没有任何关于NVCC编译器的相关内容,意思是没有qmake成功。
- 遇事不决问百度,其实有很多人的答案已经很接近我的问题了,但是一时之间没有意识到。没错,问题还是处在“\”这个符号上。仔细看上面的配置内容,会发现,在
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}.obj \ #输出目录
中,在obj和#之间,有一个“\”符号。之前我一直认为这个放在末尾,不会影响配置项,现在看来,还是会有影响的。
二、分析
在pro文件中,“\”代表着换行,即当一行写不下,准备写两行时,需要在第一行最后添加一个“\”,同理可得的是,一旦有了这个“\”符号,就代表着后面还有内容,即便你什么都没写,qmake时也会认为这里有个配置项,只不过其内容为空而已,但是一旦配置为空,可能就会导致这个配置项失效。
就比如上述这句语句,cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}.obj \ #输出目录
。qmake就因为认为多了个空格,而不是配置成功,因此就相当于没有配置输出地址,那自然就无法输出。
三、解决
将此行代码做修改。
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}.obj \ #输出目录
去掉“\”。
cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}.obj #输出目录
四、总结
- 在pro文件中使用“\”符号务必慎重。
- 情况1,在配置内容中间,应该换行的地方,本来应该是一个“\”,手误多写了一个或者几个,比如“\”,一个道理,也是多出一个空白配置项,所以出错。
- 情况2,在配置内容末尾,多了“\”内容,也会报错,不允许有。
- 情况3,正常情况
则不会报错。FORMS += \ mainwindow.ui
- 总之,任何地方不要乱加“\”,养成良好的代码习惯。