CUDA、Win7、Qt Creator - LNK1104:无法打开文件“<cuda 文件>.obj”

Posted

技术标签:

【中文标题】CUDA、Win7、Qt Creator - LNK1104:无法打开文件“<cuda 文件>.obj”【英文标题】:CUDA, Win7, Qt Creator - LNK1104: cannot open file '<cuda file>.obj' 【发布时间】:2015-08-28 20:21:08 【问题描述】:

我正在尝试将 CUDA 与 Qt Creator、Win7 和 VS2012 编译器一起使用。我有在 Windows 上使用 Qt 的经验,但未能成功设置将 CUDA 代码集成到 Qt 项目中。我尝试了几个发布的解决方案(例如Compiling Cuda code in Qt Creator on Windows),但都没有成功。我最终决定简化并将我的代码基于这篇博文:https://cudaspace.wordpress.com/2012/07/05/qt-creator-cuda-linux-review/,但仍然遇到问题。

目前,我收到错误“LNK1104: cannot open file 'obj\cuda_code.obj'

我的 .pro 文件是:

QT       += core
QT       -= gui

TARGET = QtCuda
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app

SOURCES += main.cpp \
           cuda_code.cu

# project build directories
DESTDIR     = $$PWD
OBJECTS_DIR = $$DESTDIR/obj

# C++ flags
QMAKE_CXXFLAGS_RELEASE =-O3

# Cuda sources
CUDA_SOURCES += cuda_code.cu

# Path to cuda toolkit install
CUDA_DIR      = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v7.0"

# Path to header and libs files
INCLUDEPATH  += $$CUDA_DIR/include
QMAKE_LIBDIR += $$CUDA_DIR/lib/x64

# libs used in your code
LIBS += -lcudart -lcuda

# GPU architecture
CUDA_ARCH     = sm_50 

# Here are some NVCC flags I've always used by default.
NVCCFLAGS     = --compiler-options -use_fast_math


# Prepare the extra compiler configuration (taken from the nvidia forum - i'm not an expert in this part)
CUDA_INC = $$join(INCLUDEPATH,' -I','-I',' ')

cuda.commands = $$CUDA_DIR/bin/nvcc -m64 -O3 -arch=$$CUDA_ARCH -c $$NVCCFLAGS \
                $$CUDA_INC $$LIBS  $QMAKE_FILE_NAME -o $QMAKE_FILE_OUT \
                2>&1 | sed -r \"s/\\(([0-9]+)\\)/:\\1/g\" 1>&2

cuda.dependency_type = TYPE_C

cuda.depend_command = $$CUDA_DIR/bin/nvcc -O3 -M $$CUDA_INC $$NVCCFLAGS   $QMAKE_FILE_NAME

cuda.input = $$CUDA_SOURCES

cuda.output = $$OBJECTS_DIR/$QMAKE_FILE_BASE_cuda.obj

# Tell Qt that we want add more stuff to the Makefile
QMAKE_EXTRA_COMPILERS += cuda

我的 main.cpp

#include <QtCore/QCoreApplication>
#include <iostream>
using namespace std;

#include <cuda_runtime.h>

extern "C"
cudaError_t cuda_main();

int main(int argc, char *argv[])

    QCoreApplication a(argc, argv);

    cudaError_t cuerr = cuda_main();

    if (cuerr != cudaSuccess) cout << "CUDA Error: " << cudaGetErrorString( cuerr ) << endl;

    return a.exec();

我的 cuda 文件 (cuda_code.cu):

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
extern "C"
cudaError_t cuda_main()

    // generate 16M random numbers on the host
    thrust::host_vector<int> h_vec(1 << 24);
    thrust::generate(h_vec.begin(), h_vec.end(), rand);

    // transfer data to the device
    thrust::device_vector<int> d_vec = h_vec;

    // sort data on the device (805 Mkeys/sec on GeForce GTX 480)
    thrust::sort(d_vec.begin(), d_vec.end());

    // transfer data back to host
    thrust::copy(d_vec.begin(), d_vec.end(), h_vec.begin());

    return cudaGetLastError();

【问题讨论】:

有没有办法可以将makefile发出的编译命令的副本贴出来? 我假设您指的是 makefile 中的任何“nvcc”命令行?如果是这样,我只是搜索了我的 makefile 并没有发现对 nvcc 的引用。如果有帮助的话,我可以将整个 makefile 发布在共享站点上,但我现在猜测由于某种原因没有调用 nvcc ???如果我不在基地,请告诉我。谢谢。 如果您看不到任何 nvcc 调用,那么问题显然是对象永远不会被编译(而不是被编译但具有不同的名称或位于不同的位置)。所以解决方案是首先解决这个问题,但你如何做到这一点实际上是一个 qmake 问题,而不是与 CUDA 本身有任何关系 你说得对。看起来我的 qmake 项目文件有问题。我现在调用了 nvcc,但现在它正在寻找“C:\Program.obj”。奇怪的。如果您有兴趣,这里是我的 make 文件中的 nvcc 命令:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\bin\nvcc.exe" -D_DEBUG -I"C:/Program Files /NVIDIA GPU 计算工具包/CUDA/v7.0/include" -lcuda -lcudart --machine 64 -arch=sm_50 -c -o obj\cuda_code.obj cuda_code.cu 在上面添加了一个似乎已解决问题的编辑。 【参考方案1】:

通过进行以下更改,OP 能够获得成功的编译链接:

1) 在.pro文件中,添加

