在QTCreator中使用MinGW编译C++和CUDA代码

4

我正在尝试编译一个简单的CUDA程序(源代码取自在Windows上使用Qt Creator编译CUDA代码)。 这是我的.pro文件:

TARGET = Cuda

# Define output directories
DESTDIR = release
OBJECTS_DIR = release/obj
CUDA_OBJECTS_DIR = release/cuda

# Sourcefiles
SOURCES += main.cpp

# This makes the .cu files appear in your project
OTHER_FILES +=  vectorAddition.cu

# CUDA settings <-- may change depending on your system
CUDA_SOURCES += vectorAddition.cu

CUDA_SDK = "C:/Cuda/CudaSamples"   # Path to cuda SDK install
CUDA_DIR = "C:/Cuda/CudaToolkit"            # Path to cuda toolkit install
SYSTEM_NAME = Win32         # Depending on your system either 'Win32', 'x64', or 'Win64'
SYSTEM_TYPE = 32            # '32' or '64', depending on your system
CUDA_ARCH = sm_11           # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10'
TEMP = 'C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin' #tried to add VS compiler path, seems woring. When i changed it to higher version error appeared
VS = $$join(TEMP,'" -ccbin "','-ccbin "','"') #joing path to VS compiler with quotes
NVCC_OPTIONS = --use_fast_math $$VS

# include paths
INCLUDEPATH += $$CUDA_DIR/include \
               $$CUDA_SDK/common/inc/ \
               $$CUDA_SDK/../shared/inc/ \

# library directories
QMAKE_LIBDIR += $$CUDA_DIR/lib/$$SYSTEM_NAME \
                $$CUDA_SDK/common/lib/$$SYSTEM_NAME \
                $$CUDA_SDK/../shared/lib/$$SYSTEM_NAME \
                C:/CUDA/VS10/VC/lib \   #tried to add VS runtime libraries, after that some errors disappeared, and some new emerged so i guess it worked
QMAKE_LIBS += -lmsvcrt -llibcmt -llibcpmt #after adding VS runtime to QMAKE_LIBDIR this line seems to have no effect
# Add the necessary libraries
LIBS += -lcuda -lcudart
#LIBS += -lmsvcr100
QMAKE_CFLAGS_RELEASE += -v
MSVCRT_LINK_FLAG_DEBUG   = "/MTd"
MSVCRT_LINK_FLAG_RELEASE = "/MT"

# The following makes sure all path names (which often include spaces) are put between quotation marks
CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
#this was nested in CONFIG (see link above) but i dont think it worked
    cuda.input = CUDA_SOURCES
    cuda.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o
    cuda.commands = $$CUDA_DIR/bin/nvcc.exe $$NVCC_OPTIONS $$CUDA_INC $$LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH \
                    -Xcompiler "/wd4819,/EHsc,/W3,/nologo,/O2,/Zi" \ 
                    -Xptxas -v \
                    -Xcompiler $$MSVCRT_LINK_FLAG_RELEASE \
     -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME} #Xptxas -v is command for some extra output during cuda compiling (nvvc). -Xcompiler, honesly i have no idea what "/wd4819,/EHsc,/W3,/nologo,/O2,/Zi" \ means,i copied those from some chinese webpage and again some errors went away
    cuda.dependency_type = TYPE_C
    QMAKE_EXTRA_COMPILERS += cuda

HEADERS += \
    vectorAddition.h #empty header, i was just trying something.

这是编译器输出:

