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:

  1. cmake <path> -G <CMake generator> -DCMAKE_TOOLCHAIN_FILE=<path to
  2. 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:

  1. $ git clone https://github.com/conan-io/examples2.git
  2. $ 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.

  1. def generate(self):
  2. tc = CMakeToolchain(self)
  3. tc.user_presets_path = 'ConanPresets.json'
  4. tc.generate()
  5. ...

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

CMakePresets.json

  1. {
  2. "version": 4,
  3. "include": ["./ConanPresets.json"],
  4. "configurePresets": [
  5. {
  6. "name": "default",
  7. "displayName": "multi config",
  8. "inherits": "conan-default"
  9. },
  10. {
  11. "name": "release",
  12. "displayName": "release single config",
  13. "inherits": "conan-release"
  14. },
  15. {
  16. "name": "debug",
  17. "displayName": "debug single config",
  18. "inherits": "conan-debug"
  19. }
  20. ],
  21. "buildPresets": [
  22. {
  23. "name": "multi-release",
  24. "configurePreset": "default",
  25. "configuration": "Release",
  26. "inherits": "conan-release"
  27. },
  28. {
  29. "name": "multi-debug",
  30. "configurePreset": "default",
  31. "configuration": "Debug",
  32. "inherits": "conan-debug"
  33. },
  34. {
  35. "name": "release",
  36. "configurePreset": "release",
  37. "configuration": "Release",
  38. "inherits": "conan-release"
  39. },
  40. {
  41. "name": "debug",
  42. "configurePreset": "debug",
  43. "configuration": "Debug",
  44. "inherits": "conan-debug"
  45. }
  46. ]
  47. }

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):

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

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

  1. # Linux (single-config, 2 configure, 2 builds)
  2. $ cmake --preset debug
  3. $ cmake --build --preset debug
  4. $ ./build/Debug/foo
  5. > Hello World Debug!
  6. $ cmake --preset release
  7. $ cmake --build --preset release
  8. $ ./build/Release/foo
  9. > Hello World Release!
  10. # Windows VS (Multi-config, 1 configure 2 builds)
  11. $ cmake --preset default
  12. $ cmake --build --preset multi-debug
  13. $ build\\Debug\\foo
  14. > Hello World Debug!
  15. $ cmake --build --preset multi-release
  16. $ build\\Release\\foo
  17. > Hello World Release!