Skip to main content

cpp-linter-hooks

PyPI ci coverage part of cpp-linter

pre-commit hooks that pip-install the clang-format and clang-tidy version you pin, on every developer's machine.

Website · Get started · Discussions

Quick start

Add this configuration to your .pre-commit-config.yaml file:

repos:
  - repo: https://github.com/cpp-linter/cpp-linter-hooks
    rev: v1.6.1
    hooks:
      - id: clang-format
        args: [--style=file, --version=21]
      - id: clang-tidy
        args: [--version=21]

Run pre-commit install once in each clone. --style=file loads the style from your .clang-format file, and clang-tidy reads your .clang-tidy file by itself. The clang-tidy hook needs a compile_commands.json, which it looks for in build/ and a few other directories (see Compilation database); leave it out if you only run clang-tidy in CI, for example with cpp-linter-action.

Usage

Custom clang tool version

  • --version=21 installs the newest 21.x wheel, and --version=21.1.8 pins an exact release. clang-tidy wheels are released separately from clang-format wheels and skip some releases, so give clang-tidy the major version.
  • clang-format wheels cover LLVM 6 to 23 and clang-tidy wheels LLVM 13 to 22. For a version without a wheel, the hook fails and lists some of the versions that exist.
  • The hook looks the version up on pypi.org every time it runs. Without network access it fails when --version is set, and otherwise uses the clang-format or clang-tidy already installed.

clang-format

To use a predefined coding style instead of your .clang-format file:

      - id: clang-format
        args: [--style=Google] # Other coding style: LLVM, GNU, Chromium, Microsoft, Mozilla, WebKit.

When clang-format changes a file, the hook fails and pre-commit stops the commit:

clang-format.............................................................Failed
- hook id: clang-format
- files were modified by this hook

Here’s a sample diff showing the formatting applied with --style=Google:

--- a/testing/main.c
+++ b/testing/main.c
@@ -1,3 +1,6 @@
 #include <stdio.h>
-int main() {for (;;) break; printf("Hello world!\n");return 0;}
-
+int main() {
+  for (;;) break;
+  printf("Hello world!\n");
+  return 0;
+}
clang-format.............................................................Failed
- hook id: clang-format
- exit code: 1

main.c:2:13: error: code should be clang-formatted [-Wclang-format-violations]
int main() {for (;;) break; printf("Hello world!\n");return 0;}
            ^
main.c:2:21: error: code should be clang-formatted [-Wclang-format-violations]
int main() {for (;;) break; printf("Hello world!\n");return 0;}
                    ^
main.c:2:28: error: code should be clang-formatted [-Wclang-format-violations]
int main() {for (;;) break; printf("Hello world!\n");return 0;}
                           ^
main.c:2:54: error: code should be clang-formatted [-Wclang-format-violations]
int main() {for (;;) break; printf("Hello world!\n");return 0;}
                                                     ^
main.c:2:63: error: code should be clang-formatted [-Wclang-format-violations]
int main() {for (;;) break; printf("Hello world!\n");return 0;}
                                                              ^

clang-tidy

To set the checks in args instead of your .clang-tidy file, quote the whole option: inside [...], YAML splits an unquoted value at each comma.

      - id: clang-tidy
        args: ["--checks=boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*,clang-analyzer-*,cppcoreguidelines-*"]

When clang-tidy reports a warning or an error, the hook fails:

clang-tidy...............................................................Failed
- hook id: clang-tidy
- exit code: 1