13:09:17: Running steps for project Cuda...
13:09:17: Starting: "F:\Programs\Qt5.1.1\Tools\mingw48_32\bin\mingw32-make.exe" clean
F:/Programs/Qt5.1.1/Tools/mingw48_32/bin/mingw32-make -f Makefile.Release clean
mingw32-make[1]: Entering directory 'F:/workspaceSchool/build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release'
del release\cuda\vectorAddition_cuda.o
del release\cuda\vectorAddition_cuda.o release\obj\main.o
Could Not Find F:\workspaceSchool\build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release\release\cuda\vectorAddition_cuda.o
mingw32-make[1]: Leaving directory 'F:/workspaceSchool/build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release'
F:/Programs/Qt5.1.1/Tools/mingw48_32/bin/mingw32-make -f Makefile.Debug clean
mingw32-make[1]: Entering directory 'F:/workspaceSchool/build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release'
del release\cuda\vectorAddition_cuda.o
Could Not Find F:\workspaceSchool\build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release\release\cuda\vectorAddition_cuda.o
del release\cuda\vectorAddition_cuda.o debug\obj\main.o
Could Not Find F:\workspaceSchool\build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release\release\cuda\vectorAddition_cuda.o
Could Not Find F:\workspaceSchool\build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release\debug\obj\main.o
mingw32-make[1]: Leaving directory 'F:/workspaceSchool/build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release'
13:09:18: The process "F:\Programs\Qt5.1.1\Tools\mingw48_32\bin\mingw32-make.exe" exited normally.
13:09:18: Starting: "F:\Programs\Qt5.1.1\5.1.1\mingw48_32\bin\qmake.exe" F:\workspaceSchool\Cuda\Cuda.pro -r -spec win32-g++ -v
QMake version 3.0
Using Qt version 5.1.1 in F:\Programs\Qt5.1.1\5.1.1\mingw48_32\lib
13:09:18: The process "F:\Programs\Qt5.1.1\5.1.1\mingw48_32\bin\qmake.exe" exited normally.
13:09:18: Starting: "F:\Programs\Qt5.1.1\Tools\mingw48_32\bin\mingw32-make.exe" 
F:/Programs/Qt5.1.1/Tools/mingw48_32/bin/mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory 'F:/workspaceSchool/build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release'
C:\Cuda\CudaToolkit\bin\nvcc.exe --use_fast_math -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin" -I"C:/Cuda/CudaToolkit/include" -I"C:/Cuda/CudaSamples/common/inc/" -I"C:/Cuda/CudaSamples/../shared/inc/" -lcuda -lcudart --machine 32 -arch=sm_11 -Xcompiler /wd4819,/EHsc,/W3,/nologo,/O2,/Zi -Xptxas -v -Xcompiler /MT -c -o release\cuda\vectorAddition_cuda.o ..\Cuda\vectorAddition.cu
ptxas : info : 0 bytes gmem
ptxas : info : Compiling entry function '__cuda_dummy_entry__' for 'sm_11'
ptxas : info : Used 0 registers
g++ -c -pipe -fno-keep-inline-dllexport -O2 -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I..\Cuda -I"C:\Cuda\CudaToolkit\include" -I"C:\Cuda\CudaSamples\common\inc" -I"C:\Cuda\CudaSamples\..\shared\inc" -I"..\..\Programs\Qt5.1.1\5.1.1\mingw48_32\include" -I"..\..\Programs\Qt5.1.1\5.1.1\mingw48_32\include\QtGui" -I"..\..\Programs\Qt5.1.1\5.1.1\mingw48_32\include\QtCore" -I"release" -I"." -I"..\..\Programs\Qt5.1.1\5.1.1\mingw48_32\mkspecs\win32-g++" -o release\obj\main.o ..\Cuda\main.cpp
In file included from C:\Cuda\CudaToolkit\include/device_types.h:53:0,
                 from C:\Cuda\CudaToolkit\include/builtin_types.h:56,
                 from ..\Cuda\main.cpp:2:
C:\Cuda\CudaToolkit\include/host_defines.h:79:0: warning: "__cdecl" redefined [enabled by default]
 #define __cdecl
 ^
..\Cuda\main.cpp:1:0: note: this is the location of the previous definition
 #include <cuda.h>
 ^
In file included from C:\Cuda\CudaToolkit\include/builtin_types.h:60:0,
                 from ..\Cuda\main.cpp:2:
