How to enable assert in CMake Release mode?

2019-02-16 16:39发布

问题:

CMake is being used to compile some C++ files. There are assert calls in the code. These calls are disabled in Release mode of CMake. It defines NDEBUG in Release mode, I guess.

If I'm interested in having assert in Release mode of CMake, how do I enable it?

回答1:

1

If you interested in assert functionality only in your own code then the simple one solution is to provide custom assert. For instance:

#if (MY_DEBUG)
# define MY_ASSERT(A) ... checks here ...
#else
# define MY_ASSERT(A) ... ignore A ...
#endif

Use option to enable/disable assert:

# CMakeLists.txt
option(ENABLE_MY_ASSERT "Turn on MY_ASSERT checks" OFF)
if(ENABLE_MY_ASSERT)
  add_definitions(-DMY_DEBUG=1)
else()
  add_definitions(-DMY_DEBUG=0)
endif()

In this case you have full control over your checks, you can verify one component and ignore others:

... FOO_DEBUG=0 BOO_DEBUG=1 BAR_DEBUG=0 ...

2

Add custom CMAKE_BUILD_TYPE (also see CMAKE_CONFIGURATION_TYPES):

cmake_minimum_required(VERSION 2.8.12)
project(foo)

set(CMAKE_CXX_FLAGS_MYREL "-O3")

add_library(foo foo.cpp)

output:

# Debug
# ... -g ...

# Release
# ... -O3 -DNDEBUG ...

# RelWithDebInfo
# ... -O2 -g -DNDEBUG ...

# MyRel
# ... -O3 ...


回答2:

This would be a solution for the MSVC compiler:

string( REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")

A better option may be to enable asserts not in Release mode but in RelWithDebInfo mode instead:

string( REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")

But this depends on your project and preferences of course.



回答3:

See this answer in the CMake FAQ, i.e.:

Fix it manually by changing the definition of the cache variables CMAKE_C_FLAGS_RELEASE and CMAKE_CXX_FLAGS_RELEASE. This has to be done every time you set up a new build directory.

To fix it permanently, create a custom CMake rules file in your source folder with the desired settings for the release flags (omit the option /D NDEBUG). Then in your outermost CMakeLists.txt point the variable CMAKE_USER_MAKE_RULES_OVERRIDE to the custom CMake rules file.