#!/usr/bin/env python3 """Regenerate CMakePresets.json - one uniform pipeline per chip. The tiers reimplement the ATmega328P-only reference protocol, so that is the whole chip list. It stays a generated file rather than a hand-written one because the shape - configure, build, test, workflow, and a reflect pair without tests - is the shape a second chip would need too. Run from the repo root: tools/make_presets.py - or with --check, which verifies the committed file matches this generator and edits nothing (the ctest entry `presets.generated` runs that, so drift reds the gate). """ import json import os import sys CHIPS = [ "atmega328p", ] # The reflect pair: the same chip, built in libavr's other mode. REFLECT_SPOT = [ "atmega328p", ] def main(): configure = [{ "name": "base", "hidden": True, "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "toolchainFile": "${sourceDir}/libavr/cmake/avr-toolchain.cmake", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", "CMAKE_COLOR_DIAGNOSTICS": "ON", }, }] build, test, workflows = [], [], [] def add(chip, mode): name = f"{chip}-{mode}" configure.append({ "name": name, "inherits": "base", "cacheVariables": { "LIBAVR_MCU": chip, "LIBAVR_REFLECT": "ON" if mode == "reflect" else "OFF", }, }) build.append({"name": name, "configurePreset": name}) steps = [{"type": "configure", "name": name}, {"type": "build", "name": name}] if mode == "generated": test.append({"name": name, "configurePreset": name, "output": {"outputOnFailure": True}}) steps.append({"type": "test", "name": name}) workflows.append({"name": name, "steps": steps}) for chip in CHIPS: add(chip, "generated") for chip in REFLECT_SPOT: add(chip, "reflect") # CMake rejects unknown fields in the presets root, $comment included, so # the file cannot carry a generated-file marker; the --check ctest is the # whole of rule 10's guard here. presets = { "version": 8, "configurePresets": configure, "buildPresets": build, "testPresets": test, "workflowPresets": workflows, } rendered = json.dumps(presets, indent=1) + "\n" path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "CMakePresets.json") if "--check" in sys.argv[1:]: current = open(path).read() if os.path.exists(path) else "" if current != rendered: print("CMakePresets.json does not match its generator - run tools/make_presets.py") return 1 return 0 with open(path, "w") as f: f.write(rendered) print(f"{len(CHIPS)} chips, {len(REFLECT_SPOT)} reflect: {os.path.normpath(path)}") return 0 if __name__ == "__main__": sys.exit(main())