Search code examples
c++cmakemakefilebuild-system

How to configure debug and release mode for c++ with cmake


I am trying to set up a c++ project with cmake. I want to be able to compile my project in both release and debug mode, and I therefore want different folders for my executables. Since there are only a few differences that separate the two builds, like compiler flags, I would like them to have as many of the other configurations in common as possible. Ideally my folder structure would look like this:

root/
│
├── src/
│  
├── CMakeLists
│
└── build/
      └── bin/
       │   ├── Debug/
       │   └── Release/
       └──Makefile

In this case, both folders share makefile and cmake configurations files. I have noticed that visual studio does it something like this. However, cmake seems to make me choose between debug and release mode already when running cmake -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release. I does not seems to affect any cmake --build build --config Release, for example when setting the binary output directory.

This stack overflow post suggest having debug and release directly under build and having two completely separate makefiles and cmake configs for the two modes. This would complicate and make the rest of my environment setup quite messy.

For example, doing stuff like this would always resolve to false even with --config Release:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY${CMAKE_BINARY_DIR}/$<IF:$<CONFIG:Debug>,Debug,Release>)

Any pointers on how to achieve this folder structure and correctly implement build modes for c++ with cmake?


Solution

  • cmake is not the visual studio build system.

    I think the opposite of what you say would be true: mixing different builds within the same build try makes things terribly complicated, at it would require re-writing a lot of relative paths, especially with generated targets, within your select build tool, "Makefiles".
    Cmake simply doesn't work that way – a build type is a configuration-wide constant for the Makefiles, Ninja and most other backends (generating a Visual Studio project is the exception).

    You can't have two different build types within one build. So, what you want is plain impossible, without actually doing two cmake runs, two build runs, and copying of files together into a single hierarchy. At which point you really won nothing!

    In this case, both folders share makefile and cmake configurations files.

    Definitely not! Makefiles would necessarily be different – not only would compiler flags differ, there would also be other build artifacts. There's very little to reuse here.

    So, yes, the other source is correct: make two different directories, two different cmake runs in there, one with -DCMAKE_BUILD_TYPE=Release, the other with -DCMAKE_BUILD_TYPE=RelWithDebInfo (or whichever debug type of build you want).