Search code examples
clinuxmakefilelanguage-server-protocolclangd

Why is clangd not seeing my custom library location


Problem Statement:

I have a library installed in a custom location, and compilation and linkage works properly, but clangd is reporting various errors related to the custom lib.

My Makefile has the following flags:

CFLAGS += -I/usr/local/share/mylib                             
LDFLAGS += -lmylib -L/usr/local/lib/
...
<snip>

However, clangd doesn't know how to find the header file and therefore my editor is showing errors like the following where it is unhelpful:

#include <mylibheader.h>    'mylibheader.h' file not found

mylib_type1_t foo                     unknown type name 'mylib_type1_t'

...
<snip>

searching the internet for the errors and keywords clangd, clangd config, clangd .clang-format failed to produce anything useful on SO or elsewhere (hence this question).

The question is:

How do I tell clangd where my non-standard headers are so that it won't show bogus "file not found" warnings?


Solution

  • tl;dr:

    add compile flags to compile_flags.txt (small project) or for a more complicated project generate compile_commands.json. See instructions here.

    Example: my compile_flags.txt contains:

    -I/usr/local/share/mylib
    -lmylib
    -L/usr/local/lib/
    

    If you don't want to make one by hand, you can use a tool to generate this for you such as bear.

    How Did I Troubleshoot?

    man 1 clangd gives a useful hint for inspecting output

           --check[=<string>]                 - Parse one file in isolation instead of acting as a language server. Useful to investigate/reproduce crashes or configu‐
                  ration problems. With --check=<filename>, attempts to parse a particular file.
    

    Some output of clangd --check=src/main.c:

    E[13:12:40.787] [pp_file_not_found] Line 10: 'mylibheader.h' file not found
    
    E[13:12:40.820] [unknown_typename] Line 187: unknown type name 'mylib_type1_t'
    E[13:12:40.820] [unknown_typename] Line 202: unknown type name 'mylib_type1_t'
    E[13:12:40.820] [undeclared_var_use] Line 820: use of undeclared identifier 'mylib_type2_t'
    ...
    <snip>
    

    Adding pp_file_not_found to my search terms led me to this very helpful issue*, which has a comment that says:

    Looks like you don't have a compile_flags.txt or compilation_database.json set up. That file tells clangd where to find include files, you can check project setup guide for details.

    • Note that I am not using coc-neovim, but rather using Neovim's builtin lsp server, so this question doesn't directly relate but happens to have my solution.

    Linux Kernel:

    Generate compile_commands.json using ./scripts/clang-tools/gen_compile_commands.py after compiling (uses .cmd files).