There is a way of distributing C/C++ libraries as a one header-only file. Library is in one library.h
file: header declarations together with implementation hidden under #ifdef LIBRARY_IMPL
. You need to create some .c
/.cpp
file that does #define LIBRARY_IMPL; #include "library.h"
which creates compilation unit with implementation.
I have a project which uses such libraries extensively. Project build system creates compile_commands.json
which is then used by clangd
to provide project paths, data structures and hints to VSCode (with llvm-vs-code-extensions.vscode-clangd).
The issue I have is when opening the library.h
file for editing, the symbol LIBRARY_IMPL
is not defined, thus the #ifdef LIBRARY_IMPL
section is treated as comment – without syntax highlighting, type checking etc.
Is there a way to tell clangd
or the extension to treat the file as it was during compilation of the library.c
wrapper file, not stand-alone .h file?
2
Answers
You can use the
defines
field of thec_cpp_properties.json
file to set#define
s in a way thatclangd
can see. Here is the full schema reference. The relevant portion isThis is where you would put your
LIBRARY_IMPL
. Yourc_cpp_properties.json
file should be in the top level directory of your project folder.A simple way would be to create a
.clangd
file in your project’s root directory, containing:This instructs clangd to add the flag
-DLIBRARY_IMPL
(which has the effect of defining the macroLIBRARY_IMPL
) to any compile command used when opening a file in your project.Note, for this to be effective,
library.h
needs to be located in the directory tree of your project (because the.clangd
file will only apply to files in that directory tree).If
library.h
is located outside the project directory, an alternative approach would be to create a user config file containing the same thing, but this time you probably want to make it conditional on the file’s path:You can read more about clangd config files at https://clangd.llvm.org/config.html.