1

I have a setup with a project written in C that is statically linked with a library. The sources of the library are in a different folder somewhere else on the system. I am using emacs and lsp-mode with clangd as the LSP. Both, the project and the library can be used with LSP just fine, but what I want to do is this: I have a call to a library function in my project sources, and if I use LSP to find the definition of said function I want it to take me to the definition of the function inside my library.

The basic structure on the file system is like this:

 . └── / └── code/ ├── library/ │ ├── .clangd │ └── src/ │ ├── c/ │ │ └── libsource.c │ ├── include/ │ │ └── libsource.h │ └── lib/ │ └── libbinary.lib └── project/ ├── .clangd ├── src/ │ ├── c/ │ │ └── projectsource.c │ └── include/ │ └── projectsource.h └── env/ └── compile_commands.json 

In reality this setup is a bit more complicated with more subfolders in subfolders, but I have broken it down to the important part. The .clangd files only contain configuration on where to find the compile_commands.json of the respective project, i.e in ./env Both code place now work with LSP on their own, if LSP is ran with library or project as their root folder. Where the compile_commands.json contains the flag -I../../library/source/include for the file ../src/c/projectsource.c, the directory for that file is the directory where the compile_commands.json is. (All other paths for that file in the conpile_commands.json are relative to that path.

Let’s now say libsource.c contains the implementation of a function int libfunc(void){} and libsource.h contains the declaration of that function int libfunc(void); project_source.c includes libsource.h and contains a call of libfunc(); somewhere in its code. Having point on libfunc(); and using LSPs find definition, it takes me into the header. Because the LSP server running in the folder project it does know about header because of the -I../../… line in the compile_commands.json for that file, but it doesn’t know about the source file containing the implementation of the libfunc(void) function.

Can I tell lsp-mode/ Clangd that is running in the project directory where that other compile_commands.json of the library is, so it indexes those files as well?

I tried using the folder code as the project root for LSP, but then it can not find the implementation of the libfunc either.

1 Answer 1

0

While not a very "nice" solution, one approach that will make this work is to have a single compile_commands.json file at code/compile_commands.json, containing entries from both project and library, instead of one for each.

The combined code/compile_commands.json file could be created by something like a post-build script that uses a tool like jq to combine the original compile_commands.json files. (The original compile_commands.json files then need to be deleted or renamed to force clangd to search in the ancestor directory to find the combined one.)


Another approach that not's exactly what you're looking for but worth knowing about: with separate compile_commands.json files in project/ and library/, if some source file in library/ has already been opened during your editor session, then clangd will have loaded library/compile_commands.json, and now "knows about" the definitions in the source files in library/, and so go-to-definition from calls in project/ should target them correctly.


What is missing, to make the approach with separate compile_commands.json files work exactly the way you want, is some way to tell clangd that when opening a file in project/, it should load project/compile_commands.json and library/compile_commands.json. I'm not aware of a way to do this today.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.