#ifdef DEBUG 与 CMake 独立于平台
Posted
技术标签:
【中文标题】#ifdef DEBUG 与 CMake 独立于平台【英文标题】:#ifdef DEBUG with CMake independent from platform 【发布时间】:2011-12-21 14:54:40 【问题描述】:我正在使用 CMake 在 Windows (Visual Studio) 以及 Linux 机器 (gcc) 上构建我的项目。我想将一些代码标记为“仅调试”,例如
#ifdef DEBUG
//some logging here
#endif
问题是:在 CMake“调试”构建类型的所有平台上,哪些编译器定义可用? DEBUG 似乎不存在。 (我希望只有在构建类型为 Debug 时才具有日志记录或其他内容。)
【问题讨论】:
***.com/a/7725055/560648 【参考方案1】:默认情况下,CMake 将 -DNDEBUG
添加到 CMAKE_C_FLAGS_RELEASE, MINSIZEREL 中。所以,你可以使用#ifndef NDEBUG
。
【讨论】:
双重否定很讨厌:) 为什么没有-DDEBUG?NDEBUG
的含义由C standard 定义。它会停用断言。【参考方案2】:
我建议您添加自己的定义。 CMake
符号 CMAKE_C_FLAGS_DEBUG
可以包含仅在调试模式下使用的标志。例如:
C
:
set(CMAKE_C_FLAGS_DEBUG "$CMAKE_C_FLAGS_DEBUG -DMY_DEBUG")
C++
:
set(CMAKE_CXX_FLAGS_DEBUG "$CMAKE_CXX_FLAGS_DEBUG -DMY_DEBUG")
然后您可以在代码中编写以下内容:
#ifdef MY_DEBUG
// ...
#endif
(也许,您必须将 "/DMY_DEBUG"
用于 Visual Studio。)
【讨论】:
我很想为你的用户名投票,但我投票反对,因为我不喜欢重新做你的工具已经为你完成的工作,根据另一个答案,NDEBUG
是由 CMake 定义的,所以更可取。
NDEBUG
是 C 标准定义的符号,用于控制 assert()
:s 是否应该处于活动状态。就个人而言,我认为您不应该将其用于其他任何事情。 (感谢您对用户名的称赞。)
我也反对使用NDEBUG
。 FWIW,添加宏定义的正确方法(至少现在)是add_definitions(-DMY_DEBUG)
。 documentation 表明它将 -
或 /
识别为前缀,因此它应该与操作系统无关。
@JasonLefler,不幸的是,使用add_definition()
不会解决 OPs 问题,因为它会将定义添加到所有配置中,而不仅仅是 Debug
。
@Lindydancer,你说得对,我认为会有一个if
开关设置CMAKE_BUILD_TYPE
等等。为了贡献一些有用的东西,我已经确认 add_definition
将解析 -
和 /
,但 set
ting 手动标记不会。【参考方案3】:
在 CMake >= 2.8 中,使用 target_compile_definitions
:
target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")
在调试模式下编译时,这将定义在您的代码中使用的调试符号。它甚至可以在 Visual Studio 和 Xcode 等 IDE 中工作,cmake 会为所有编译模式生成一个文件。
您必须为每个目标 [1] 执行此操作。或者,您可以使用add_compile_options
(Cmake >= 3.0):
add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>")
请注意,最新版本的 Visual C++(至少自 VS2015 起)允许使用 / 或 - 作为参数,因此它应该可以跨编译器正常工作。此命令对于您可能希望添加的其他编译选项也很有用(MSVC 的发布模式为“/O2”,G++/Clang 的发布模式为“-O3”)
[1] :注意:在 CMake >= 3.12(当前为测试版)中,还有一个支持生成器表达式的 add_compile_definitions
,它会影响所有目标。
【讨论】:
以上是关于#ifdef DEBUG 与 CMake 独立于平台的主要内容,如果未能解决你的问题,请参考以下文章
#ifdef _DEBUG 在 vs 2008 中的发布模式
如何使用Cmake生成debug版本和release版本的程序