Because C++ doesn't have a single well-defined build system, clangd
doesn't know how exactly to compile the files you are asking it to - in this case, it doesn't know what headers to include. On some other distros it might "just work" because all headers are lumped together somewhere in /usr/include
or something, and something somewhere tells clangd to just look in there. This isn't the case on NixOS (in fact the headers are not installed at all with your system), and so you have to tell clangd
where to look for them.
Typically, your build system will have that information somehow. The process can vary depending on the build system you are using - some (like CMake or meson) can do it natively, for others you have to resort to a very useful hack called bear
. Judging by your shell.nix
, I would guess it's make
, which doesn't have native compile_commands.json
support, so what you have to do is:
- Add
bear
to yournativeBuildInputs
- Enter the shell again so that you have it in
$PATH
- Run
make clean
(or otherwise ensure there are no build artifacts already present - maybegit clean -fx
but be careful with that) - Run
bear -- make
from the project root.
make
should then build your entire project, compiling every file in the process. bear
will inspect the system calls that make
is executing and determine which commands (and hence which command arguments) it used to compile each file, and create a file called compile_commands.json
recording this information. clangd
should then automatically find that file and use it to figure out which headers (and other arguments) it needs to compile each file.
This is the setup I personally use to hack on Nix itself BTW, and it works great. Although I'm using helix and not neovim, but that shouldn't matter.