reddit / emacs

How to pass arguments to clang-tidy?

NoisyFrequency · 2022-02-07 12:40
Edit : fixed, without a specific build system, using a `compile_flags.txt` ([see docs here](https://clangd.llvm.org/installation#compile_flagstxt)) with one argument per line, gets picked up by `clangd`. -Wall -pedantic --std=c++17 Hi, I'm using LSP-mode for C++ and I can't find how to pass arguments to `clang-tidy`. It's annoying because I'd like to use C++17 functionalities which `flycheck` flags as illegal (though they are not). My config does have `(lsp-clients-clangd-args '("--clang-tidy"))` but I don't know how to pass arguments to `clang-tidy`, through `clangd`. Any combination I could think of, of `'("--clang-tidy --std=c++17")`, `'("--clang-tidy" "--std=c++17")`, `'("--clang-tidy -extra-arg=-std=c++17")`,... failed. I thought about using a `.clang-tidy` file instead but there's no example [of such a file](https://clang.llvm.org/extra/index.html) in the `clang-tidy` docs. Any help would be appreciated! P.S: This issue can be reproduced with any post C++17 feature, such as `std::optional`.
zaywolfe · 2022-02-07 15:03
Eagerly watching this so I can disable automatic header inclusion. Nearly everytime I finish coding I look at top and find 20 unnecessary includes automatically inserted without me knowing. I hope other people find this as annoying as I do.
northgaard1 · 2022-02-07 17:00
This is unrelated to clang-tidy. You can disable it by adding `”—-header-insertion=never”` to `lsp-clients-clangd-args`.
ForkInBrain · 2022-02-08 05:53
Clangd has a dot file you can put in the root of your project. I think it is called .clangd. With it you can set clang-tidy options that will be in effect for clangd only. You can also use the .clang-tidy file, which will set options for both clangd and clang-tidy. See also the output of clang-tidy —dump-config. Trying to set these tools up by setting emacs config vars is probably not a great idea. It can be pretty handy to run clang-tidy from the command line, for example, if only to debug the config options. The docs can be sparse but I found useful examples on the web, usually stack overflow, with targeted queries. All the clang tooling uses the same YAML based config file approach and they seem to document it inconsistently. Ping this reply if you want more info and I can paste my relatively small configs in the morning You’ll also want to generate a compile_commands.json file, btw. This is how you’d actually pass things like -std=c++17 to clangd. The best way to get this set up depends on your build system.
NoisyFrequency · 2022-02-08 09:56
I've tried to turn on all the options and then dump the file to `.clang-tidy` but it seems there's still no explicit parameter to set which C/C++ standard is used for the static analysis. Also, I'm not even sure where and how `lsp-mode` picks those files. Sure, please do share your .dot files, I'd be happy to go through them! I usually build with `make` but I'll move over to `cmake` when I have the time.
ForkInBrain · 2022-02-08 21:12
It sounds to me like you have a handle on the `.clangd` and `.clang-tidy` files, but I think the piece your missing is that clangd's idea of the compiler options being used is not controlled by `.clangd` or `.clang-tidy` configs. The compiler flags `clangd` and `clang-tidy` pick to compile with are controlled by yet another configuration file called the "compilation database". You'll need to set this up external to anything related to `lsp-mode`. If you're still on `make` check out the "bear" tool linked on this page: See https://clang.llvm.org/docs/JSONCompilationDatabase.html. You'll eventually want a `compile_commands.json` file somewhere, probably in the root directory of your workspace (next to the .git dir, etc.). The clang tools look for it there by default. Or, if you just want a quick and dirty solution for a simple project, try just a `compile_commands.txt` file: https://clang.llvm.org/docs/JSONCompilationDatabase.html#alternatives I've never done this. Here is an excerpt from my `compile_commands.json`: ``` },{ "file": "ravl/tree.cxx", "command": "/usr/lib/llvm-13/bin/clang --language=c++ -U_FORTIFY_SOURCE -fstack-protector -Wall -Wthread-safety -Wself-assign -Wunused-but-set-parameter -Wno-free-nonheap-object -fcolor-diagnostics -fno-omit-frame-pointer -std=c++0x -MD -MF bazel-out/k8-fastbuild/bin/ravl/_objs/tree/tree.pic.d -frandom-seed=bazel-out/k8-fastbuild/bin/ravl/_objs/tree/tree.pic.o -fPIC -iquote . -iquote bazel-out/k8-fastbuild/bin -Wextra -Werror -stdlib=libc++ -std=gnu++20 -no-canonical-prefixes -Wno-builtin-macro-redefined -D__DATE__=\"redacted\" -D__TIMESTAMP__=\"redacted\" -D__TIME__=\"redacted\" -c ravl/tree.cxx -o bazel-out/k8-fastbuild/bin/ravl/_objs/tree/tree.pic.o", "directory": "/home/matt/git/treeplay" },{ ``` cmake can generate one of these files for you, based on your build. Or, that "bear" tool can watch a make invocation and generate one. Because I wanted to experiment with C++20 features, and some of those features differ between gcc and clang (especially with respect to coroutines), I had to set up my `compile_commands.json` to use clang and LLVM's libc++ even though I normally build with gcc and GNU libstdc++.
holgerschurig · 2022-02-08 21:34
You can stay at make if you really wish and use bear with it. It can be used with any compilation system to create the compilation database. And beside, Meson is better than cmake :-)
NoisyFrequency · 2022-02-08 23:31
Thanks for the references, I'll dig into that! It's a bit destabilizing how many different configuration files need to be setup in order for a project to work as expected though.
NoisyFrequency · 2022-02-08 23:31
I'll look it up, thank you!
ForkInBrain · 2022-02-08 23:48
The complexity comes in part from the extreme flexibility projects have with how they express code in files and how their build system is set up. That and no standard build system for C or C++. :-) oh, if you’re not into cmake, meson can generate compile_commands.json for you too
NoisyFrequency · 2022-02-08 23:54
You're the second person to mention Meson, I'll have to check it out with my teammate then =)
NoisyFrequency · 2022-02-10 20:43
/u/yyoncho Any idea where the static linter looks up the `C/C++` version?
yyoncho · 2022-02-11 08:29
I believe you are supposed to pass that info via compile_commands.json
NoisyFrequency · 2022-02-11 10:20
This seems to be what is passed to the compiler but not to the static linter though, I'm not sure how this works, the `clang` docs are pretty confusing in that regard imo
yyoncho · 2022-02-11 11:12
clagnd has discord channels, you may ask your questions there.
NoisyFrequency · 2022-02-11 11:17
will do thanks!