Search code examples
clangconfigneovimcoc.nvimclangd

How to configure clangd to find missing external header file?


I am a novice user of clang tools and I am learning c/c++.


I have some code that is based on a framework that uses its data structure and build system ( OpenFOAM). I compiled the framework's libraries in a folder in home directory. This framework has bunch of directory that keep all the header files of classes as symbolic links in it. I use neovim and coc extention as client, and clangd as language server.

The problem is, in my code clangd finds some of the header files and not all. What could be the reason for this behavior? and how can I either fix it or get rid of diagnostics in my editor.

I read the help provided with clangd (clangd --help) and turns out there's a flag, --header-insertion=<string>, which if I set the <string> to iwyu (for, Include what You Use), I can get rid of the warnings like this. According to the help, I can configure clangd via a config.yaml file in the ~/.config/clangd folder (xdg system in linux). The thing is, how can I edit this file to obtain the effect of aforementioned flag. I simply placed that flag in the file but nothing has changed. Basically what I want is, either config clangd to search for the header files in a directory recursively, Or If that is not possible get rid of the diagnostic warnings of missing header files that it cannot find.

Another thing that I don't know is, how to restart the server to re-read the config. Should I just terminate current process and re-run it?


Feel free to edit the question.

Further info:

  • OS: artixlinux
  • NVIM: v0.5.0-dev+1225-gbbdd00203
  • CLANGD: v11.1.0

Solution

  • As I said, the project I'm working on does not use CMake as its main build system.

    There are (to my knowledge) two ways to fix it.

    1. The bear utility which generates a compile_commands.json file. You have to provide a build command and I believe it will parse the output of that build system to generate the file.

      # bear -- <build command>
      
      # In my case
      bear -- wmake
      
    2. Create a compile_flags.txt file at the root of the project, by hand and add all the necessary flags, including paths to directories that contain header files with -I

      -std=c++14
      -m64
      -g
      -IlnInclude
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/OpenFOAM/lnInclude
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/OSspecific/POSIX/lnInclude
      -fPIC
      -I/opt/homebrew/include
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/atmosphericModels/lnInclude
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/fvOptions/lnInclude
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/renumber/renumberMethods/lnInclude
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/mesh/extrudeModel/lnInclude
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/mesh/snappyHexMesh/lnInclude
      -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/mesh/blockMesh/lnInclude
      
    3. Create a local clangd config file (.clangd) at the root of your project, with the following content (add whatever compiler flags you need):

      If:
        PathMatch: .*\.cpp
      
      CompileFlags:
        Add: [-std=c++20, -Wall, -Wextra,  -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/OpenFOAM/lnInclude]
      
      ---
      
      If:
        PathMatch: .*\.c
      
      CompileFlags:
        Add: [-std=c2x, -Wall, -Wextra,  -I/Volumes/OpenFOAM/OpenFOAM-v2206/src/OpenFOAM/lnInclude]