60

I am using CMake for building my projects on Windows (Visual Studio) as well as on Linux machines(gcc). I'd like to mark some code as "debugging only", like with

#ifdef DEBUG
//some logging here
#endif

The question is: what compiler definition is available on all platforms in the CMake "Debug" build type? DEBUG seems not to exist. (I want to have the logging or whatever only when the build type is Debug.)

arrowd
  • 33,231
  • 8
  • 79
  • 110
Philipp
  • 11,549
  • 8
  • 66
  • 126

4 Answers4

153

CMake adds -DNDEBUG to the CMAKE_C_FLAGS_{RELEASE, MINSIZEREL} by default. So, you can use #ifndef NDEBUG.

arrowd
  • 33,231
  • 8
  • 79
  • 110
38

I would suggest that you add your own definition. The CMake symbol CMAKE_C_FLAGS_DEBUG can contain flags only used in debug mode. For example:

C:

set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DMY_DEBUG")

C++:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DMY_DEBUG")

In your code you can then write the following:

#ifdef MY_DEBUG
// ...
#endif

(Maybe, you would have to use "/DMY_DEBUG" for visual studio.)

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
Lindydancer
  • 25,428
  • 4
  • 49
  • 68
  • 2
    I'm tempted to upvote you for your username, but instead a I downvoted because I'm not a fan of re-doing work that's already done for you by your tools, and according to the other answer, `NDEBUG` is defined by CMake, so it's preferable. – Kyle Strand Apr 09 '15 at 23:30
  • 5
    `NDEBUG` is a symbol defined by the C standard to control whether `assert()`:s should be active or not. Personally, I don't think you should use it for anything else. (Thanks for the compliment regarding the user name.) – Lindydancer Apr 10 '15 at 13:43
  • 2
    I'm against using `NDEBUG`, as well. FWIW, the proper way to add macro definitions (now, at least) is `add_definitions(-DMY_DEBUG)`. The [documentation](http://www.cmake.org/cmake/help/v3.0/command/add_definitions.html) suggests that it recognizes `-` or `/` as prefixes, so it should be OS agnostic. –  Jun 07 '15 at 01:10
  • @JasonLefler, Unfortunately, using `add_definition()` won't solve the OPs problem, since it will add the definition to all configurations, not only to `Debug`. – Lindydancer Jun 08 '15 at 07:03
  • I prefer to use NDEBUG in code and [define own assert](http://stackoverflow.com/questions/22140520/how-to-enable-assert-in-cmake-release-mode) (allow turn on asserts in release mode without using magic to disable NDEBUG) – Wojciech Mleczek Jun 08 '15 at 08:12
  • 4
    @Lindydancer, You're right, I figured there'd be an `if` switch setting `CMAKE_BUILD_TYPE` and such or something. To contribute something useful, then, I've confirmed that `add_definition` will parse `-` and `/`, but `set`ting the flags manually will not. –  Jun 08 '15 at 11:41
  • @JasonLefler, For some of the generators (including the one for Visual Studio) CMake generates one build system which contains both a Debug and a Release configuration. This mean that you can't check `CMAKE_BUILD_TYPE` in your CMake files. Thanks for the info on `-` and `/` in the variables! – Lindydancer Jun 08 '15 at 12:03
  • That's CMAKE_CXX_FLAGS_DEBUG for C++ projects. – jtbr Jul 02 '18 at 12:29
  • @KyleStrand very old, but there is a slight difference between checking NOT (Not Debug) and DEBUG, if i put critical code for debug only, i would want an OPT-IN approach and not the opposite (like off by default if no flags are defined correctly) – Tomer W May 22 '22 at 06:39
31

In CMake >= 2.8, use target_compile_definitions:

target_compile_definitions(MyTarget PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")

When compiling in Debug mode, this will define the DEBUG symbol for use in your code. It will work even in IDEs like Visual Studio and Xcode for which cmake generates a single file for all compilation modes.

You have to do this for each target [1]. Alternatively you can use add_compile_options (Cmake >= 3.0):

add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>")

Note that recent versions of Visual C++ (at least since VS2015) allow either / or - for parameters, so it should work fine across compilers. This command is also useful for other compile options you might like to add ("/O2" in release mode for MSVC or "-O3" for release mode in G++/Clang)

[1] : Note: in CMake >= 3.12 (currently beta) there is also an add_compile_definitions that supports generator expressions, which affects all targets.

legends2k
  • 31,634
  • 25
  • 118
  • 222
jtbr
  • 1,149
  • 13
  • 13
0

I'm using the following in my 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 ()

Then, in my code, I can write:

#ifdef __DEBUG__
    // blablabla
#edif

My minimum CMake version:

cmake_minimum_required(VERSION 3.16.3)
BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185