如何在CMake Release模式下启用断言?

时间:2014-03-03 06:56:38

标签: cmake assert ndebug

CMake用于编译一些C ++文件。代码中有assert次调用。在CMake的发布模式下禁用这些调用。我猜它在发布模式中定义了NDEBUG

如果我对在CMake的发布模式下断言感兴趣,我该如何启用它?

4 个答案:

答案 0 :(得分:6)

请参阅CMake常见问题解答中的this answer,即:

通过更改缓存变量CMAKE_C_FLAGS_RELEASECMAKE_CXX_FLAGS_RELEASE的定义来手动修复它。每次设置新的构建目录时都必须这样做。

要永久修复它,请在源文件夹中创建一个自定义CMake规则文件,其中包含释放标记的所需设置(省略选项/D NDEBUG)。然后在最外面的CMakeLists.txt中将变量CMAKE_USER_MAKE_RULES_OVERRIDE指向自定义CMake规则文件。

答案 1 :(得分:5)

这将是MSVC编译器的解决方案:

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

更好的选择可能是启用不在发布模式但在RelWithDebInfo模式下的断言:

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

但这当然取决于你的项目和偏好。

答案 2 :(得分:3)

1

如果您只对自己的代码感兴趣assert功能,那么简单的解决方案 是提供自定义断言。例如:

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

使用option启用/禁用断言:

# 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()

在这种情况下,您可以完全控制您的支票,您可以验证一个 组件并忽略其他人:

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

2

添加自定义CMAKE_BUILD_TYPE(另请参阅CMAKE_CONFIGURATION_TYPES):

cmake_minimum_required(VERSION 2.8.12)
project(foo)

set(CMAKE_CXX_FLAGS_MYREL "-O3")

add_library(foo foo.cpp)

输出:

# Debug
# ... -g ...

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

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

# MyRel
# ... -O3 ...

答案 3 :(得分:1)

这是 LLVM 如何做到的。他们向项目添加一个 LLVM_ENABLE_ASSERTIONS 选项(将 LLVM 更改为您项目的前缀),然后检查它并过滤编译标志。 MSVC 有一个特例。

总的来说,这对我来说似乎比定义构建配置更明智。启用断言是 IMO 对整体构建配置的正交关注。

# This is commonly needed so define it before we include anything else.
string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)

[...]

if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
    option(QD_ENABLE_ASSERTIONS "Enable assertions" ON)
else()
    option(QD_ENABLE_ASSERTIONS "Enable assertions" OFF)
endif()

[...]

if(QD_ENABLE_ASSERTIONS)
    if(NOT MSVC)
        add_definitions(-D_DEBUG)
    endif()
    # On non-Debug builds cmake automatically defines NDEBUG, so we explicitly undefine it:
    if(NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
        # NOTE: use `add_compile_options` rather than `add_definitions` since
        # `add_definitions` does not support generator expressions.
        add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-UNDEBUG>)

        # Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines.
        foreach (flags_var_to_scrub
                CMAKE_CXX_FLAGS_RELEASE
                CMAKE_CXX_FLAGS_RELWITHDEBINFO
                CMAKE_CXX_FLAGS_MINSIZEREL
                CMAKE_C_FLAGS_RELEASE
                CMAKE_C_FLAGS_RELWITHDEBINFO
                CMAKE_C_FLAGS_MINSIZEREL)
            string (REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " "
                    "${flags_var_to_scrub}" "${${flags_var_to_scrub}}")
        endforeach()
    endif()
endif()

来源:https://opensource.apple.com/source/llvmCore/llvmCore-2358.3/CMakeLists.txt.auto.html