I want to ensure that a particular compiler definition is set/not set based on the build type. I thought that this would work but it’s not:
if($ENV{CMAKE_BUILD_TYPE} MATCHES "[Dd][Ee][Bb][Uu][Gg]")
# In case it was added
remove_definitions("-DNDEBUG")
else()
# In case it wasn't added
add_compile_definitions("NDEBUG")
endif()
Ooo! That’s great. However, I need to be able to remove it and it would seem that remove_definitions doesn’t expand generator expressions. That’s unfortunate.
It’s really unclear where generator expressions can work correctly.
The general rule is that if the documentation doesn’t explicitly say generator expressions are supported, then they are not supported for that documented thing.
To help you more generally, generator expressions cannot be evaluated during the configure phase. What that means is that you cannot switch logic in your CMakeLists.txt files based on a value that may contain generator expressions. That’s why something like if($<CONFIG:Debug>) can’t work. The if() command is logic evaluated at configure time. The $<CONFIG:Debug> generator expression can only be evaluated at generation time (which is after the configure phase is finished, i.e. after processing all the CMakeLists.txt files has finished).
The reason is legacy. I just came on to the project and I’m not going to disrupt their current workflow until I understand it.
Though, if I understand the cmake system correctly, I can explicitly remove the define with this:
remove_definitions("-DNDEBUG")
and use your:
code without affecting the rest of the project, as this stuff percolates up into the directory tree. Everything below that doesn’t see anything. Is that right?
It’d only be seen by the directory that does this and any children. There’s no mechanism to affect parent scopes beyond one level with PARENT_SCOPE, the cache, or setting DIRECTORY properties on specific directories.
As I said before, I’m new here and they have this defined in the root CMakeLists.txt file as:
if (DEBUG_MODE OR SANITIZER_ENABLED)
else (DEBUG_MODE OR SANITIZER_ENABLED)
add_compile_definitions("NDEBUG")
endif(DEBUG_MODE OR SANITIZER_ENABLED)
And until I can explain why this is, I can’t/won’t change it as it may break something else. Something very bad on a RT motor controller. My code isn’t run on the controller. It’s just a Windows app, that takes the data that the controller generates and spits it out in human readable form.
Something like that if can only work with single-configuration generators (e.g. makefiles) where separate build trees are used for debug and release builds. For these single-config generators you can use the value of CMAKE_BUILD_TYPE to determine the build type that is being generated (see here for info on this variable).
For multi-config generators such as visual studio CMAKE_BUILD_TYPE is not set/defined.
The way your if is written makes me think you are using a single-config generator. It would help if we knew what toolchain you are using (for both your RT motor controller project and your windows app project).
Also: find out where the variables DEBUG_MODE and SANITIZER_ENABLED are set. Are they set on the command line when CMake is called?