#ifdef DEBUG在CMake中独立于平台的使用方法

60

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

#ifdef DEBUG
//some logging here
#endif

问题是:在CMake的“Debug”构建类型中,所有平台都可以使用哪个编译器定义?DEBUG似乎不存在。(我希望只在构建类型为Debug时才记录日志或进行其他操作。)


https://dev59.com/AGsz5IYBdhLWcg3wsaAN#7725055 - Lightness Races in Orbit
4个回答

155

CMake默认会在CMAKE_C_FLAGS_{RELEASE, MINSIZEREL}中添加-DNDEBUG,因此您可以使用#ifndef NDEBUG


47
双重否定很糟糕 :) - entheh
12
为什么没有 -DDEBUG 选项? - simplename
17
NDEBUG 是由C标准定义含义的宏,它用于关闭断言。 - Antti Haapala -- Слава Україні

38
我建议您添加自己的定义。 CMake 符号 CMAKE_C_FLAGS_DEBUG 可以包含仅在调试模式下使用的标志。例如:

C


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

(也许你需要在Visual Studio中使用"/DMY_DEBUG"。)


2
我很想因为你的用户名给你点赞,但我还是选择了踩一下,因为我不喜欢重复已经被工具完成的工作。根据其他答案所说,NDEBUG由CMake定义,所以这更可取。 - Kyle Strand
5
NDEBUG是C标准定义的一个符号,用于控制assert()函数是否应该被激活。个人认为你不应该将其用于其他任何目的。(感谢对用户名的赞美。) - Lindydancer
2
我也反对使用NDEBUG。至于正确的添加宏定义的方法(现在至少是这样),应该是add_definitions(-DMY_DEBUG)文档建议识别-/作为前缀,因此它应该是与操作系统无关的。 - user1236508
我更喜欢在代码中使用NDEBUG并定义自己的断言(允许在发布模式下打开断言,而不使用禁用NDEBUG的魔法)。 - Wojciech Mleczek
4
@Lindydancer,你是对的,我本来以为会有一个设置CMAKE_BUILD_TYPE等的if开关。为了贡献一些有用的东西,我已经确认add_definition将解析“-”和“/”,但手动set标志则不会。 - user1236508
显示剩余4条评论

31

在 CMake >= 2.8 中,请使用 target_compile_definitions 命令:

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:DEBUG>: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”)。
注意:在CMake >= 3.12(目前为测试版)中,还有一个支持生成器表达式的add_compile_definitions,它会影响所有目标。

0
我在我的 CMakeLists.txt 中使用了以下内容:
set(IS_DEBUG_BUILD CMAKE_BUILD_TYPE STREQUAL "Debug")

# Indication to the code that this is a debug build
if (${IS_DEBUG_BUILD})
    add_compile_definitions(__DEBUG__)
endif ()

然后,在我的代码中,我可以写:
#ifdef __DEBUG__
    // blablabla
#edif

我的最低 CMake 版本:

cmake_minimum_required(VERSION 3.16.3)

1
不允许使用以双下划线“__”开头的标识符。 - Raildex
@Raildex:嗯,你可以使用它们,但是可能会因为标准库冲突而不应该这样做。 - BullyWiiPlaza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接