Search code examples
c++eclipsecudamakefilensight

How to get Nsight EE to compile with -dc flag?


I'm trying to compile a CUDA application with Nsight that compiles .cpp files to .o files then links the main application. I'm basing my build off the NVIDIA "Parallel for All" example Separate Compilation and Linking of CUDA C++ Device Code and its Makefile:

objects = main.o particle.o v3.o

all: $(objects)
        nvcc -arch=sm_20 $(objects) -o app

%.o: %.cpp
        nvcc -x cu -arch=sm_20 -I. -dc $< -o $@

clean:
        rm -f *.o app

When I copy my code into a new directory and use that Makefile (adapted to my filenames and other flags, of course), everything works fine.

But I can't figure out how to get the same options into Eclipse and as such the build always fails with the following errors:

/usr/local/cuda-7.5/bin/nvcc -G -g -O0 -std=c++11 -gencode arch=compute_50,code=sm_50  -odir "src" -M -o "src/Object.d" "../src/Object.cpp"
/usr/local/cuda-7.5/bin/nvcc -G -g -O0 -std=c++11 --compile  -x c++ -o  "src/Object.o" "../src/Object.cpp"

../src/kernels.cu:31:12: error: ‘blockIdx’ was not declared in this scope
#... lots more "no one told me this was CUDA" errors

../src/Object.cpp:125:26: error: expected primary-expression before ‘<’ token
#... can't call CUDA kernels from cpp either ...

My project files' relevant includes are are:

Object.cpp:

#include "Object.h"
#include "kernels.cu"

main.cpp: (same error with fname as main.cu)

#include "Object.h"

kernels.cu:

#include "Object.h"

Object.h:

#include <cuda_runtime.h>

The code compiles fine with the custom makefile. The missing piece appears to be the -dc (device code) flag but I don't know how to enable it in Nsight Eclipse edition. I know I can create a Makefile project, but I'd really prefer to do it from within Eclipse so that all the introspection works right etc.


Solution

  • I solved the problem, though I still don't entirely understand it... It seems that the -x c++ was the key flag, not -dc.

    The default build settings of Nsight Eclipse work correctly when the files are renamed as follows:

    Object.cpp Object.cu:

    #include "Object.h"
    #include "kernels.cuh"
    

    main.cpp: (main.cu is also good)

    #include "Object.h"
    

    kernels.cu kernels.cuh:

    #include "Object.h"
    

    Object.h:

    #include <cuda_runtime.h>
    

    Apparently .cu files are compiled to .o files with -x cu (language CUDA) and then linked but .cpp files are compiled with language -x c++ and therefore do not see all of the CUDA markup. The main.cpp file has no actual CUDA in it so it doesn't matter.

    Without renaming the kernels.cu to kernels.cuh build fails with multiple definition errors because it's compiled twice.

    The current configuration appears to work, I hope this is helpful to someone. I really wish there was some clear documentation or settings on how file extensions affect build rules in Nsight...