2014-03-03 34 views
8

CMake被用来编译一些C++文件。代码中有assert调用。这些调用在CMake的发布模式中被禁用。它在释放模式下定义了NDEBUG,我猜。如何在CMake发布模式下启用断言?

如果我有兴趣在CMake的发布模式中声明,我该如何启用它?

+1

明显地从'CMAKE_CXX_RELEASE_FLAGS'中删除这个定义。 – arrowd

+2

请注意,如果您发现自己需要执行Release中的检查,那么'assert'可能是该作业的错误工具(尽管对于您的问题仍然存在有效的用例,例如调试仅在发布中出现的问题) 。考虑引入与assert相比具有较弱语义的其他诊断宏(事实上,它指定了一个必须_never fail_的条件),但仍可以选择性地启用(例如,如果用户将无效参数传递给函数,则条件可能会失败)。 – ComicSansMS

回答

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 ... 

添加自定义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 ... 
2

通过改变缓存变量CMAKE_C_FLAGS_RELEASECMAKE_CXX_FLAGS_RELEASE的定义见this answer在CMake的常见问题,即:

修复它手动。这必须在每次设置新的编译目录时完成。

要永久修复它,请使用所需的发布标志设置(忽略选项/D NDEBUG)在源文件夹中创建自定义CMake规则文件。然后在最外面的CMakeLists.txt中将变量CMAKE_USER_MAKE_RULES_OVERRIDE指向自定义CMake规则文件。

2

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

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

一个更好的选择可以是,使断言不释放模式,但在RelWithDebInfo模式,而不是:

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

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

+0

对于gcc或clang,'/ DNDEBUG' - >'-DNDEBUG'。为了清除这个问题,你可以将它包装在一个if语句中,比如'if(CMAKE_CXX_COMPILER_ID MATCHES“Clang | GNU”)... endif()' –

相关问题