Skip to main content

Automatically generate combinations of different CMake Presets options

Project description

CMake Presets Exploder

PyPI version Python versions Tests status License: MIT

A simple Python tool to automatically generate combinations of different CMake Presets options.

Motivation and basic usage

CMake Presets are a useful tool for specifying and sharing configuration, build, and test settings for CMake Projects. Many editors and IDEs, such as Visual Studio Code, can integrate with presets files.

However, some projects have a large number of different configuration and build options, and CMake currently doesn't support specifying multiple presets. For example, suppose you have a project with a compile-time option called ENABLE_FEATURE_X, and you need to support compilation with both GCC and Clang toolchains. You would need to create a separate preset for each combination of feature and toolchain:

{
  "version": 5,
  "configurePresets": [
    {
      "name": "base-config",
      "generator": "Ninja"
    },
    {
      "name": "configure-feature-x-on-gcc",
      "inherits": ["base-config"],
      "cacheVariables": {
        "ENABLE_FEATURE_X": "on"
      },
      "toolchainFile": "gcc"
    },
    {
      "name": "configure-feature-x-off-gcc",
      "inherits": ["base-config"],
      "cacheVariables": {
        "ENABLE_FEATURE_X": "off"
      },
      "toolchainFile": "gcc"
    },
    {
      "name": "configure-feature-x-on-clang",
      "inherits": ["base-config"],
      "cacheVariables": {
        "ENABLE_FEATURE_X": "on"
      },
      "toolchainFile": "clang"
    },
    {
      "name": "configure-feature-x-off-clang",
      "inherits": ["base-config"],
      "cacheVariables": {
        "ENABLE_FEATURE_X": "off"
      },
      "toolchainFile": "clang"
    }
  ]
}

Now, suppose you add a new feature ENABLE_FEATURE_Y, or want to configure different build configurations such as Debug, Release, or support different config generators (such as Ninja and Visual Studio). The number of presets increases exponentially, which would be tedious and error-prone to maintain manually.

This tool automates the 'combinatorial explosion' of presets given a template file. For example, the above config file could be generated by creating a file named CMakePresetsMatrixTemplate.json:

{
  "version": 5,
  "configurePresets": [
    {
      "name": "base-config",
      "generator": "Ninja",
      "hidden": true
    }
  ],
  "vendor": {
    "exploder": {
      "version": 0,
      "presetGroups": {
        "configure": {
          "type": "configure",
          "inherits": ["base-config"],
          "parameters": {
            "feature-x": {
              "feature-x-on": "on",
              "feature-x-off": "off"
            },
            "toolchainFile": ["gcc", "clang"]
          },
          "templates": {
            "feature-x": {
              "cacheVariables": {
                "ENABLE_FEATURE_X": "$value"
              }
            }
          }
        }
      }
    }
  }
}

And then running

cmake-presets-exploder --output CMakePresets.json

Which will generate the following CMakePresets.json:

{
  "version": 5,
  "configurePresets": [
    {
      "name": "base-config",
      "generator": "Ninja",
      "hidden": true
    },
    {
      "name": "configure-feature-x-feature-x-on",
      "hidden": true,
      "cacheVariables": {
        "ENABLE_FEATURE_X": "on"
      }
    },
    {
      "name": "configure-feature-x-feature-x-off",
      "hidden": true,
      "cacheVariables": {
        "ENABLE_FEATURE_X": "off"
      }
    },
    {
      "name": "configure-toolchainFile-gcc",
      "hidden": true,
      "toolchainFile": "gcc"
    },
    {
      "name": "configure-toolchainFile-clang",
      "hidden": true,
      "toolchainFile": "clang"
    },
    {
      "name": "configure-feature-x-on-gcc",
      "inherits": [
        "base-config",
        "configure-feature-x-feature-x-on",
        "configure-toolchainFile-gcc"
      ]
    },
    {
      "name": "configure-feature-x-on-clang",
      "inherits": [
        "base-config",
        "configure-feature-x-feature-x-on",
        "configure-toolchainFile-clang"
      ]
    },
    {
      "name": "configure-feature-x-off-gcc",
      "inherits": [
        "base-config",
        "configure-feature-x-feature-x-off",
        "configure-toolchainFile-gcc"
      ]
    },
    {
      "name": "configure-feature-x-off-clang",
      "inherits": [
        "base-config",
        "configure-feature-x-feature-x-off",
        "configure-toolchainFile-clang"
      ]
    }
  ]
}

The template file can also be written in YAML or TOML if YAML or TOML support is installed and yaml or toml are passed to the --loader option on the CLI.

Jinja2 templating is also optionally supported. As a contrived example, the ENABLE_FEATURE_X option above could be capitalised with the following:

{
  "templates": {
    "feature-x": {
      "cacheVariables": {
        "ENABLE_FEATURE_X": "{jinja}{{ value | upper }}"
      }
    }
  }
}

(See Installation for how to install optional dependencies.)

Run cmake-presets-exploder --help for more information on the different CLI options.

(More documentation to follow...)

Other tools

This tool was directly inspired by Scott Dixon's TCPM (The CMake Preset Matrix), which supports more complex configuration generation. The project is still under active development, so if you find you have more complex needs, check out that project!

Pre-commit hook

A pre-commit hook is provided for running the tool when changes to the CMakePresets.json or CMakePresetsMatrixTemplate.json files are committed, preventing the files from going out of sync from one another. To use it, add the following to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/harrymander/cmake-presets-exploder
    rev: v0.3.1  # replace with desired tag (must be at least v0.3.1)
    hooks:
      - id: cmake-presets-exploder

Installation

Available from PyPI under cmake-presets-exploder, which provides a script with the same name for running the tool. I recommend using a tool such as pipx or uv to install the script into an isolated environment.

pipx install cmake-presets-exploder

# or
uv tool install cmake-presets-exploder

You can also just run the script directly without installing it to PATH with pipx run cmake-presets-exploder or uvx cmake-presets-exploder.

To install optional YAML, TOML, and/or Jinja2 support, install with the yaml and jinja2 extras. E.g.

pipx install cmake-presets-exploder[yaml,toml,jinja2]

# or
uv tool install cmake-presets-exploder[yaml,toml,jinja2]

(Note that Python 3.11 and higher has built-in TOML support, so installing the toml extra on those versions has no effect.)

To install the latest development version, pass the Git URL, e.g.

uv tool install git+https://github.com/harrymander/cmake-presets-exploder.git

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cmake_presets_exploder-0.3.1.tar.gz (46.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cmake_presets_exploder-0.3.1-py3-none-any.whl (12.6 kB view details)

Uploaded Python 3

File details

Details for the file cmake_presets_exploder-0.3.1.tar.gz.

File metadata

File hashes

Hashes for cmake_presets_exploder-0.3.1.tar.gz
Algorithm Hash digest
SHA256 51aea2767be20663f509a0c466b5117c9aad0f7b79dc10909bd9fcc3775ceab1
MD5 a689df64b60cdfa26339efdcf30262b5
BLAKE2b-256 b5965953dcb15e151b8f8dbaf2bdf83d4c8554ec8f01e1f3b1ad277796c90af6

See more details on using hashes here.

File details

Details for the file cmake_presets_exploder-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for cmake_presets_exploder-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a2a740c1ad6c7e217796a19bede766fbe77942c102c5f4dd12a61551a247dca2
MD5 a13f2d20efb9e4de193e3bc6742105b8
BLAKE2b-256 d2328dd9031592998aedf9cfa9d5a46746e6c7e95e65c9ac97866aca5cc991da

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page