#ifdef与CMake独立于平台的DEBUG

Phi*_*ipp 28 c c++ cmake

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

#ifdef DEBUG
//some logging here
#endif
Run Code Online (Sandbox Code Playgroud)

问题是:CMake"Debug"构建类型中的所有平台上都有哪些编译器定义?DEBUG似乎不存在.(我希望只有在构建类型为Debug时才能进行日志记录或其他任何操作.)

arr*_*owd 89

CMake -DNDEBUG默认添加到CMAKE_C_FLAGS_ {RELEASE,MINSIZEREL}.所以,你可以使用#ifndef NDEBUG.

  • 双重负面是讨厌的:) (15认同)
  • 为什么没有-DDEBUG? (5认同)
  • NDEBUG是由[C标准](http://port70.net/~nsz/c/c11/n1570.html#7.2)定义的含义。它禁用断言。 (2认同)

Lin*_*cer 23

我建议你添加自己的定义.该CMake符号CMAKE_C_FLAGS_DEBUG只能包含在调试模式下使用的标志.例如:

C:

set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DMY_DEBUG")
Run Code Online (Sandbox Code Playgroud)

C++:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DMY_DEBUG")
Run Code Online (Sandbox Code Playgroud)

在您的代码中,您可以编写以下内容:

#ifdef MY_DEBUG
// ...
#endif
Run Code Online (Sandbox Code Playgroud)

(也许,你必须使用"/DMY_DEBUG"视觉工作室.)

  • 我很想为你的用户名投赞成票,但我投了反对票,因为我不喜欢重新做你的工具已经为你完成的工作,根据另一个答案,“NDEBUG”是由CMake,所以它是更好的选择。 (2认同)
  • `NDEBUG`是由C标准定义的符号,用于控制`assert()`:s是否应该是活动的.就个人而言,我认为你不应该将它用于其他任何事情.(感谢您对用户名的称赞.) (2认同)
  • 我也反对使用“NDEBUG”。FWIW,添加宏定义的正确方法(至少现在)是“add_definitions(-DMY_DEBUG)”。[文档](http://www.cmake.org/cmake/help/v3.0/command/add_definitions.html)建议它识别“-”或“/”作为前缀,因此它应该与操作系统无关。 (2认同)
  • @Lindydancer,你是对的,我认为有一个`if`开关设置`CMAKE_BUILD_TYPE`等等.为了贡献一些有用的东西,那么,我已经确认`add_definition`将解析`-`和`/`,但是`set`ing the flags手动不会. (2认同)

jtb*_*tbr 9

在CMake> = 2.8中,使用target_compile_definitions:

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")
Run Code Online (Sandbox Code Playgroud)

在调试模式下编译时,这将定义在代码中使用的DEBUG符号.它甚至可以在像Visual Studio和Xcode这样的IDE中工作,cmake为所有编译模式生成单个文件.

你必须为每个目标做到这一点[1].或者你可以使用add_compile_options(Cmake> = 3.0):

add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>")
Run Code Online (Sandbox Code Playgroud)

请注意,Visual C++的最新版本(至少从VS2015开始)允许使用/或 - for参数,因此它应该在编译器之间正常工作.此命令对于您可能要添加的其他编译选项也很有用(在MSVC的发布模式下为"/ O2",在G ++/Clang中为发布模式为"-O3")

[1]:注意:在CMake> = 3.12(目前为beta)中,还有一个add_compile_definitions支持生成器表达式,它影响所有目标.