522 warnings generated.
Suppressed 521 warnings (521 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
/home/runner/work/cpp-linter-hooks/cpp-linter-hooks/testing/main.c:4:13: warning: statement should be inside braces [readability-braces-around-statements]
    for (;;)
            ^
             {
repos:
  - repo: https://github.com/cpp-linter/cpp-linter-hooks
    rev: v1.6.1  # includes --fix support
    hooks:
      - id: clang-tidy
        args: [--fix]

Compilation database

For CMake or Meson projects, clang-tidy works best with a compile_commands.json file that records the exact compiler flags used for each file. Without it, clang-tidy may report false positives from missing include paths or wrong compiler flags.

The hook auto-detects compile_commands.json in common build directories (build/, out/, cmake-build-debug/, _build/) and passes -p <dir> to clang-tidy automatically — no configuration needed for most projects:

repos:
  - repo: https://github.com/cpp-linter/cpp-linter-hooks
    rev: v1.6.1
    hooks:
      - id: clang-tidy
        # Auto-detects ./build/compile_commands.json if present

To specify the build directory explicitly:

      - id: clang-tidy
        args: [--compile-commands=build]

To disable auto-detection (e.g. in a monorepo where auto-detect might pick the wrong database):

      - id: clang-tidy
        args: [--no-compile-commands]

Examples

Two self-contained templates plus quick snippets for other common setups.

Troubleshooting

Performance optimization

- repo: https://github.com/cpp-linter/cpp-linter-hooks
  rev: v1.6.1
  hooks:
    - id: clang-format
      args: [--style=file, --version=21]
      files: ^(src|include)/.*\.(cpp|cc|cxx|h|hpp)$ # Limits to specific dirs and file types
    - id: clang-tidy
      args: [--version=21]
      files: ^(src|include)/.*\.(cpp|cc|cxx|h|hpp)$

For clang-tidy, you can also process multiple files in parallel by adding --jobs or -j:

- repo: https://github.com/cpp-linter/cpp-linter-hooks
  rev: v1.6.1
  hooks:
    - id: clang-tidy
      args: [--version=21, --jobs=4]

Alternatively, if you want to run the hooks manually on only the changed files, you can use the following command:

pre-commit run --files $(git diff --name-only)

This approach ensures that only modified files are checked, further speeding up the linting process during development.

Verbose output

repos:
  - repo: https://github.com/cpp-linter/cpp-linter-hooks
    rev: v1.6.1
    hooks:
      - id: clang-format
        args: [--style=file, --version=21, --verbose]   # Shows processed files
      - id: clang-tidy
        args: [--verbose]   # Shows which compile_commands.json is used

Compared with mirrors-clang-format

mirrors-clang-format is pre-commit's mirror of the clang-format wheel.

Feature cpp-linter-hooks mirrors-clang-format
Supports clang-format and clang-tidy Both clang-format only
Custom configuration files .clang-format, .clang-tidy .clang-format
Specify tool version via --version arg (e.g. --version=21) via rev tag (e.g. rev: v21.1.8)
rev tag meaning Project version, not the tool version Equals the clang-format version directly
Default file types C, C++ C, C++, C#, CUDA, Java, JavaScript, JSON, Objective-C, proto, textproto, Metal
Supports passing format style string via --style via --style
Verbose output via --verbose via --verbose
Dry-run mode via --dry-run via --dry-run --Werror
Auto-fix mode via --fix (clang-tidy only) No
Compilation database support auto-detect or --compile-commands No

Used by

These organizations run cpp-linter-hooks on their default branch:

MIT ACL · Bazel Contrib · CodSpeed · doldecomp · HKUST Aerial Robotics · Kubewarden · Computational Geography · IMSY · CONVINCE-Project

The showcase lists more projects that use cpp-linter tools.

Contributing

See the contributing guide and open an issue for bugs and feature requests.

License

This project is licensed under the MIT License.

Metadata

Release files for cpp-linter-hooks 1.6.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for cpp-linter-hooks 1.6.1
File Interpreter ABI Platform
cpp_linter_hooks-1.6.1-py3-none-any.whl Python 3 none any Details

Release files / cpp_linter_hooks-1.6.1-py3-none-any.whl

Download URL cpp_linter_hooks-1.6.1-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2920e7385eca7b25e88135f0d88c3bd91a3188b6b4d5ce6884cf2b2e6930dcf5
BLAKE2b-256 checksum
How to use checksums
b859e8e8417f3d94d4757e8eb6bf8af3d4cc70475a4915512b4c1a4ec77e6e05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

1.6.1 This release

1 release file

1.6.0

1 release file

1.5.0

1 release file

1.4.1

1 release file

1.4.0

1 release file

1.3.1

1 release file

1.3.0

1 release file

1.2.0

1 release file

1.1.14

1 release file

1.1.13

1 release file

1.1.12

1 release file

1.1.11

1 release file

1.1.10

1 release file

1.1.9

1 release file

1.1.8

1 release file

1.1.7

1 release file

1.1.6

1 release file

1.1.5

1 release file

1.1.4

1 release file

1.1.3

1 release file

1.1.2

1 release file

1.1.1

1 release file

1.1.0

1 release file

1.0.1

1 release file

1.0.0

1 release file

0.8.3

1 release file

0.8.2

1 release file

0.8.1

1 release file

0.8.0

1 release file

0.7.0

1 release file

0.6.1

1 release file

0.6.0

1 release file

0.5.1

1 release file

0.5.0

1 release file

0.4.1

1 release file

0.4.0

1 release file

0.3.0

1 release file

0.2.10

1 release file

0.2.9

1 release file

0.2.8

1 release file

0.2.7

1 release file

0.2.6

1 release file

0.2.5

1 release file

0.2.4

1 release file

0.2.2

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page