cquery是一款基于libclang的C/C++ Language Server,可以支持代码补全、引用查找等编辑和浏览代码的时候常见操作。cquery是服务端,跟它相配套的客户端有VS Code、EMACS以及Vim等。本文介绍如何在Windows下编译cquery。官方文档Building cquery对此有一定的描述,本文记录一些编译过程中的问题。

准备过程

首先是从Github检出代码:

git clone --recursive --depth=1 https://github.com/cquery-project/cquery.git
cd cquery
mkdir build && cd build

确保你的电脑上安装了CMake,并且cmake命令在PATH中可以找到。

cquery依赖于Clang,关于如何在Windows下配置Clang,可以参考在Windows下配置Clang编译器

如果你想用Visual Studio来编译的话,可以安装Visual Studio Community(其实安装相应的Build Tools)就足够了。Visual Studio Community对于个人是免费的,但是在规模以上的企业环境中使用是违反协议的。不过不要紧,还有另外一个选项,就是安装Visual Studio Express

如果不想用Visual Studio,则可以使用MingW,在Windows下配置Clang编译器一文中有介绍如何使用。

最好在本机上预先安装好Clang/LLVM,避免编译的时候去下载。对于cquery,可以用官方预编译好的Windows包,也可以使用第三方的,比如Building Zig on Windows提供的llvm+clang-7.0.0-win64-msvc-release.tar.xz。官方的Clang/LLVM预编译包比较精简,但是不影响cquery的编译。

编译过程

使用Clang编译器+MinGW库

前提条件

  • LLVM安装在C:/Program Files/LLVM/,注意CMake要求路径是反斜杠/分隔
  • MinGW已安装,需要POSIX线程的版本,比如64位的需要使用x86_64-8.1.0-posix-seh-rt_v6-rev0
  • 确保MinGW的相关程序在PATH之中,执行MinGW提供的mingw-w64.bat脚本可以帮你自动设置。

执行MinGW提供的mingw-w64.bat脚本打开命令行窗口,到之前创建的cquery代码目录的build子目录下执行以下命令:

cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=release -DCMAKE_EXPORT_COMPILE_COMMANDS=YES -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang++.exe" -DCMAKE_CXX_FLAGS="-target x86_64-pc-windows-gnu" -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="C:/Program Files/LLVM" -DSYSTEM_CLANG=ON -DCMAKE_C_FLAGS="-target x86_64-pc-windows-gnu" -DCMAKE_C_COMPILER="C:/Program Files/LLVM/bin/clang.exe" -DCMAKE_CXX_STANDARD=14

解释一下上面命令中的一些参数:

  • -DCMAKE_CXX_COMPILER="C:/Program Files/LLVM/bin/clang++.exe",使用clang++作为C++编译器
  • -DCMAKE_CXX_FLAGS="-target x86_64-pc-windows-gnu",编译C++时使用MinGW的库
  • -DCMAKE_C_COMPILER="C:/Program Files/LLVM/bin/clang.exe",使用clang作为C编译器
  • -DCMAKE_C_FLAGS="-target x86_64-pc-windows-gnu",编译C时使用MinGW的库
  • -DSYSTEM_CLANG=ON,使用系统的LLVM库,而不是去下载
  • -DCMAKE_PREFIX_PATH="C:/Program Files/LLVM",指定系统LLVM库所在位置
  • -G "MinGW Makefiles,生成MinGW格式的Makefile
  • -DCMAKE_CXX_STANDARD=14,使用C++14标准,cquery的要求

等待CMake做完配置之后,就可以执行cmake --build .来编译。所有的文件都正确编译了,可惜最后链接的时候出现了下面的问题:

0unique_ptrINS_12_Result_baseENS3_8_DeleterEEvEEb]+0x89): undefined reference to
 `std::__once_call'

这种方法编译失败。

使用MinGW编译器+MinGW库

这种方法不使用Clang编译器,而是使用MinGW中提供的GCC编译器来编译cqeury。前提条件与上一种方法类似。

执行MinGW提供的mingw-w64.bat脚本打开命令行窗口,到之前创建的cquery代码目录的build子目录下执行以下命令:

"C:\Program Files\CMake\bin\cmake" .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=release -DCMAKE_EXPORT_COMPILE_COMMANDS=YES -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="C:/Program Files/LLVM" -DSYSTEM_CLANG=ON -DCMAKE_CXX_STANDARD=14

CMake会自动找到GCC,并生成相应的makefile。然后执行cmake --build .进行编译。可以看到过程中产生了不少警告信息,但是最终编译成功了。

这种方法编译成功。

使用VS C++编译器和库

前提条件:

  • 和前面两种方式一样,需要安装LLVM
  • 安装Visual Stduio Community或者Express版本

在开始菜单里面找到Developer Command Prompt for VS 2017.bat,打开进入命令行窗口,到之前创建的cquery代码目录的build子目录下执行以下命令:

cmake ..  -DCMAKE_PREFIX_PATH="C:/Program Files/LLVM" -DSYSTEM_CLANG=ON -DCMAKE_CXX_STANDARD=14

会生成Visual Studio的工程文件。然后执行cmake --build . --config Release来编译Release配置,一切顺利。

这种方法编译成功。

在Windows上使用cquery

VSCode的cquery扩展很出色,建议使用VSCode作为Windows上的客户端。

另外因为Windows上的Clang发行版不带C++库,所以cquery无法通过clang -E命令查看到C++头文件所在的目录。如果你使用compile_commands.json的方式使用cquery的话应该没有问题,如果你使用.cquery的方式使用cquery的话,则需要在.cquery文件里面指明C++库头文件的包含地址。 以Visual Studio为例,打开Developer Command Prompt for VS 2017.bat,执行echo %INCLUDE%查看头文件包含目录,然后把这些头文件目录写到.cquery文件中去,在我的电脑上,这部分的内容应该是这样的:

-IC:\Program Files (x86)\Microsoft Visual Studio\2017\WDExpress\VC\Tools\MSVC\14.16.27023\include
-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um
-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt
-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\shared
-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\um
-IC:\Program Files (x86)\Windows Kits\10\include\ 10.0.17763.0\winrt
-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\cppwinrt

其他