如何在windows中构建和运行Clang插件

如何在windows中构建和运行Clang插件,windows,plugins,clang,clang-plugin,Windows,Plugins,Clang,Clang Plugin,我已经克隆了llvm项目存储库 然后,我使用 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

我已经克隆了llvm项目存储库

然后,我使用

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导出符号

将生成解决方案和所有项目。然后我构建了Clang本身和一个示例Clang插件,该插件已经在llvm项目源代码中提供。PrintFunctionNames似乎是叮当声插件的hello世界,所以我已经构建了它,根据

构建成功运行,现在我在install dir中有了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)

似乎CLAN++不适用于DLL插件,这很奇怪,因为CLAN+++似乎是同一个CLAN驱动程序,除了与C++库连接的不同预设。 我遇到的另一个问题是,在构建树外插件时,cmake install命令无法将库文件clang.lib复制到install dir,否则无法构建树外插件。手动设置此库的路径(位于原始输出目录中,而不是cmake install移动其他构建输出的位置)似乎允许正确构建树外插件

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


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

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

虽然我没有让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会弄乱插件注册机制,为插件创建第二个插件注册表,这是愚蠢的。所以clangfronted不能包含在插件中。但它需要的所有其他内容都必须链接进来,即使cmake没有使用这些设置生成项目,编译器也不会抛出链接错误


至于clang++仍然不起作用:我广泛地研究了clang的构建步骤,发现clang.exe只是作为构建后步骤被复制为clang++.exe。由于二进制文件大小完全相同,我想知道是否有任何区别。就我所知,您可以用CLAN.EXE编译器(驱动程序)编译C++代码,因此只使用CLAN.EXE似乎是好的。然而,在IDE集成中,期望clang++的外部项目不能使用插件,所以存在这样的问题。也许使用符号链接重定向clang++调用可能是解决该问题的一种黑客手段。

它使用
clang.exe
但不使用
clang++.exe
的原因很可能是plugin.dll从
clang.exe
导入了clang符号。尝试动态加载DLL时,它也会从
clang.exe
加载符号,但它们已从
clang++.exe
中出现,从而创建冲突。您可以使用
dumpbin/imports plugin.dll
,查看导入的来源。。我还不确定,这是否可以改变或以其他方式规避。但是,你也可以使用CLAN.EXE作为C++,你只需要为标准LIB添加链接标志。