Skip to content

presets: Add expanding/overriding and global environment

Artin Alavi requested to merge Arastais/cmake:improve-presets into master

Add preset expanding/overriding and global environment to cmake-presets(7).

These commits significantly improve cmake-presets by giving developers the ability to specify global environment variables and to override and extend presets with the same name. All of these can be done within CMakePresets.json and CMakeUserPresets.json. A version 7 of cmake-presets has been created (when specifying at least cmake version 3.26) along with unit tests and documentation additions for these changes.

Global environment variables can be set in any presets file, with those specified in CMakeUserPresets.json being able to override those in CMakePresets.json, similar to how normal environment variables work. However, unlike normal environment variables, these global variables would apply to all presets of any type; i.e. all presets would have all global environment variables included as a part of its environment. Global environment variables can also override preset specific environment variables and vice versa.

Overriding presets allows the fields/values of a "child" preset to override those of a "parent" preset of the same name. The child preset in this case would be the preset that specifies the override boolean field. Overriding would essentially work the same as inherits - the only difference being that these two presets have the same name. This basically means that now a preset can inherit another preset of the same name, allowing a total of two presets now with the same name. Any more than two will cause a duplicate error.

To highlight the use case for this, consider how tedious it is for users to extend/override exsiting presets currently. In order for users to be able to specify their own environment variables for example (without just having to create new presets and using those instead), they would currently have to do what is stated in #23046: Developers create hidden presets in the main CMakePresets.json file and version control a "template" file for CMakeUserPresets.json, then said users must use that template file to create their own presets inheriting from the hidden ones. You can find more information on the limitations of cmake-presets currently and use cases for overriding presets in the actual issue page for #23046.

Instead of all that, here is an example of what a setup with global environment variables and could look like:

CMakePresets.json

{
  "version": 7,
  "configurePresets": [
    {
      "name": "MyPreset",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CACHE_VAR": "Original cache variable"
      },
      "environment": {
        "ENV_VAR": "Original environment variable"
      }
    }
  ]
}

CMakeUserPresets.json

{
  "version": 7,
  "environment": {
    "MY_ROOT_PATH": "New environment variable that applies to all presets"
  },
  "configurePresets": [
    {
      "name": "MyPreset",
      "binaryDir": "${sourceDir}/bin",
      "override": true,
      "cacheVariables": {
        "CACHE_VAR": "Overriden cache variable"
      },
      "environment": {
        "ENV_VAR": "Overriden environment variable"
      }
    }
  ]
}

In this scenario, the final variables of the "MyPreset" configure preset for this specific user would have:

${CACHE_VAR}: "Overriden cache variable"
ENV${ENV_VAR}: "Overriden environment variable"
ENV${MY_ROOT_PATH}: "New environment variable that applies to all presets"

The binaryDir of this preset would also be set to ${sourceDir}/bin. This is much simpler than the what's needed to accomplish this same setup in cmake 3.25, as highlighted in #23046.

Fixes: #23046
Topic-rename: preset-global-env

Edited by Brad King

Merge request reports