CMakeToolchain: Extending your CMakePresets with Conan generated ones

In this example we are going to see how to extend your own CMakePresets to include Conan generated ones.

Note

We use CMake presets in this example. This requires CMake >= 3.23 because the “include” from CMakeUserPresets.json to CMakePresets.json is only supported since that version. If you prefer not to use presets you can use something like:

cmake <path> -G <CMake generator> -DCMAKE_TOOLCHAIN_FILE=<path to
conan_toolchain.cmake> -DCMAKE_BUILD_TYPE=Release

Conan will show the exact CMake command everytime you run conan install in case you can’t use the presets feature.

Please, first clone the sources to recreate this project. You can find them in the examples2 repository in GitHub:

$ git clone https://github.com/conan-io/examples2.git
$ cd examples2/examples/tools/cmake/cmake_toolchain/extend_own_cmake_presets

Please open the conanfile.py and check how it sets tc.user_presets_path = 'ConanPresets.json'. By modifying this attribute of CMakeToolchain, you can change the default filename of the generated preset.

def generate(self):
    tc = CMakeToolchain(self)
    tc.user_presets_path = 'ConanPresets.json'
    tc.generate()
    ...

Now you can provide your own CMakePresets.json, besides the CMakeLists.txt:

CMakePresets.json
{
"version": 4,
"include": ["./ConanPresets.json"],
"configurePresets": [
    {
        "name": "default",
        "displayName": "multi config",
        "inherits": "conan-default"
    },
    {
        "name": "release",
        "displayName": "release single config",
        "inherits": "conan-release"
    },
    {
        "name": "debug",
        "displayName": "debug single config",
        "inherits": "conan-debug"
    }
],
"buildPresets": [
    {
        "name": "multi-release",
        "configurePreset": "default",
        "configuration": "Release",
        "inherits": "conan-release"
    },
    {
        "name": "multi-debug",
        "configurePreset": "default",
        "configuration": "Debug",
        "inherits": "conan-debug"
    },
    {
        "name": "release",
        "configurePreset": "release",
        "configuration": "Release",
        "inherits": "conan-release"
    },
    {
        "name": "debug",
        "configurePreset": "debug",
        "configuration": "Debug",
        "inherits": "conan-debug"
    }
]
}

Note how the "include": ["./ConanPresets.json"], and that every preset inherits a Conan generated one.

We can now install for both Release and Debug (and other configurations also, with the help of build_folder_vars if we want):

$ conan install .
$ conan install . -s build_type=Debug

And build and run our application, by using our own presets that extend the Conan generated ones:

# Linux (single-config, 2 configure, 2 builds)
$ cmake --preset debug
$ cmake --build --preset debug
$ ./build/Debug/foo
> Hello World Debug!

$ cmake --preset release
$ cmake --build --preset release
$ ./build/Release/foo
> Hello World Release!

# Windows VS (Multi-config, 1 configure 2 builds)
$ cmake --preset default

$ cmake --build --preset multi-debug
$ build\\Debug\\foo
> Hello World Debug!

$ cmake --build --preset multi-release
$ build\\Release\\foo
> Hello World Release!