CMake Preset Best Practices for Build Types

I am trying to convert my project from using Visual Studio Code Extension specific cmake-kits.json to leveraging the CMake supported, CMakePresets. My project builds for a couple different toolchains, but shares some common cache options. A slightly stripped down version looks like this…

{
    "version": 3,
    "cmakeMinimumRequired": {
        "major": 3,
        "minor": 21,
        "patch": 0
    },
    "configurePresets": [
        {
            "name": "default",
            "description": "Default configuration",
            "hidden": true,
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build/${presetName}",
            "cacheVariables": {
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
                "OTHER_COMMON_OPTION": "ON"
            }
        },
        {
            "name": "linux",
            "inherits": "default",
            "toolchainFile": "${sourceDir}/tools/cmake/toolchains/linux.cmake"
        },
        {
            "name": "qnx",
            "inherits": "default",
            "toolchainFile": "${sourceDir}/tools/cmake/toolchains/qnx.cmake"
        }
    ]
}

For the most part, this works great. The only challenge or contrast I have to my previous configuration with the VS Code CMake Extension is the build directory structure. Previously this would’ve looked like this…

build
  - linux
    - Debug
    - Release
  - qnx
    - Debug
    - Release

With unique build directories for each platform and build type. This is beneficial on my project where it’s common to switch between debug/release builds. In this situation, sharing the same build directory for different platforms or build types would require re-builds more often. In VS code, I could define a setting like "cmake.buildDirectory": "${workspaceFolder}/build/${buildKit}/${buildType}". However, with CMakePresets binaryDir option, I’m not sure how to accomplish this. It’d be nice to be able to have an option in the base preset like "binaryDir": "${sourceDir}/build/${presetName}/${buildType}", but I don’t think such an option exists. I understand part of the challenge is that build type is just a cache variable. Effectively any macro Presets like ${cache:CMAKE_BUILD_TYPE} might be difficult (if not impossible) to implement.

Is my only option to make different presets for each build type (linux-debug, linux-release, qnx-debug, qnx-release, qnx-relwithdeb, etc.)? I’m curious to hear how others have approached this challenge? How do others specify build type in their CMakePresets?

1 Like

I use the “Ninja Multi-Config” generator so this is not an issue since all the build types come from the same binary directory.