C:\Cuda\CudaToolkit\include/vector_types.h:73:0: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning(push)
 ^
C:\Cuda\CudaToolkit\include/vector_types.h:74:0: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning(disable: 4201 4408)
 ^
C:\Cuda\CudaToolkit\include/vector_types.h:350:0: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning(pop)
 ^
g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o release\Cuda.exe release/cuda/vectorAddition_cuda.o release/obj/main.o  -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 -lqtmain -LC:\Cuda\CudaToolkit\lib\Win32 -LC:\Cuda\CudaSamples\common\lib\Win32 -LC:\Cuda\CudaSamples\..\shared\lib\Win32 -LC:\CUDA\VS10\VC\lib -LQMAKE_LIBS -L+= -L-lmsvcrt -L-llibcmt -L-llibcpmt -lcuda -lcudart -LF:\Programs\Qt5.1.1\5.1.1\mingw48_32\lib -lQt5Gui -lQt5Core 
Warning: .drectve `/FAILIFMISMATCH:"_MSC_VER=1600" /FAILIFMISMATCH:"_ITERATOR_DEBUG_LEVEL=0" /DEFAULTLIB:"libcpmt" /DEFAULTLIB:"LIBCMT" /DEFAULTLIB:"OLDNAMES" ' unrecognized
f:/programs/qt5.1.1/tools/mingw48_32/bin/../lib/gcc/i686-w64-mingw32/4.8.0/../../../../i686-w64-mingw32/lib/../lib/crt2.o:crtexe.c:(.text+0xcf): undefined reference to `_imp___fmode'
f:/programs/qt5.1.1/tools/mingw48_32/bin/../lib/gcc/i686-w64-mingw32/4.8.0/../../../../i686-w64-mingw32/lib/../lib/crt2.o:crtexe.c:(.text+0x2de): undefined reference to `_imp___acmdln'
f:/programs/qt5.1.1/tools/mingw48_32/bin/../lib/gcc/i686-w64-mingw32/4.8.0/../../../../i686-w64-mingw32/lib/../lib/crt2.o:crtexe.c:(.text+0x3cf): undefined reference to `_imp____initenv'
f:/programs/qt5.1.1/tools/mingw48_32/bin/../lib/gcc/i686-w64-mingw32/4.8.0/../../../../i686-w64-mingw32/bin/ld.exe: f:/programs/qt5.1.1/tools/mingw48_32/bin/../lib/gcc/i686-w64-mingw32/4.8.0/../../../../i686-w64-mingw32/lib/../lib/crt2.o: bad reloc address 0x0 in section `.CRT$XCAA'
collect2.exe: error: ld returned 1 exit status
Makefile.Release:78: recipe for target 'release\Cuda.exe' failed
mingw32-make[1]: Leaving directory 'F:/workspaceSchool/build-Cuda-Desktop_Qt_5_1_1_MinGW_32bit-Release'
makefile:34: recipe for target 'release' failed
mingw32-make[1]: *** [release\Cuda.exe] Error 1
mingw32-make: *** [release] Error 2
13:09:28: The process "F:\Programs\Qt5.1.1\Tools\mingw48_32\bin\mingw32-make.exe" exited with code 2.
Error while building/deploying project Cuda (kit: Desktop Qt 5.1.1 MinGW 32bit)
When executing step 'Make'
13:09:28: Elapsed time: 00:11.

所有问题(由于声望不足,无法发布图像):问题

如果我没有弄错的话,问题出在链接cuda目标文件(vectorAddition_cuda.o)上,该文件是由nvvc.exe使用cl.exe和VS libs编译的。然后MinGW(g++编译器)正在尝试将cuda目标文件和c++目标文件(main.o)以及所有库链接到可执行文件中。但是g++不知道VS运行时库,因此会引发这些错误。所以我想我需要以某种方式将VS libs传递给g++。如何解决这个问题?


你尝试过使用完整路径链接cuda和cudart吗?我发现有时候这样更容易调试和解决这些问题。可以尝试像这样:LIBS += C:/Cuda/CudaToolkit/cuda.lib C:/Cuda/CudaToolkit/cudart.lib。一旦它能够正常工作,你就可以使用变量并清理你的.pro文件了。 - Uflex
我尝试了一下,但好像行不通。我认为你不能像那样将库链接到LIBS变量中(从“-l”来看)。无论如何,我更新了编译器输出以显示完整的过程(qmake -> 重建项目)。如果你现在查看编译器输出,nvvc命令似乎正在工作。 - Vojtech Molek
2个回答

2
我有点困惑,你是在使用MinGW还是Visual Studio?标题似乎表明你正在使用MinGW,但项目文件似乎混合使用了两者。你不能混用这两个。如果你使用Visual Studio 2010编译(或直接从NVidia下载二进制文件)CUDA,则必须使用VS10来编译你的项目,否则它将无法工作。
我自己从未使用过CUDA,但似乎系统要求中只提到了Visual Studio 2008、2010和2012。如果你想在Qt中使用它,这是可能的,你只需要获取一个使用VS编译的Qt(32位和64位都有,在下载页面上可以找到)。只要不创建任何商业应用程序,你就可以免费获取Visual Studio Express版本
使用带有MSVC后端编译器的QtCreator,请前往“工具”>“选项”>“构建和运行”>“套件”,添加一个新的套件,其中包括MSVC编译器、cdb作为调试器以及您刚刚下载的Qt版本(它必须已经使用相同的Visual Studio版本进行编译,否则它将无法正常工作)。然后打开您的项目,转到“项目”选项卡(左侧),并选择您刚刚创建的套件。在一切顺利之前,您应该清理您的.pro文件。
另外,您的链接器行中似乎有几个不合适的事情。
g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o release\Cuda.exe release/cuda/vectorAddition_cuda.o release/obj/main.o  -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 -lqtmain -LC:\Cuda\CudaToolkit\lib\Win32 -LC:\Cuda\CudaSamples\common\lib\Win32 -LC:\Cuda\CudaSamples\..\shared\lib\Win32 -LC:\CUDA\VS10\VC\lib -LQMAKE_LIBS -L+= -L-lmsvcrt -L-llibcmt -L-llibcpmt -lcuda -lcudart -LF:\Programs\Qt5.1.1\5.1.1\mingw48_32\lib -lQt5Gui -lQt5Core 

首先是这个 -L+=,可能是由于在 QMAKE_LIBDIR 的末尾使用了转义反斜杠导致的。
然后语法 -L-lmsvcrt 看起来不对。这可能是因为您正在使用 QMAKE_LIBS,我个人从未必须使用它,并且根据 文档,您也不应该使用它,因为它是一个内部变量。同样适用于 QMAKE_LIBDIR。我会为任何外部依赖项使用 LIBS 变量。

所以我不能使用CUDA Windows二进制文件进行g++编译。 如果我想要使用QT和CUDA,我需要使用Linux和CUDA for linux编译器是gcc对吗? - Vojtech Molek
我修改了我的答案,因为它无法适应评论,希望它有助于澄清。 - Uflex
它正在工作,问题在于QT没有使用VS编译。我从您提供的网站下载了QT,并成功构建了此程序。谢谢! - Vojtech Molek
很高兴能帮上忙 :) 我仍然会清理那个 .pro 文件,如果它只是一个测试项目并且可以正常工作,那么这没问题,但是在其他开发者的计算机上可能会出现问题。 - Uflex

0

您可以将以下内容添加到您的 .pro 文件中,以便在 Windows 上使用 VS2010 和 Linux 上链接到 CUDA:

# Define output directories

CONFIG(release, debug|release): CUDA_OBJECTS_DIR = release/cuda
else: CUDA_OBJECTS_DIR = debug/cuda


# This makes the .cu files appear in your project
OTHER_FILES +=  vectorAddition.cu

# CUDA settings <-- may change depending on your system
CUDA_SOURCES += vectorAddition.cu

win32:{
    CUDA_SDK = "C:/ProgramData/NVIDIA Corporation/NVIDIA GPU Computing SDK 5.5/C"   # Path to cuda SDK install
    CUDA_DIR = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v5.5"           # Path to cuda toolkit install
}
else:unix{
    CUDA_SDK = "/usr/local/cuda-5.5/"   # Path to cuda SDK install
    CUDA_DIR = "/usr/local/cuda-5.5/"           # Path to cuda toolkit install
}

win32: SYSTEM_NAME = win32         # Depending on your system either 'Win32', 'x64', or 'Win64'
else:unix: SYSTEM_NAME = unix

SYSTEM_TYPE = 32            # '32' or '64', depending on your system
CUDA_ARCH = sm_30           # Type of CUDA architecture, for example 'compute_10', 'compute_11', 'sm_10'
NVCC_OPTIONS = --use_fast_math

# include paths
INCLUDEPATH += $$CUDA_DIR/include
               #$$CUDA_SDK/common/inc/ \
               #$$CUDA_SDK/../shared/inc/

# library directories
win32:{
    QMAKE_LIBDIR += $$CUDA_DIR/lib/$$SYSTEM_NAME
                    #$$CUDA_SDK/common/lib/$$SYSTEM_NAME \
                    #$$CUDA_SDK/../shared/lib/$$SYSTEM_NAME
}
else:unix:{
    QMAKE_LIBDIR += $$CUDA_DIR/lib
}


win32:{
# The following library conflicts with something in Cuda
QMAKE_LFLAGS_RELEASE = /NODEFAULTLIB:msvcrt.lib
QMAKE_LFLAGS_DEBUG   = /NODEFAULTLIB:msvcrtd.lib
}

# Add the necessary libraries
win32:{
    CUDA_LIBS = cuda cudart
    # The following makes sure all path names (which often include spaces) are put between quotation marks
    CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
    NVCC_LIBS = $$join(CUDA_LIBS,' -l','-l', '')
    LIBS += $$join(CUDA_LIBS,'.lib ', '', '.lib')
}
else:unix:
{
    CUDA_LIBS = -lcuda -lcudart
    # The following makes sure all path names (which often include spaces) are put between quotation marks
    CUDA_INC = $$join(INCLUDEPATH,'" -I"','-I"','"')
    NVCC_LIBS = $$join(CUDA_LIBS,' -l','-l', '')
    LIBS += $$CUDA_LIBS
}

# Configuration of the Cuda compiler
CONFIG(debug, debug|release) {
    # Debug mode
    cuda_d.input = CUDA_SOURCES
    cuda_d.output = $$CUDA_OBJECTS_DIR/${QMAKE_FILE_BASE}_cuda.o

    win32: cuda_d.commands = $$CUDA_DIR/bin/nvcc.exe -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
    else:unix: cuda_d.commands = $$CUDA_DIR/bin/nvcc -D_DEBUG $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}

    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}_cuda.o

    win32: cuda.commands = $$CUDA_DIR/bin/nvcc.exe $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
    else:unix: cuda.commands = $$CUDA_DIR/bin/nvcc $$NVCC_OPTIONS $$CUDA_INC $$NVCC_LIBS --machine $$SYSTEM_TYPE -arch=$$CUDA_ARCH -c -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}

    cuda.dependency_type = TYPE_C
    QMAKE_EXTRA_COMPILERS += cuda
}

谢谢你提供的 .pro 文件。我自己的文件中已经包含了大部分内容,但是由于QT版本不对,它们一直无法正常工作。现在我可以使用它们了(下载并编译了VS版的QT)。 - Vojtech Molek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接