Metadata-Version: 2.4
Name: cmake-presets-exploder
Version: 0.1.0
Summary: Automatically generate combinations of different CMake Presets options
Author-email: Harry Mander <harrymander96@gmail.com>
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.9
Requires-Dist: click>=8.1.8
Requires-Dist: pydantic>=2.10.6
Provides-Extra: jinja2
Requires-Dist: jinja2>=3.1.5; extra == 'jinja2'
Provides-Extra: yaml
Requires-Dist: pyyaml>=6.0.2; extra == 'yaml'
Description-Content-Type: text/markdown

# CMake Presets Exploder

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

## Motivation and basic usage

[CMake Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html)
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](https://gitlab.kitware.com/cmake/cmake/-/issues/22538)
specifying multiple presets. For example, suppose you have 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:

```json
{
    "version": 5,
    "configurePresets": [
        {
            "name": "base-config",
            "generator": "Ninja"
        }
        {
            "name": "feature-x-on-gcc",
            "inherits": ["base-config"],
            "cacheVariables": {
                "ENABLE_FEATURE_X": "on"
            },
            "toolchainFile": "gcc"
        },
        {
            "name": "feature-x-off-gcc",
            "inherits": ["base-config"],
            "cacheVariables": {
                "ENABLE_FEATURE_X": "off"
            },
            "toolchainFile": "gcc"
        },
        {
            "name": "feature-x-on-clang",
            "inherits": ["base-config"],
            "cacheVariables": {
                "ENABLE_FEATURE_X": "on"
            },
            "toolchainFile": "clang"
        },
        {
            "name": "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, and 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`:

```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

```bash
cmake-presets-exploder --output CMakePresets.json
```

Which will generate the following `CMakePresets.json`:

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

The template file can also be written in YAML if YAML support is installed and
the `--yaml` option is passed 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:

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

(See [Installation](#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)](https://github.com/thirtytwobits/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!

## 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](https://pipx.pypa.io/stable/installation/) or
(uv)[https://docs.astral.sh/uv/getting-started/installation/] to install the
script into an isolated environment.

```bash
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-explorer` or `uvx cmake-presets-explorer`.

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

```bash
pipx install cmake-presets-exploder[yaml,jinja2]

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

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

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