【问题标题】:#ifdef DEBUG with CMake independent from platform#ifdef DEBUG 与 CMake 独立于平台
【发布时间】:2012-01-25 09:06:34
【问题描述】:

我正在使用 CMake 在 Windows (Visual Studio) 以及 Linux 机器 (gcc) 上构建我的项目。我想将一些代码标记为“仅调试”,例如

#ifdef DEBUG
//some logging here
#endif

问题是:在 CMake“调试”构建类型的所有平台上,哪些编译器定义可用? DEBUG 似乎不存在。 (我希望只有在构建类型为 Debug 时才具有日志记录或其他内容。)

【问题讨论】:

标签: c++ c cmake


【解决方案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 将解析 -/,但 setting 手动标记不会。
【解决方案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,它会影响所有目标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 2021-09-10
    • 2013-04-05
    相关资源
    最近更新 更多