Building CUDA in Qt Creator

Here is a working example of CUDA in a qmake project file (.pro) w/ support for error selection in Qt Creator. This code was cobbled together from several blogs and StackOverflow questions. I don't have the original references so I apologize if I've aped someone's hard work without the proper attribution.

Project Script

TEMPLATE = app  
CONFIG += console  
CONFIG -= app_bundle

HEADERS += \  
    example.hpp

SOURCES += \  
    example.cpp

OTHER_FILES +=  \  
    cuda_kernel.cu

DESTDIR = $$PWD  
OBJECTS_DIR = $$DESTDIR/CudaObj  
CUDA.dir = /usr/local/cuda-5.5          #Change to your path here  
CUDA.lib = $$CUDA.dir/lib64             #Change to your path (and specify 32 vs 64 bit)  
CUDA.bin = $$CUDA.dir/bin  
CUDA.objects_dir = release/cuda  
CUDA.arch = sm_30                       #Change to a compute architecture supported by your graphics card

# Example CUDA flags
CUDA.nvcc_flags = "--compiler-options -fno-strict-aliasing -use_fast_math --ptxas-options=-v"

INCLUDEPATH += $$CUDA.dir/include  
QMAKE_LIBDIR += $$CUDA.lib  
DEPENDPATH += $$CUDA.lib

# Append cuda libs to existing lib requirements
LIBS += -lcudart \  
        -lcuda

# Generate CUDA includes after *all* INCLUDEPATH statements
CUDA.inc = $$join(INCLUDEPATH,'" -I"','-I"','"')

# Create CUDA compiler
cudac.commands = $$CUDA.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

cudac.dependency_type = TYPE_C  
cudac.depend_command = $$CUDA.dir/bin/nvcc -O3 -M $$CUDA.inc $$NVCCFLAGS ${QMAKE_FILE_NAME}  
cudac.input = OTHER_FILES  
cudac.output = ${OBJECTS_DIR}${QMAKE_FILE_BASE}_cuda.o

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

My project file is currently for Linux only. It relies on sed in the following block:

cudac.commands = $$CUDA.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

Windows users can try gnuwin32-sed or they can omit 2>&1 \| sed -r \"s/\\(([0-9]+)\\)/:\\1/g\" 1>&2 from cudac.commands. This will remove issue double-clicking in Qt Creator but you can still look at the compiler output to find your errors.

sed is used to reshape nvcc output to follow gcc's output style. The result is piped back in to stderr which Qt Creator uses to allow error selection in the IDE.

nvcc error output:

cuda_kernel.cu(48): error: identifier "asd" is undefined  

Corrected (gcc-like) error output:

cuda_kernel.cu:48: error: identifier "asd" is undefined  

Qt Creator clickable error:

/home/jc/projects/cuda_test/cuda_kernel.cu:48: error: identifier "asd" is undefined

Adding new CUDA Files to the Project

In the script above I am storing my CUDA files (.cu) in Qt's Other Files filter. These must be manually added to the project file here:

OTHER_FILES +=  \  
    cuda_kernel.cu \
    your_new_file_here.cu

I haven't found a cleaner way to include CUDA files in Qt Creator while excluding them from the default gcc build cycle. Some users have suggested doing something like:

SOURCES += cuda_kernel.cu  
#... do other stuff
SOURCES -= cuda_kernel.cu  

Supposedly that will add cuda_kernel.cu to the Sources filter and then remove it from default compilation. Either option is a hack that could disappear with a new version of Qt Creator but I prefer my approach as it seems less likely Other Files will ever be anything but a catch-all filter excluded from builds.

CUDA Syntax Highlighting

You may also wish to enable syntax highlighting. I can't recall if this is handled by the project file (.pro) or if I did it manually but just to be safe you can enable syntax highlighting in Tools->Options->Environment->MIME Types:

Troubleshooting

Q: Why aren't changes to my CUDA code showing up in the executable?

A: I don't recall the reasons for this happening but sometimes Qt Creator will successfully build your executable using stale CUDA object files from a previous build. Verify that the object files (.o) in CudaObj have a recent timestamp.

Q: Why the hell did you name the compiler cudac?

A: (Cuda) + (C)ompiler = cudac. Call it whatever you like, I use that variable CUDA in my project files to store CUDA specific variables.

View Comments