5

I'm writing some code that can be compiled as C++ or as CUDA. In the latter case, it makes use of CUDA kernels, in the former it just runs conventional code.

Having created a file named test.cpp, I can compile it manually thus:

g++ test.cpp          # build as C++ with GCC
nvcc -x cu test.cpp   # build as CUDA with NVCC

where -x cu tells nvcc that although it's a .cpp extension, I'd like it to treat it as CUDA. So far, so good.

However, when I migrate to using CMake, I don't know how to do the same thing. That is: how to ask CMake to compile the .cpp file with NVCC, rather than GCC.

cmake_minimum_required(VERSION 3.9)
project(cuda_test LANGUAGES CUDA CXX)
add_executable(cuda_test test.cpp)     # builds with GCC

If I create a symlink to the original file:

ln -s test.cpp test.cu

then change CMakeLists.txt:

add_executable(cuda_test test.cu)     # builds with NVCC

But I'd like to be able to specify the equivalent of NVCC's -x switch within CMake, rather than playing games with extensions. Something like:

set_target_properties(cuda_test PROPERTIES FORCE_LANGUAGE CUDA)

or even

set_target_properties(test.cpp PROPERTIES FORCE_LANGUAGE CUDA)

Does such an incantation exist?

talonmies
  • 70,661
  • 34
  • 192
  • 269
Edd Inglis
  • 1,067
  • 10
  • 22
  • Possible dupe: https://stackoverflow.com/questions/44284275/passing-compiler-options-cmake – sweenish Nov 14 '19 at 16:35
  • 4
    For tell CMake to use CUDA compiler for a **source file**, you may set [LANGUAGE](https://cmake.org/cmake/help/v3.15/prop_sf/LANGUAGE.html) property for that file: `set_source_file_properties(test.cpp PROPERTIES LANGUAGE CUDA)`. – Tsyvarev Nov 14 '19 at 16:37
  • Thanks @sweenish, but I don't think that's the same question. I can pass compiler-specific arguments okay but not specify the compiler in the first place. That is, if I do `target_compile_options(cuda_test PRIVATE "-x cu")` the flag gets passed to GCC, not NVCC. – Edd Inglis Nov 14 '19 at 16:41
  • @Tsyvarev, it's `...files...` but otherwise that's exactly what I needed. Thanks so much. Please make it an answer rather than a comment and I'll accept it. – Edd Inglis Nov 14 '19 at 16:44

1 Answers1

10

By default, CMake chooses compiler for a source file according to the file's extension. But you may force CMake to use the compiler you want by setting LANGUAGE property for a file:

set_source_files_properties(test.cpp PROPERTIES LANGUAGE CUDA)

(This just calls CUDA compiler for a file using normal compiler options. You still need to pass additional options for that compiler, so it could work with the unusual file's extension.)

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • I realise I'm just being a pain now, but... I'm now limited to _only_ compiling this file as CUDA, since the property is file- rather than target-specific. I'm going to look around for an answer, but wondered if you had a magic solution to this too?! – Edd Inglis Nov 14 '19 at 16:55
  • @EddInglis Note, you can list *all* the source files in the same call: `set_source_files_properties(test.cpp test2.cpp test3.cpp PROPERTIES ...)` or you can provide a variable containing a list of all the sources instead. – Kevin Nov 14 '19 at 16:58
  • Thanks, @squareskittles, that's handy. What I meant, though, was once I've set the property on test.cpp, now CMake will always compile it with NVCC. Ideally I could build it with either GCC or NVCC. Rather than complicating this question, I'll ask a new one. Cheers. – Edd Inglis Nov 14 '19 at 17:00
  • 1
    In CMake single **target** may contain source files for **different languages**. So, compile language is not a property for a target. (There is target property [LINKER_LANGUAGE](https://cmake.org/cmake/help/v3.15/prop_tgt/LINKER_LANGUAGE.html) for specify language for the linker, but linking and compiling are separate steps.) – Tsyvarev Nov 14 '19 at 17:02