CMake templates

Table of Contents

This page is the literate source for the cmake facet of the codegen template library. Each section documents one template and holds its source in a mustache block tangled to the sibling .mustache file consumed by generator.py. The .mustache files are generated artefacts — edit this document, then run the tangle (compass build --direct tangle_codegen_templates or the emacs script directly). Output paths and profile membership come from facet_catalogue.org.

Summary

Eight templates generate the CMake build files for a component: cmake_component_root for the component root, four *_src variants for the lib / api / core / service flavours of src/CMakeLists.txt, cmake_component_tests for the Catch2 test target, and cmake_component_modeling for the PlantUML diagram target. cmake_service_src is currently referenced by no profile and no code — retained pending the profiles-drift audit.

The cmake facet

In MASD terms a facet is a coherent family of artefacts generated from a model element — one projection of the model onto a concern such as the domain types, the repository, the SQL schema, or, here, the build system. Where the entity facets (entity lifecycle) project an entity model onto C++ and SQL, the cmake facet projects a component onto its CMake build files: which targets exist, what they link, and how tests and diagrams are wired into the global run_all_tests / make_all_diagrams aggregation targets.

The facet's shape follows the api/core/service component split described in component architecture: every component gets the same root, tests, and modeling files, while src/CMakeLists.txt varies by component flavour — that is why there are four *_src variants but only one of each of the others. The component, component-api, component-core and component-service profiles in facet_catalogue.org select the right variant; the other three templates are shared by all four profiles.

Mustache incantations

The templates use a small, deliberate subset of Mustache, rendered by pystache from generator.py's render_template:

{{#component}}{{/component}}
section. Renders its body with the component object pushed onto the context stack, so bare names inside resolve against the component first. It also guards: if component were missing the body would render empty rather than fail.
{{full_name}}
escaped interpolation, resolved against the context stack (the enclosing component). HTML-escaping is a no-op for the names that appear here, so the double-stache is safe for identifiers.
{{{cmake_license}}}
triple-stache (unescaped interpolation). The licence header is multi-line text containing characters HTML-escaping would mangle (quotes, angle brackets), so it must be injected verbatim. Supplied by the generator's standard data, not by the component model.
{{! … }}
comment. Renders to nothing; per the Mustache spec a comment standing alone on a line is removed together with the line, which is what makes the GENERATED FILE header on each template output-neutral.

CMake's own ${var} syntax passes through Mustache untouched — braces only become magic when doubled — so the templates freely mix the two without escaping.

Archetypes

Archetype Description
cmake_component_root.mustache Tiny dispatcher: the component root CMakeLists.txt just descends into src/, tests/ and modeling/. Used by every component profile (component, component-api, component-core, component-service); output projects/{component_full}/CMakeLists.txt.
cmake_component_src.mustache src/CMakeLists.txt for a plain library component (component profile): one shared library from all *.cpp under src/, with the database/utility/sqlgen dependency set. Output projects/{component_full}/src/CMakeLists.txt.
cmake_component_api_src.mustache src/CMakeLists.txt for an .api component (component-api profile): pure-types library linking only the eventing/platform public surface. Output projects/{component_full}/src/CMakeLists.txt.
cmake_component_core_src.mustache src/CMakeLists.txt for a .core component (component-core profile): links its sibling api library ({{api_full_name}}.lib) publicly plus the NATS/service stack privately. Output projects/{component_full}/src/CMakeLists.txt.
cmake_component_service_src.mustache src/CMakeLists.txt for a .service component (component-service profile): splits the sources into a library (everything except main.cpp, linking the sibling core via {{core_full_name}}.lib) and the service executable (main.cpp only). Output projects/{component_full}/src/CMakeLists.txt.
cmake_component_tests.mustache tests/CMakeLists.txt for every component profile: a Catch2 test executable from all *.cpp under tests/, the test_<name> custom target wired into run_all_tests, and the CTest registration with XML output. (The repeated boilerplate across the 65 per-component test files is the subject of the centralise-test-target capture.) Output projects/{component_full}/tests/CMakeLists.txt.
cmake_component_modeling.mustache modeling/CMakeLists.txt for every component profile: the generate_<name>_diagram PlantUML target, wired into make_all_diagrams. Output projects/{component_full}/modeling/CMakeLists.txt.
cmake_service_src.mustache Library + executable split like the service flavour, but with no sibling core dependency — the pre-regroup standalone-service shape. Referenced by no profile and no code; retained pending the facet-catalogue staleness audit (see the facet_catalogue.org stale-outputs capture). If the audit confirms it is dead, delete this section and the artefact together.

See also

Emacs 29.1 (Org mode 9.6.6)