Canonical project guidance for AI agents (Cursor, Claude Code, Copilot, etc.). Tool-specific files in this repo are thin adapters; do not duplicate this content elsewhere.
C++ library template (mb.cpp-lib-template): static library by default, optional header-only mode. Demonstrates professional CMake layout, FetchContent lockfile deps, GoogleTest, examples, install/find_package, and CI via the devenv git submodule (devmarkusb/devenv).
- CMake project name:
mb.cpp-lib-template(must stayvendor.lib— two dot-separated segments formb_devenv_install_library). - Namespace:
mb::cpp_lib_template - Public headers:
include/mb/cpp-lib-template/ - Implementation:
src/(omitted whenMB_CPP_LIB_TEMPLATE_HEADER_ONLY=ON) - C++ standard: 26 for GCC/Clang presets; 23 for
msvc-*andappleclang-*inCMakePresets.json - Submodule required:
devenv/— rungit submodule update --init --recursiveafter clone
scripts/new-cpp-lib.py instantiates a new library from this template; treat template-renaming logic there as authoritative when generating new projects.
Prerequisites: CMake 3.30+, Ninja, compatible toolchain. Initialize submodules first.
git submodule update --init --recursive
cmake --preset gcc-debug
cmake --build --preset gcc-debugAlternate (same binary dir layout build/<presetName>/):
cmake --preset clang-debug
cmake --build build/clang-debugCommon configure presets: gcc-debug, gcc-release, clang-debug, clang-release, clang-libc++-debug, clang-libc++-release, appleclang-debug, appleclang-release, msvc-debug, msvc-release. List all: cmake --list-presets.
CMakeUserPresets.json is gitignored and may add local presets (e.g. IDE-specific); do not commit it.
Configure with tests enabled (MB_CPP_LIB_TEMPLATE_BUILD_TESTS=ON, default when top-level):
ctest --preset gcc-debugOr after build:
ctest --test-dir build/gcc-debug --output-on-failureTests live in src/*.test.cpp and register via mb_devenv_add_test (GoogleTest).
Pre-commit (.pre-commit-config.yaml): trailing whitespace, JSON/YAML checks, markdownlint, codespell, ruff/pyupgrade on Python, gersemi (CMake), clang-format (C/C++).
After CMake configure, hooks are installed by mb-pre-commit (from fetchcontent-lockfile.json). Run the full hook sweep:
cmake --preset gcc-debug # once, if not configured
cmake --build --preset gcc-debug --target mb-pre-commit-sweepEquivalent: ninja -C build/gcc-debug mb-pre-commit-sweep.
Manual (if pre-commit is on PATH): pre-commit run -a.
clang-format: .clang-format (LLVM-based). clang-tidy: .clang-tidy at repo root; optional review via devenv:
python3 devenv/scripts/clang-tidy-review.py changed
python3 devenv/scripts/clang-tidy-review.py full --preset clang-debugRequires a configured preset with compile_commands.json. Use --install on supported platforms if clang-tidy is missing.
README uses CMake configure + mb-pre-commit-sweep for pre-commit setup.
| Path | Role |
|---|---|
CMakeLists.txt, CMakePresets.json |
Top-level build, presets, options |
fetchcontent-lockfile.json |
Pinned FetchContent deps (GTest, mb-pre-commit, dot-clangformat/tidy) |
cmake/ |
find_package config template |
include/mb/cpp-lib-template/ |
Public API headers (FILE_SET) |
src/ |
Library .cpp and *.test.cpp |
examples/ |
Example executables linking the library |
devenv/ |
Submodule: toolchains, CI workflow reuse, helper scripts |
scripts/new-cpp-lib.py |
Template → new library generator |
.github/workflows/ |
CI entrypoints (delegate to devenv reusable workflows) |
build/ |
Out-of-tree build output (gitignored) |
Not a monorepo; no nested AGENTS.md unless a subtree gains a different toolchain.
- Match existing style:
mb::cpp_lib_templatenamespace, snake_case for functions, include guard macros with unique suffix in headers. - CMake options use prefix
MB_CPP_LIB_TEMPLATE_*; library targetmb.cpp-lib-template, aliasmb::cpp-lib-template. - Prefer
mb_devenv_*helpers fromdevenv/cmakeover ad hoc CMake. - New tests: GoogleTest in
src/*.test.cpp, registered throughmb_devenv_add_test. - Python in
scripts/targets 3.10+ (pyupgrade hook). - When renaming for a real project, follow the checklist at the top of
CMakeLists.txtor usescripts/new-cpp-lib.py.
- Add or update tests for behavior changes in
src/*.test.cpp. - Run
ctest --preset <same-as-build>before claiming done. - CI runs preset tests (Linux/macOS/Windows) and extended sanitizer/coverage matrices via
devenvworkflows — localgcc-debugis the usual fast check.
- Secrets / local env:
.env, credentials, tokens - Lockfiles:
fetchcontent-lockfile.json,devenv/fetchcontent-lockfile.json(pins CI reproducibility) - Generated / build output:
build/,compile_commands.jsonat repo root, FetchContent trees underbuild/**/_deps/ - Submodule content:
devenv/— prefer PRs to devmarkusb/devenv; only touch here for integration glue in the parent repo - User-local CMake:
CMakeUserPresets.json(gitignored) - CI release / deployment:
.github/workflows/*unless the task is CI-related; reusable workflow logic lives upstream indevenv - Vendored / fetched code: Do not hand-edit populated dependencies under
build/
- No secrets in repo, commits, or agent config.
- Do not weaken CI, sanitizers, or hook checks without explicit request.
pre-commit-check.ymlusespull_request_targetfor reviewdog permissions — do not broaden token scopes casually.
- Submodules initialized if CMake/devenv paths were used
- Build and tests run for the preset you used (or note why skipped)
-
mb-pre-commit-sweepor equivalent hooks considered for touched file types - No edits to lockfiles,
devenv/internals, or CI unless requested - Changes scoped to the task; template rename rules respected if touching names/paths