skip to Main Content

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


  1. You can use the defines field of the c_cpp_properties.json file to set #defines in a way that clangd can see. Here is the full schema reference. The relevant portion is

    "configurations": [
      {
        ...
        "defines": ["FOO", "BAR=100"],
        ...
      },
    ]
    

    This is where you would put your LIBRARY_IMPL. Your c_cpp_properties.json file should be in the top level directory of your project folder.

    Login or Signup to reply.
  2. A simple way would be to create a .clangd file in your project’s root directory, containing:

    CompileFlags:
      Add: [-DLIBRARY_IMPL]
    

    This instructs clangd to add the flag -DLIBRARY_IMPL (which has the effect of defining the macro LIBRARY_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:

    If:
      PathMatch: /path/to/library/library.h
    
    CompileFlags:
      Add: [-DLIBRARY_IMPL]
    

    You can read more about clangd config files at https://clangd.llvm.org/config.html.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search