c++cmakecmake-presets

Merge and/or Override flags of different configure presets in CMakePresets.json


I have two configure presets in my CMakePresets.json were I would like to merge the flags of the inherit configurePresets (gcc) with the other preset (gcc-arm-embedded)

Here is a simplified version:

  "configurePresets": [
    {
      "name": "gcc",
      "hidden": true,
      "cacheVariables": {
        "CMAKE_CXX_FLAGS": "-Wall -Wextra",
        "CMAKE_BUILD_TYPE": "Release"
      }
    },
    {
      "name": "gcc-arm-embedded",
      "hidden": true,
      "inherits": ["gcc"],
      "cacheVariables": {
        "CMAKE_CXX_FLAGS": "-ffunction-sections -fdata-sections",
        "CMAKE_EXE_LINKER_FLAGS": "-mcpu=cortex-m7 -mthumb",
        "CMAKE_BUILD_TYPE": "MinSizeRel"
      }
    },
    {
      "name": "embedded",
      "inherits": ["gcc", "gcc-arm-embedded"]
    }
  ]

The problem is, if I use the presets embedded the resulting CMAKE flags are:

CMAKE_CXX_FLAGS: "-Wall -Wextra"
CMAKE_EXE_LINKER_FLAGS: "-mcpu=cortex-m7 -mthumb",
CMAKE_BUILD_TYPE: "Release"

My goal is this:

CMAKE_CXX_FLAGS: "-Wall -Wextra -ffunction-sections -fdata-sections"
CMAKE_EXE_LINKER_FLAGS: "-mcpu=cortex-m7 -mthumb",
CMAKE_BUILD_TYPE: "MinSizeRel"

Is this somehow possible with CMakePresets?


Solution

  • First, simplify the inherits entry to:

    "inherits": ["gcc-arm-embedded"]
    

    The resolution order works left to right, never overwriting, but since gcc-arm-embedded inherits from gcc already, there's no need to specify both. So that gets you to this:

    CMAKE_CXX_FLAGS: "-ffunction-sections -fdata-sections"
    CMAKE_EXE_LINKER_FLAGS: "-mcpu=cortex-m7 -mthumb",
    CMAKE_BUILD_TYPE: "MinSizeRel"
    

    Now let's add a base preset:

        {
          "name": "base",
          "hidden": true,
          "cacheVariables": {
            "CMAKE_CXX_FLAGS": "$env{CXX_WARNINGS} $env{CXX_OPT}",
            "CMAKE_BUILD_TYPE": "Release"
          }
        },
    

    Then make gcc inherit from base and remove the cacheVariables section. Instead, set:

          "environment": {
            "CXX_WARNINGS": "-Wall -pedantic"
          }
    

    and in gcc-arm-embedded additionally set:

          "environment": {
            "CXX_OPT": "-ffunction-sections -fdata-sections"
          }
    

    The end result is this:

    {
      "version": 3,
      "cmakeMinimumRequired": {
        "major": 3,
        "minor": 21,
        "patch": 0
      },
      "configurePresets": [
        {
          "name": "base",
          "hidden": true,
          "cacheVariables": {
            "CMAKE_CXX_FLAGS": "$env{CXX_WARNINGS} $env{CXX_OPT}",
            "CMAKE_BUILD_TYPE": "Release"
          }
        },
        {
          "name": "gcc",
          "inherits": ["base"],
          "hidden": true,
          "environment": {
            "CXX_WARNINGS": "-Wall -pedantic"
          }
        },
        {
          "name": "gcc-arm-embedded",
          "hidden": true,
          "inherits": ["gcc"],
          "cacheVariables": {
            "CMAKE_EXE_LINKER_FLAGS": "-mcpu=cortex-m7 -mthumb",
            "CMAKE_BUILD_TYPE": "MinSizeRel"
          },
          "environment": {
            "CXX_OPT": "-ffunction-sections -fdata-sections"
          }
        },
        {
          "name": "embedded",
          "inherits": ["gcc-arm-embedded"]
        }
      ]
    }