Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake 3.8+: Setting different compiler flags for projects that include both .cpp (C++) and .cu (CUDA) files

Tags:

c++

cuda

cmake

I have a CMake project which includes a single target that includes both C++(.cpp) and CUDA C++(.cu) files. However I have some questions which I failed to address.

At the top of my CMakeLists.txt I have:

project(my-project CUDA CXX)

For the ones confused: Yes, CMake 3.8 makes CUDA C++ an intrinsically supported language. So there is no longer need to use things like cuda_add_executable() and sorcery like that. Everything works just fine by using standard and native CMake commands. Also, apparently you can set more than one languages in CMake's project() command. See: https://devblogs.nvidia.com/parallelforall/building-cuda-applications-cmake/

My problem now is that I want to set different compiler flags for the different compilers in a CMake way (i.e., with the target_compile_options() command). The first solution I can think of is:

add_compile_options(my_target
    PRIVATE
    $<$<COMPILE_LANGUAGE:CXX>:-Wsign-conversion>
    $<$<COMPILE_LANGUAGE:CUDA>:-arch=compute_30>
)

However, I find this code a bit ugly. The other option I can think of would be to create two separate targets, one for the .cpp files and one for the .cu files. Then I will be able to set the compiler options separately for the GCC and NVCC targets.

Both of the above solutions seem to work, but I am trying to figure out which is the better way. Any suggestions? Pros and cons?

I am also having trouble with the first solution when I want to include multiple compiler flags. What is the proper way of splitting them? Just use space between the different flags? And what if I want to span the expression on multiple lines? If I try to do so in any way, CMake gives me syntax errors.

Finally, I want to avoid manually altering CMAKE_CXX_FLAGS and CMAKE_CUDA_FLAGS.

Thank you in advance

like image 203
AstrOne Avatar asked Oct 24 '17 05:10

AstrOne


1 Answers

I agree with @OutOfBound in comments, the simplest solution is to split your code in sub project(s). This way you can control each project flags independently, and even build multiple .cu files with different flags (if needed). If this becomes more complex, you might also want to build kernels with nvcc and load them with cuModuleLoad*().

like image 98
Robin Thoni Avatar answered Oct 03 '22 08:10

Robin Thoni