How should I specify the language in a CMake project that optionally supports CUDA?

Viewed 436

I am adding optional CUDA functionalities to a CMake project. Right now, the project is organized as an executable and some static libraries. In the top level CMakeLists.txt file there is a project statement like this:

project (my_project LANGUAGES CXX)

And below there an option statement adds the parameter to regulate whether to build with the CUDA functionalities or not

option(CUDA_FEATS "Set to On to use CUDA features" ON)

I am not sure what the correct thing to do would be. Should I:

  • Edit the top project statement to add CUDA
  • Add, after the CUDA_FEATS option is set, a statement like project (my_project LANGUAGES CXX CUDA) (could this conflict with the initial one?)
  • Only put the project statement after the parameter has been set

Or something else entirely? What is the best practice in these cases?

1 Answers

Use the enable_language command, it's pretty self-explanatory:

cmake_minimum_required(VERSION 3.20)
project(my_project)

option(CUDA_FEATS "Set to On to use CUDA features" ON)
if (CUDA_FEATS)
    enable_language(CUDA)
endif ()

After that point, if CUDA_FEATS is true, then you certainly have enabled the CUDA language, have found a compiler, etc.


To address your partial solutions:

Should I:

  • Edit the top project statement to add CUDA

No, because you don't require CUDA. This is the right thing to do if your project will not build without a CUDA compiler, but when it's optional you should not search for a CUDA compiler you might not use (especially since this will fatal-error if it can't find it!).

  • Add, after the CUDA_FEATS option is set, a statement like project (my_project LANGUAGES CXX CUDA) (could this conflict with the initial one?)

I think this would technically work, just because project happens to call enable_language internally, but it's very smelly.

  • Only put the project statement after the parameter has been set

The policy settings and project/language detection features are so essential, they they should always be configured at the start of your top-level CMakeLists.txt. That means the first two lines ought to be cmake_minimum_required and project, with no code in between or before. I can't think of any instance when violating this rule would be a hard requirement in modern CMake.

Related