Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMakePresets.json vs CMakeSettings.json vs CMakeLists.txt

There are a lot of tutorials on how to use CMakePresets, CMakeSettings, and CMakeLists, but I'm struggling to understand which one needs to be used for a particular project. As far as I understand, they all have some overlap in features, such as defining environment variables or CMake variables.

What I've generally understood is that CMakePresets and CMakeSettings are Microsoft "tools" for the integration of a CMake project in Visual Studio or Visual Studio Code, etc. How do they compare with CMakeLists, and what exactly is the scope/use of each one?

like image 675
Buzz Avatar asked Nov 21 '25 06:11

Buzz


2 Answers

Every project needs to have a CMakeLists.txt file that configures the CMake project. You can learn more step-by-step by following the official CMake tutorial. Here's a tutorial on CMakeLists.txt files by CLion.

CMakePresets.json is an optional, builtin CMake feature. It is not a Microsoft-specific thing. It's a tool to allow writing up presets for configuration, build, test, and packaging settings that are commonly used together. That's what it's useful for. Ex. filling in option() variables (that are defined in the project's CMakeLists.txt file), or other cache and environment variables. Presets are basically a tool to not have to write many commonly-used-together commandline arguments for common user scenarios and instead have a shortcut/alias for them.

CMakeSettings.json is specific to Visual Studio. You can use it when building projects specifically with Visual Studio. It has some similar capabilities as CMakePresets.json files, but is much more oriented to work with Visual Studio IDE configuration. The official docs recommend that it no longer be used, and that CMakePresets.json be used instead.


Here's an analogy for what presets are and when they're useful: Imagine a project is like a sandwich shop where you pick what ingredients you want in the sandwich (what options you want to choose when configuring the project build). Let's say one sandwich shop has (among many other ingredients), bacon, lettuce, tomato, and cucumber, which are the ingredients you like to have in your sandwich. The list of all the possible ingredients to choose from is defined (explicitly or implicitly) by the project(s)'s CMakeLists.txt file(s)*. You could sort of say that the CMakeLists.txt files plus CMake itself are the shop. The shop owner (project maintainer(s)) notice that many people like to order sandwiches with bacon, lettuce, and tomato together, so they make a preset: "B.L.T.". So now, you can tell them what you want faster: Instead of bacon, lettuce, tomato, and cucumber, you can say: "I want a B.L.T. with cucumbers" (Ex. cmake --preset=BLT -DWITH_CUCUMBERS=YES ...). Now imagine a different shop with many more ingredients, and you often ordering the same thing with many more ingredients. Can you see how that would be useful? Now- not all customers will commonly want the same thing, and the "official" presets are determined by the shop owner (the project maintainers commit a CMakePresets.json file to their project repo), but you might want to have some custom presets. That's what the CMakeUserPresets.json file is for (never committed to project repo. In .gitignore).

So how do you choose what settings to put in the CMakeLists.txt versus a CMakePresets.json if you choose to create one? If you are 100% certain that one specific value for something (a CMake variable, an environment variable, etc.) will always be the desired value to be used and nobody will want anything different, then hardcode it in the CMakeLists.txt (Ex. target_compile_features, when a target's interface or internal sources require a specific language version to use / build). Otherwise, use the appropriate mechanism (Ex. set(... CACHE ...), option(), if(DEFINED ...)) to define the setting with an overridable default value in the CMakeLists.txt and leave the choice up to the user at configuration time, and if useful, provide some preset bits to help them / yourself out.

More examples: Here are some things that I generally wouldn't hardcode in a CMakeLists.txt file, but I would put in certain presets: CMAKE_CONFIGURATION_TYPES, CMAKE_EXPORT_COMPILE_COMMANDS, CMAKE_COLOR_DIAGNOSTICS, CMAKE_DEFAULT_BUILD_TYPE- at least- not except within an if(NOT DEFINED ...) block.


*This is not really true, but I simplified for the analogy, and sort of alluded towards the whole truth in saying CMake itself is part of the shop. General compiler options or definitions to apply to all source files, link options to apply to all linker invocations, environment variables that affect build tooling like the compiler or linker, general CMake behaviour options (Ex. variables that start with "CMAKE_"), etc. are also options available to the user running build configuration (our "sandwich shop customer"). In that sense, CMake, the compiler, linker, and any other involved build tooling like sanitizers, static analyzers, compiler caches, and so on are also defining avilable "sandwich ingredients" to pick from. There can be a very large space of available options.

Note that if you only need to generate one buildsystem for a project on one machine, you may not feel much need for presets. CMake's cache will remember the options you specified when performing configuration. But presets will be handy if you are generating multiple buildsystems with similar configuration options, or use similar options to build the project on multiple machines, or if you find need to wipe the generated buildsystem and regenerate it. If you have certain kinds of options you want to specify for all your project builds on your machine user, look into available user-scopable options like environment variables defined by CMake or by your build tooling.

like image 142
starball Avatar answered Nov 22 '25 18:11

starball


CMakeSettings.json was the first config setup for Visual Studio, but recent versions of Visual Studio can use either CMakePresets.json OR CMakeSettings.json, and they now recommend the use of CMakePresets.json (see the documentation)

We recommend CMakePresets.json as an alternative to CMakeSettings.json. Visual Studio never reads from both CMakePresets.json and CMakeSettings.json at the same time.

Since CMakePresets.json is now both recommended by Microsoft, and is also the more standard/cross-platform solution, I think we can consider CMakeSettings.json to be effectively deprecated at this point.

like image 28
muusbolla Avatar answered Nov 22 '25 19:11

muusbolla



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!