Original question (title: .cu file is processed as a .cpp file in Visual Studio/CMake)
I am trying to add a static library with CUDA code to my C++ project. I have a top level CMakeLists.txt file, a static library that's added from there, and my CUDA-using library that's added from that library (both libraries have their own CMakeLists.txt file. In the root file I have used enable_language(CUDA), in the 1st level library's CMakeLists.txt I have done this:
add_subdirectory(cuda_library)
set_target_properties(level_1_lib PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(level_1_lib PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
target_link_libraries(level_1_lib cuda_library)
and in the CUDA library's CMakeLists.txt:
add_library(cuda_library
cuda_library.cu cuda_library.h)
target_include_directories(cuda_library
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
A .cpp file in the level 1 library calls an "interface function" I declare in cuda_library.h that is implemented in cuda_library.cu and internally launches a CUDA __global__ kernel this way:
namespace cuda_library {
__global__
void real_foo(int number, int *out) {
*out = number * 2;
}
inline int foo(int number) {
int* x;
cudaMallocManaged(&x, sizeof(int));
real_foo<<<1,1>>>(number, x);
cudaDeviceSynchronize();
int y = *x;
cudaFree(x);
return y;
}
}
When I build from Visual Studio (with the CMake extension enabled, and it uses ninja as a generator), though, the build does not like the __global__ keyword, making me think that the .cu file is treated like a normal .cpp file and not compiled as CUDA code.
What am I doing wrong?
Edit to better clarify the errors I get
If I hit Visual Studio's "Build All" (or run CMake with ninja from the Visual Studio command prompt, which normally can compile simple CUDA examples with nvcc, the errors are the same) and I'm not on the cuda_library.cu file, I only get errors that boil down to unresolved external symbol cuda_library::foo(int), which from some research means that the function might be declared but not defined. This makes sense if the header is included but the .cu file is not correctly compiled.
However, only if I make the .cu file active VS shows me the errors that are related to the CUDA code treated like C++ code, and they don't have the normal error logo (like the first error in this image), but the one you can see in the second and third one:
so could they simply be Intellisense errors that do not appear while building?
In that case there might be another cause why the static library's implementation is not properly linked. To be more thorough about it, this is the header (cuda_library.h):
#ifndef _CUDA_LIBRARY_H_
#define _CUDA_LIBRARY_H_
namespace cuda_library {
inline int foo(int number);
}
#endif
and I try to import and use it this way in the .cpp file where the unresolved external symbol cuda_library::foo(int) error occurs:
#include "cuda_library/cuda_library.h"
printf("Result from the GPU: %d\n", cuda_library::foo(5));
Funnily enough I've also tried
#include <cuda_library.h>
and the result is the same, maybe because CMake includes it in what would be the include search path?
The project has this structure:
root_dir\
CMakeLists.txt
libs\
CMakeLists.txt
level_1_lib\
CMakeLists.txt
file_using_cuda_lib.cpp
cuda_library\
CMakeLists.txt
cuda_library.cu
cuda_library.h
I really can't understand what's exactly going wrong, so any help is well accepted.
