style
esc
  • Loading…

Check itC++ Style Guide lint kit

Conventions for writing, structuring, formatting and shipping modern C++23 that builds clean on MSVC, Clang and GCC.

Download the kit 39 checks · rule IDs on every finding

Checks a C++ codebase against the C++ Style Guide and reports every finding with its rule ID, linked to the rule:

Engine/src/Engine/Gpu/Shader.h:1:1: MUST CPP-07.1: start every header with #pragma once, not an include guard [chopper]
Engine/src/Engine/Gpu/Shader.cpp:42:5: MUST NOT CPP-08.1: no `new` outside allocators and containers; use CreateScope / CreateRef [chopper]

It runs three kinds of check:

  • clang-format with the guide's .clang-format (chapter 6).
  • clang-tidy with the guide's .clang-tidy, when it finds a compile_commands.json. With Premake: premake5 ninja, then ninja -t compdb > compile_commands.json (or bear -- make with the Makefiles). With CMake: -DCMAKE_EXPORT_COMPILE_COMMANDS=ON. Build once before linting, so generated files such as the precompiled header exist; the kit says so when clang-tidy could not compile a file.
  • The guide's own checks for rules neither tool expresses: #pragma once, using namespace in headers, relative includes, macro prefixes, // namespace X comments, platform headers outside Platform/, test file placement, TODO owners, log format strings, assert messages and more. checks.json lists them all.

The repository's own .clang-format and .clang-tidy are used when it has them; otherwise the kit's copies (the guide's appendix, verbatim) are.

Run it

Needs Python 3.9+, and clang-format and clang-tidy 19 for the tool checks (pip install clang-format~=19.1.0 clang-tidy~=19.1.0 works everywhere).

python3 chopper_lint.py                       # the current folder
python3 chopper_lint.py Engine/src Sandbox    # some folders
python3 chopper_lint.py --compile-commands build/compile_commands.json
python3 chopper_lint.py --code ENG --strict   # set the macro prefix; fail on SHOULD too
python3 chopper_lint.py --list-checks         # what it checks

Folders named vendor, third_party, external, build, bin and bin-int are skipped, as are generated *.gen.* files.

Exit status: 1 when a MUST or MUST NOT rule is broken (any finding with --strict), else 0.

In GitHub Actions

- uses: actions/checkout@v4
- uses: carson-hopper/chopper.dev/content/styleguides/cpp/lint@main
  with:
    paths: Engine/src Sandbox/src
    # compile-commands: build/compile_commands.json   # enables clang-tidy

Findings appear as annotations on the pull request. Pin @main to a commit SHA for reproducible runs.

Silencing a finding

On the same line or the line above, with a reason:

auto* block = new (storage) Block();  // chopper-lint: allow CPP-08.1 (pool allocator)

For a whole file: // chopper-lint: allow-file CPP-08.1.