Issue
In CMake, how can I define an option that is not configurable by the user, but automatically calculated?
I would like to do the following:
if (FOO AND NOT BAR)
option(BOO "Foo and not bar" ON)
endif()
And then I can use BOO
in different CMake files:
if (BOO)
# do something
endif()
And also in sources:
#ifdef BOO
// do something
#endif
So BOO
behaves like a regular option, but is automatically calculated and not configurable by user running cmake
.
EDIT: I now realize that options are not implicitly available in sources, but need to be defined explicitly with target_add_definitions
or other means. So now it becomes obvious that the solution is to define BOO
as a CMake variable, rather than an option.
Solution
Your "non-user-configurable" option sounds like a variable, which you can create like:
if(FOO AND NOT BAR)
set(BOO TRUE)
else()
set(BOO FALSE)
endif()
To use this variable in C++ code, you need to tell CMake to create a C++ file which defines this information. Take a look at CMake's configure_file
function. Here's the official documentation, and here's part of the official CMake tutorial which walks through a simple usage of this function. I would type out some example code, but it would be a lot of boilerplate, and the linked documents do the job and should be better at answering your questions.
There is an alternative to configure_file
: using target_compile_definitions
. The tradeoff to make is between simplicity of implementation and build times. If the value of a compile definitions changes upon reconfiguration, then CMake has to assume that every source file of the target needs to be recompiled, since it has no information about how that definition is being used (ie. target_compile_definitions
is easy to implement, but can lead to much slower build times in specific scenarios). When you use configure_file
, only the files that include the file that defines those definitions need to be recompiled. There's also potentially an argumen to be made about "readability": if your target gets installed, it's easier for someone reading the installed headers to find the definition versus having to read generated CMake files to find it.
Answered By - David Fong Answer Checked By - Marilyn (WPSolving Volunteer)