17

I used to work with VSCode C/C++ extension. there was a feature in this extension(in a json file), called "includePath", which I could set the paths for my headers, so without execution of CMake or make, I would have the suggestion of my headers and code completion from those.

now I have switched to neovim and clangd as the language server for code completion. I searched a lot to find the corresponding feature in clangd options but I could not find anything more than this link.

since the clangd is a powerful language server, I am in wonder if there is not such a feature in it. so I want to know is there actually such a feature in clangd? and if YES how can I use that?

Note: I use a language client, called "coc-clangd". I don't know if it matters or not.

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
AMIR REZA SADEQI
  • 409
  • 2
  • 5
  • 13
  • 3
    You need to provide `compiler_commands.json`, see: https://clangd.llvm.org/installation.html – HolyBlackCat Apr 14 '20 at 11:41
  • I know that. but I use the catkin_make(ROS platform) which automatically generates CMake files and then I generate compile_commands.json base on it. so if I want to automate the process I can't use this file for doing that. – AMIR REZA SADEQI Apr 14 '20 at 12:33

5 Answers5

12

Clangd uses compile_commands.json database file which contains flags (such as include directories) for each file in project. But this file is auto-generated, so all modifications to it will be overwritten eventually. You can ask CMake to add any custom compile flags with -DCMAKE_CXX_FLAGS command line argument.

Example for system headers (#include <file.h>):

cmake -DCMAKE_CXX_FLAGS="-isystem /path/to/includes" /path/to/source

For project headers (#include "file.h"):

cmake -DCMAKE_CXX_FLAGS=-Ipath/to/includes /path/to/source

Additionally, you can set CXXFLAGS environment variable:

export CXXFLAGS="-isystem /path/to/includes"
cmake path/to/sources

After that new flags should appear in your compile_commands.json file.

lufterd
  • 406
  • 5
  • 7
  • 2
    FYI if you need to generate `compile_commands.json` you can use `bear -- make` to generate it. – Alex Aug 18 '22 at 18:47
  • This worked for me, I was having a similar issue but with standard libraries like `#include `, I was struggling to know which paths to use for system headers, I ran this to know the include paths `gcc -H mySrcFile.cpp`, this is how I run CMake now `mkdir -pv $BUILD_DIR && cd $BUILD_DIR && cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_CXX_FLAGS="-isystem /usr/include/c++/11/ -isystem /usr/include/x86_64-linux-gnu/c++/11/" && make run` – Simon Puente Mar 05 '23 at 07:25
11

Maybe this is useful: https://clangd.llvm.org/config

Create a file called '.clangd' in the top-level of the source directory. Add those content.

CompileFlags: # Tweak the parse settings
  Add: 
    - "-I=[folder]"

But I think this is not recommend, all include directories should be add in CMakeLists.txt file.

hideDragon
  • 344
  • 2
  • 5
  • 6
    Note: if you use clangd in Visual Studio Code you will have to add `--enable-config` to `Clangd: Arguments` in VS Code settings for it to use the .clangd file [source](https://blogs.igalia.com/aboya/2021/10/02/setting-up-visualstudio-code-to-work-with-webkitgtk-using-clangd/). Also I found that `"-I=path/to/dir"` did not work but `"--include-directory=path/to/dir"` did work. – Gabriel Devillers Mar 12 '22 at 16:17
  • @hideDragon I presume that all include directories that you add in `CMakeLists.txt` file are then also inside the `compile_commands.json`. But! I think that you should create `.clangd` file nevertheless! This is because in this configuration file you first **point** the `clangd` to the `compile_commands.json` using the command `CompileFlags:` and it's member `CompilationDatabase: ./build` *(if your `compile_commands.json` is inside the `build` sub folder of your project)* ([link](https://clangd.llvm.org/config#compilationdatabase)) and from there onwards it can function on it's own... – 71GA Mar 09 '23 at 13:09
8

You can add includePath to clangd.fallbackFlags into vscode's settings.json like this:

"clangd.fallbackFlags": [
    "-I${workspaceFolder}/include",
    "-I/my/include"
]
Allen Shaw
  • 1,164
  • 7
  • 23
5

To use code completion provided by Clangd, let Clangd retrieve include paths from compiler_commands.json with compiler calls used by CMake. Set the CMAKE_EXPORT_COMPILE_COMMANDS option in CMakeLists.txt, it will output compiler_commands.json to the build directory when CMake is run:

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Copy the generated compiler_commands.json to the project source directory. Clangd will now source this file.

linwownil
  • 69
  • 1
  • 3
  • So does one have to add include paths to `cmake` first and then `cmake` will include these include paths in the `compiler_commands.json` when it auto generates it? – 71GA Mar 09 '23 at 09:00
  • copying the `compiler_commands.json` to the workspace directory did not help. I'm testing this on oxen-io/oxen-core. – Martin Braun Aug 09 '23 at 22:44
1

You can use CPATH environment variable. Syntax is the same as PATH variable.

export CPATH="your/include:more/include:/usr/include"
Obsidian
  • 3,719
  • 8
  • 17
  • 30
Maksym
  • 11
  • 1