如何使 clangd 启用仅标头库实现

How to make clangd to enable header-only library implementation

提问人:smokku 提问时间:7/28/2023 更新时间:7/29/2023 访问量:241

问:

有一种方法可以将 C/C++ 库分发为一个仅标头文件。库位于一个文件中:标头声明以及隐藏在 下的实现。您需要创建一些 / 文件来创建具有实现的编译单元。library.h#ifdef LIBRARY_IMPL.c.cpp#define LIBRARY_IMPL; #include "library.h"

我有一个广泛使用此类库的项目。项目构建系统创建,然后用于向 VSCode 提供项目路径、数据结构和提示(使用 llvm-vs-code-extensions.vscode-clangd)。compile_commands.jsonclangd

我遇到的问题是在打开文件进行编辑时,符号未定义,因此该部分被视为注释 - 没有语法突出显示、类型检查等。library.hLIBRARY_IMPL#ifdef LIBRARY_IMPL

有没有办法告诉或扩展名在编译包装文件期间将文件视为文件,而不是独立的 .h 文件?clangdlibrary.c

C++ C 可视化工作室代码 clangd 仅标头

评论

1赞 rioV8 7/28/2023
has a 属性c_cpp_properties.jsondefines
0赞 Basile Starynkevitch 7/28/2023
仅标头 C++ 库的另一种方法是 with 和 ;有关示例,请参阅此标头 仅 HTTP 库templateinline
0赞 HolyBlackCat 7/28/2023
Clangd 有一个项目范围的配置文件,您可以在其中指定常见的编译器标志,也许您可以在那里定义宏。
0赞 HolyBlackCat 7/28/2023
@BasileStarynkevitch 与任何事情有什么关系?无论选择何种构建系统,您仍然需要生成相同的内容。关于:这比仅在单个 TU 中实现要慢得多。makecompiler_commands.jsoninline
1赞 Davis Herring 7/28/2023
不要将这种安排称为“仅标头”;该术语在这里具有特定的含义。你可以称它为“有条件地包含在标头中的实现”。

答:

-2赞 Steampunkery 7/29/2023 #1

您可以使用文件的字段以可以看到的方式设置 s。下面是完整的架构参考。相关部分是definesc_cpp_properties.json#defineclangd

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

这是你要把你的.文件应位于项目文件夹的顶级目录中。LIBRARY_IMPLc_cpp_properties.json

评论

0赞 HighCommander4 7/29/2023
c_cpp_properties.json用于配置 Microsoft 的 C++ 插件,而不是 clangd。Clangd 通常使用 进行配置,详见 clangd.llvm.org/installation#project-setup。您还可以使用 clangd 配置文件来自定义配置,以防构建生成的配置本身不适合。compile_commands.jsoncompile_commands.json
1赞 HighCommander4 7/29/2023 #2

一个简单的方法是在项目的根目录中创建一个文件,其中包含:.clangd

CompileFlags:
  Add: [-DLIBRARY_IMPL]

这指示 clangd 将标志(具有定义宏的效果)添加到在项目中打开文件时使用的任何编译命令中。-DLIBRARY_IMPLLIBRARY_IMPL

请注意,要使此操作有效,需要位于项目的目录树中(因为该文件仅适用于该目录树中的文件)。library.h.clangd

如果位于项目目录之外,另一种方法是创建一个包含相同内容的用户配置文件,但这次您可能希望以文件的路径为条件:library.h

If:
  PathMatch: /path/to/library/library.h

CompileFlags:
  Add: [-DLIBRARY_IMPL]

您可以在 https://clangd.llvm.org/config.html 上阅读有关 clangd 配置文件的更多信息。

评论

1赞 smokku 7/31/2023
这行得通!谢谢。:-)