cmakecmake-presets

How to add a user specific cache variable to a configure preset from CMakePresets.json?


I have this CMakePresets.json:

{
    "version": 5,
    "configurePresets": [
        {
            "name": "MSVC-VS-2022-x64",
            "displayName": "MSVC-VS-2022-x64",
            "description": "Ninja Multi-Config Build",
            "generator": "Ninja Multi-Config",
            "binaryDir": "${sourceParentDir}/${sourceDirName}Build",
            "cacheVariables": {
                "CMAKE_VS_VERSION_RANGE": "[17.0,18.0)",
                "CMAKE_CONFIGURATION_TYPES": "Debug;Release"
            }
        }
    ],
    "buildPresets": [
        {
            "name": "Debug",
            "displayName": "Debug",
            "configurePreset": "MSVC-VS-2022-x64",
            "configuration": "Debug"
        },
        {
            "name": "Release",
            "displayName": "Release",
            "configurePreset": "MSVC-VS-2022-x64",
            "configuration": "Release"
        }
    ]
}

I want to enable our developers to add a cache variable ACTIVE_SUBSETS with a user specific value A;B;C to the configure presets MSVC-VS-2022-x64.

I tried to use this CMakeUserPresets.json:

{
    "version": 5,
    "configurePresets": [
        {
            "name": "MSVC-VS-2022-x64",
            "cacheVariables": {
                "ACTIVE_SUBSETS": "A;B;C"
            }
        }
    ]
}

But this apparently creates a new configure preset instead of modifying the existing one.

CMake Error: Could not read presets from C:/tt/SourceRoot:

Duplicate preset: "MSVC-VS-2022-x64"

What does my CMakeUserPresets.json need to look like to overwrite or add values within a configure preset?

It would also be fine to copy CMakePresets.json and rename it to CMakeUserPresets.json and then modify it. Unfortunately, both files always seem to be loaded.

Analogous to the cache variables, an environment variable and the binaryDir should also be able to be overwritten.


Solution

  • Once preset is defined, it cannot be overriden. It can only be inherited when define new presets.

    If you want to define a preset in CMakePresets.json and allow a user to customize some of its properties via separate file, then you could inherit some other preset, which will be located in the separate file. That separate file cannot be CMakeUserPresets.json, because presets in that file cannot be inherited by a preset in CMakePresets.json. But you could create any other file for that purpose:

    CMakeCustomizablePresets.json:

    {
        "version": 5,
        "configurePresets": [
            {
                "name": "CustomizableBase",
                "description": "Here you could add cache variables, environment variables which you want additionally to see in the predefined presets"
            }
        ]
    }
    

    and include that file into CMakePresets.json:

    CMakePresets.json:

    {
        "version": 5,
        "include": [
          "CMakeCustomizablePresets.json"
        ],
        "configurePresets": [
            {
                "name": "MSVC-VS-2022-x64",
                "displayName": "MSVC-VS-2022-x64",
                "description": "Ninja Multi-Config Build",
                "inherits": [
                   "CustomizableBase"
                ],
                "generator": "Ninja Multi-Config",
                "binaryDir": "${sourceParentDir}/${sourceDirName}Build",
                "cacheVariables": {
                    "CMAKE_VS_VERSION_RANGE": "[17.0,18.0)",
                    "CMAKE_CONFIGURATION_TYPES": "Debug;Release"
                }
            }
        ],
        "buildPresets": [
            {
                "name": "Debug",
                "displayName": "Debug",
                "configurePreset": "MSVC-VS-2022-x64",
                "configuration": "Debug"
            },
            {
                "name": "Release",
                "displayName": "Release",
                "configurePreset": "MSVC-VS-2022-x64",
                "configuration": "Release"
            }
        ]
    }
    

    A user could modify CustomizableBase preset locally and add ACTIVE_SUBSETS variable:

    CMakeCustomizablePresets.json (modified):

    {
        "version": 5,
        "configurePresets": [
            {
                "name": "CustomizableBase",
                "description": "Here you could add cache variables, environment variables which you want additionally to see in the predefined presets",
                "cacheVariables": {
                    "ACTIVE_SUBSETS": "A;B;C"
                }
            }
        ]
    }
    

    So configuring with MSVC-VS-2022-x64 preset will use that variable.

    Note, that if you want to allow a user to customize binaryDir field of the preset, you need to delete that field from MSVC-VS-2022-x64 preset in CMakePresets.json file and add the field into CustomizableBase preset in CMakeCustomizablePresets.json file. Otherwise, value of the field in MSVC-VS-2022-x64 preset will unconditionally overwrite the inherited value from CustomizableBase preset.