MSVCRT_LINK_FLAG_DEBUG = "/MDd"

MSVCRT_LINK_FLAG_RELEASE = "/MD"

连同(到 cuda.command 语句) -Xcompiler $$MSVCRT_LINK_FLAG_DEBUG -或- -Xcompiler $$MSVCRT_LINK_FLAG_RELEASE

如中所述: Compile cuda file error: "runtime library" mismatch value 'MDd_DynamicDebug' doesn't match value 'MTd_StaticDebug' in vectorAddition_cuda.o

2) makefile 中还有一个非常奇怪的细节,我必须手动修复。我希望有一个真正的解决方案,但我一直无法弄清楚。

在 makefile 的顶部,有几个定义,包括一个用于 LIBS 的定义。在仔细检查了这个定义后,我发现在库位置的规范中多了一组引号。像这样:

LIBS          = /LIBPATH:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64" ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64"\cuda.lib" ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64"\cudart.lib" /LIBPATH:C:\Qt\5.2.1\msvc2012_64_opengl\lib C:\Qt\5.2.1\msvc2012_64_opengl\lib\Qt5Cored.lib 

如果您仔细观察,您可以在 cuda.lib 和 cudart.lib 的位置看到额外的引号集。我不知道是什么原因造成的(可能是我的 .pro 文件中的某些东西),但如果我手动删除了额外的引号,编译/链接就可以工作了。这是 makefile 中更正后的行:

LIBS          = /LIBPATH:"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64" "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64\cuda.lib" "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.0\lib\x64\cudart.lib" /LIBPATH:C:\Qt\5.2.1\msvc2012_64_opengl\lib C:\Qt\5.2.1\msvc2012_64_opengl\lib\Qt5Cored.lib 

我肯定希望能够在我的 .pro 文件中解决这个问题,这样这些额外的引用就不会出现。建议将不胜感激。

作为参考,这是我最新的 .pro 文件。

QT       += core
QT       -= gui

TARGET = QtCuda
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app

SOURCES += main.cpp \
           cuda_code.cu

# project build directories
DESTDIR     = $$PWD
OBJECTS_DIR = $$DESTDIR/obj

# C++ flags
QMAKE_CXXFLAGS_RELEASE =-O3

# Cuda sources
CUDA_SOURCES += cuda_code.cu

# Path to cuda toolkit install
CUDA_DIR      = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v7.0"

# Path to header and libs files
INCLUDEPATH  += $$CUDA_DIR/include
QMAKE_LIBDIR += $$CUDA_DIR/lib/x64

SYSTEM_TYPE = 64            # '32' or '64', depending on your system

# libs used in your code
LIBS += -lcuda -lcudart

# GPU architecture
CUDA_ARCH     = sm_50

# Here are some NVCC flags I've always used by default.
NVCCFLAGS     = --use_fast_math


# Prepare the extra compiler configuration (taken from the nvidia forum - i'm not an expert in this part)
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')


# MSVCRT link option (static or dynamic, it must be the same with your Qt SDK link option)
MSVCRT_LINK_FLAG_DEBUG = "/MDd"
MSVCRT_LINK_FLAG_RELEASE = "/MD"


# Tell Qt that we want add more stuff to the Makefile
QMAKE_EXTRA_COMPILERS += cuda

# Configuration of the Cuda compiler
CONFIG(debug, debug|release) 
    # Debug mode
    cuda_d.input = CUDA_SOURCES
    cuda_d.output = $$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 -c -o $QMAKE_FILE_OUT $QMAKE_FILE_NAME -Xcompiler $$MSVCRT_LINK_FLAG_DEBUG
    cuda_d.dependency_type = TYPE_C
    QMAKE_EXTRA_COMPILERS += cuda_d

else 
    # Release mode
    cuda.input = CUDA_SOURCES
    cuda.output = $$CUDA_OBJECTS_DIR/$QMAKE_FILE_BASE.obj
    cuda.commands = $$CUDA_DIR/bin/nvcc.exe $$NVCC_OPTIONS $$CUDA_INC $$LIBS --machine $$SYSTEM_TYPE \
                    -arch=$$CUDA_ARCH -c -o $QMAKE_FILE_OUT $QMAKE_FILE_NAME -Xcompiler $$MSVCRT_LINK_FLAG_RELEASE
    cuda.dependency_type = TYPE_C
    QMAKE_EXTRA_COMPILERS += cuda

[注意:此答案是通过对包含解决方案的问题的编辑创建的。它已被添加为社区 wiki 条目,以将问题从 CUDA 标记的未回答列表中删除]

【讨论】:

@BryanGreenway:如果您想投票或接受答案,该问题将从未回答的问题列表中删除(注意它是一个社区 wiki 答案,因此参与投票或接受) 关于报价问题,我认为没有修复,应该报bug。当路径中有空格时,必须有引号。问题是 Qt 创建者使用整个字符串,包括引号,来生成 Makefile

以上是关于CUDA、Win7、Qt Creator - LNK1104:无法打开文件“<cuda 文件>.obj”的主要内容,如果未能解决你的问题,请参考以下文章

win7下qt creator 4.5.1打不开

求解win7 64位上安装Qt4.8.6 + Qt Creator3.1.0 + mingw ??

win7/10下Qt Creator调试提示:The selected debugger may be inappropriate for the inferior的解决办法

TestDisk 之Qt creator + MinGW +Qt +gdb

QTCreate subdirs project with qt creator

QTCreate subdirs project with qt creator