# clang-tidy

## clang-tidy

[**clang-tidy**](https://clang.llvm.org/extra/clang-tidy/) is a linter for Protobuf and C, C++.

You can enable the clang-tidy linter with:

```shell
trunk check enable clang-tidy
```

### Auto Enabling

clang-tidy will be auto-enabled if a `.clang-tidy` config file is present.

### Settings

clang-tidy supports the following config files:

* `.clang-tidy`

You can move these files to `.trunk/configs` and `trunk check` will still find them. See [Moving Linters](https://docs.trunk.io/code-quality/overview/configure-linters#moving-linters) for more info. Trunk Code Quality provides a default `.clang-tidy` if your project does not already have one.

### Usage Notes

We only support using clang-tidy from Bazel and CMake projects.

In order to only see issues in your own code, not from library header files your code includes, add this to your `.clang-tidy` file:

```yaml
HeaderFilterRegex: \./.+
```

You may have to build your project first if you depend on any generated header files.

## Linter Failures

If a file you're linting does not compile, clang-tidy may fail to process it. In `trunk`, this will show up as a *Linter Failure*. The output you'll see will look like a compilation error. This can also happen if the pre-reqs to running clang-tidy haven't been met (see below).

## Using Bazel

By default Trunk will query `bazel` for compile commands used to run `clang-tidy`. This requires no configuration.

Trunk will build needed compilation pre-requisites before invoking `clang-tidy` on each file (e.g. generated protobuf headers).

You can generate a local compilation database by running `trunk generate-compile-commands`.

**Finding the bazel binary**

Trunk will search for the `bazel` binary in two ways.

* Paths relative to the workspace root.
* Binaries in any of the directories in the PATH environment variable.

First trunk will search all workspace root relative paths and then all system directories. If you override anything in `lint.bazel.paths` then we only search the paths you specify. By default the configuration is as follows.

```yaml
lint:
  bazel:
    paths:
      workspace:
        - tools/bazel
        - bazelisk
      system:
        - bazel
        - bazelisk
```

## Using `compile_commands.json` generated by CMake

Trunk supports using the `compile_commands.json` file generated by CMake. If you run `cmake` from a directory called `build` in the root of your project then Trunk will find the compile commands automatically. If you run it in some other directory then you will have to symlink the `compile_commands.json` in that directory to the root of your repo for trunk to find them. Note that Trunk does not currently support CMake out of tree builds.

## Another tool claims I have clang-tidy issues, but not Trunk. What gives?

Trunk runs `clang-tidy` with a compile commands database so that we can guarantee clang-tidy produces the correct diagnostics about your code. Other tools, such as `clangd`, may use best-effort heuristics to guess a compile command for a given clang-tidy input file (for example, see [this discussion)](https://github.com/clangd/clangd/issues/519) and consequently produce incorrect clang-tidy findings because they guessed the compile command wrong.

### Links

* [clang-tidy site](https://clang.llvm.org/extra/clang-tidy/)
* clang-tidy Trunk Code Quality [integration source](https://github.com/trunk-io/plugins/tree/main/linters/clang-tidy)
* Trunk Code Quality's [open source plugins repo](https://github.com/trunk-io/plugins/tree/main)
