0

我已经克隆了 llvm-project 存储库。

然后我为项目生成了一个 Visual Studio 解决方案,使用

cmake -G "Visual Studio 16" -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_TARGETS_TO_BUILD=X86 -DCLANG_BUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX=install ...\llvm-project\llvm

DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS正如这里所建议的,重要的部分是。

生成解决方案和所有项目。然后我构建 Clang 本身和 llvm-project 源中已经提供的示例 clang 插件。PrintFunctionNames 似乎是 Clang 插件的 hello world,所以我根据llvm 文档构建了它。

构建成功运行,现在我在安装目录中有 llvm/clang,带有 PrintFunctionNames 插件。

有两种方法可以告诉 clang 使用插件:

clang -cc1 -load PrintFunctionNames.dll -plugin print-fns test.cpp
clang++ -c -Xclang -load -Xclang PrintFunctionNames.dll -Xclang -plugin -Xclang print-fns test.cpp

第一个有效,但是,第二个无效。此外,使用带有第一个命令行参数的 clang++ 也不起作用。这两个命令都适用于 clang,但不适用于 clang++,因此看起来 clang++ 存在问题。此外,省略 -c 命令并实际构建带有激活插件的可执行文件会产生链接错误 (1137)。

似乎 clang++ 不适用于 dll 插件,这很奇怪,因为 clang++ 似乎是同一个 clang 驱动程序,除了用于与 c++ 库链接的不同预设。

我遇到的另一个问题是,在构建树外时,cmake install 命令无法将库文件clang.lib 复制到安装目录,否则无法构建树外插件。手动设置此库的路径(位于原始输出目录中,而不是 cmake install 将移动其他构建输出的位置)似乎允许正确构建树外插件。

但是问题仍然存在:您不能在 Windows 上使用 Xclang 插件加载器或带有插件的 clang++ 驱动程序。不是使用提供的示例插件,也不是使用由树制成的测试插件。

问题是:我是在构建 clang 还是插件错误?如果是这样,为什么-cc1 -load可以使用带有clang.exe的插件?如何构建提供的示例插件并使其与 clang++ 驱动程序一起使用?我查看了这个实现基本树外插件的GitHub 存储库,但它没有提供有关在 Windows 上构建的任何信息。

4

1 回答 1

0

这不是正确的答案,而是遇到问题的解决方法。

虽然我没有让 clang++ 与任何示例插件一起正常工作,但我现在对这个问题有了更好的理解。

使事情复杂化的是Windows。为了使插件可以使用 clang 符号,clang 需要构建一个包含这些符号的特殊 clang.lib 文件,因为在 Windows 上没有使用来自动态库的可执行符号的机制。太好了,链接这个额外的库(不会在 cmake INSTALL 命令上被复制!)可以构建插件。但是任何插件都必须包含clang在CMakeLists文件中构建和定义的必要库。对于 PrintFunctionNames 示例插件,这些定义如下:

clang_target_link_libraries(PrintFunctionNames PRIVATE
    clangAST
    clangBasic
    clangFrontend
    )

但是,Visual Studio 项目生成出了点问题,只有导出的符号库 clang.lib 被包含在内。如果您不仅想使用插件,还想使用 clang 构建源文件(需要这些链接来解决链接错误 1136),则需要手动添加这些库。

但是,链接 clangFrontend 会打乱插件注册机制,为插件创建第二个插件注册表,这是愚蠢的。所以 clangFrontend 不能包含在插件中。但是必须链接它需要的所有其他内容,即使 cmake 没有使用此类设置生成项目,以使编译器不会引发链接错误。

至于 clang++ 仍然无法工作:我已经广泛查看了 clang 的构建步骤,发现 clang.exe 只是被复制为 clang++.exe 作为构建后的步骤。由于二进制文件的大小完全相同,我想知道是否有任何区别。据我所知,您可以仅使用 clang.exe 编译器(驱动程序)编译 C++ 代码,因此仅使用 clang.exe 似乎没问题。但是IDE集成,期望clang++的外部项目不能使用插件,所以有。也许使用符号链接重定向 clang++ 调用可能是解决该问题的一种方法。

于 2020-11-22T00:51:30.577 回答