因为想尝试一下最新的 Clang,于是去 https://llvm.org/,从 git 获取到最新的源码。进入发布页 https://releases.llvm.org/ 就可以看到从 Git 获取代码的方法:https://llvm.org/docs/GettingStarted.html
笔者使用 MSVC 进行的构建,这需要事先安装 MSVC,去官网下载即可,安装 C++ 桌面开发 Workload。如果需要使用 lldb,似乎还需要安装 Python。
之后,便是获得源码。首先打开 Developer PowerShell for VS,建议选择以管理员模式启动。然后,切换到一个工作目录,比如 D:dev,并且将该目录添加到 Windows Defender 或者其他反病毒软件的白名单。
或者,打开 x64 Native Command prompt for VS。不理解为什么没有 x64 Native PowerShell。在 Command prompt 这里面就要使用 cmd 的命令了。
cd D:dev
由于 LLVM 的一些 Test 对 EOL 敏感,因此在 Windows 签出需要禁用自动 CRLF 转换。此外,如果磁盘空间吃紧,并且不计划参与 LLVM 开发,可以使用浅克隆,即添加参数 --depth=1。
如果网络条件不佳,注意使用代理服务器。
git clone --depth 1 --config core.autocrlf=false https://github.com/llvm/llvm-project.git
然后,进入目录 llvm-project,新建目录预备进行构建。
cd llvm-project mkdir build_ninja cd build_ninja
之后,便可以开始使用 CMake 生成构建信息了。
LLVM_ENABLE_PROJECTS 选项是选择需要的构建目标。这里笔者选择了 clang、libcxx、libcxxabi、lld、lldb。如果需要 Clang-tidy 等工具,可以添加 clang-tools-extra。
需要选择 lld 以构建 LLVM 的 linker,不然,因为 Clang 是用 MSVC 构建的,所以默认是用的 MSVC 的链接器,但是在日常使用时,默认 MSVC 的环境变量不暴露在外,所以 CMake 配置的时候就会链接失败。所以我们需要一个除了 MSVC linker 之外的 linker。
同时,如果磁盘空间吃紧,需要选择 Release 的构建类型,这样结合 --depth=1 的 Git 选项,构建后总文件大小约为 5GB,而如果选择 Debug 类型,则可能消耗数十 GB 的磁盘空间。
这里,我们使用 Ninja 作为构建工具。需要注意,Ninja 不支持选择主机平台 triplet,而我们打开的 Developer PowerShell 默认是 32 位的,因此这样构建出的 Clang 是 32 位的,且默认目标平台是 i386-windows-pc。
不过,可以添加选项,修改默认目标平台 Target Triple:-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-windows-msvc
笔者也尝试使用 MSVC 的构建工具,但是似乎无视了 Release 的 CMAKE_BUILD_TYPE 设定。
或者,打开 x64 Native 的 Developer Shell 即可,这样默认主机就是 x64 了,构建出来的也是 64 位的,默认目标平台也自然是 x86_64。
此外,可以选择 Clang + LLVM 构建好后的安装目录。即设定 CMAKE_INSTALL_PREFIX 变量,Windows 下默认为 X:/Program Files(x86)/,最后执行 ninja install 时,需要管理员权限。笔者构建时没有更改这个选项 。
综上,笔者的 CMake 命令如下:
cmake
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;libcxx;libcxxabi;lld;lldb"
-DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-windows-msvc
-GNinja
../llvm
-DCMAKE_BUILD_TYPE=Release
等待 CMake Configure 完成后,就可以开始构建了:
ninja
然后就是漫长的构建过程。笔者的 i7-1065U + 16GB RAM 大约花了 2 小时。过程中没有 error,只有一些 warning,因此可以或许在睡觉休憩的时候执行构建过程。
构建完成后,安装即可:
ninja install
至此,我们可以把安装的 Clang 添加进环境变量了。之后,就可以在普通的命令行使用 Clang 了。
但是,如果我们希望使用 CMake 并使用刚刚构建的 Clang 作为编译器,正如之前所说,我们 PC 上只安装了 Visual Studio,其环境变量默认不暴露在外,也就是说,我们 PC 默认打开一个终端,其中只有 clang、lld 等命令可用,还需要额外再安装 CMake 以及构建工具。这里,我们构建工具选择 Ninja,在其发布页下载 binary 并将程序所在目录添加进 PATH 即可。
这样之后就可以了,比如,使用 Visual Studio Code 上的 CMake 插件配置项目也不会遇到问题了。
如果时候发现想要的工具功能忘记构建,可以删除 CMakeCache.txt 并重新执行 CMake 和 build 过程。
此外,第一次构建有了 lld 过后,可以使用 lld 作为链接器。
cmake ../llvm -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;libcxx;libcxxabi;lld;lldb" -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_linkER=lld -DLLVM_PARALLEL_link_JOBS=8 -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-windows-msvc关于 Target 的问题
以下部分可能多有疏漏,仅供参考。
这里的 Target 不是指构建的“目标”,而是指“目标平台”。
LLVM 和 GCC 有个很大的不同点是, GCC 需要为每个特定的体系架构,譬如 arm/x86 独立生成一套交叉工具链套件,而 LLVM 是在一个工具链套件中就可以支持多个体系架构。
CMake 在 Configure LLVM Project 时,通过 LLVM_TARGETS_TO_BUILD 来指定生成的 LLVM 可以支持的体系架构(这里称为 target)。默认时全部都选的,详见 LLVM 文档。
LLVM_DEFAULT_TARGET_TRIPLE: 可以通过该选项修改默认的 target 的 triple 组合。
来源:https://zhuanlan.zhihu.com/p/263550372
笔者编译时没有指定,得到的结果如下:
$ clang -v clang version 14.0.0 (https://github.com/llvm/llvm-project.git a2a826d8b66cfc85499a92949767d153563078a0) Target: i686-pc-windows-msvc Thread model: posix InstalledDir: C:Program Files (x86)LLVMbin
关于 Triple 的介绍在这里:https://clang.llvm.org/docs/CrossCompilation.html#target-triple
在 LLVM 的 GettingStarted 页的例子 处了解到,可以像 gcc 那样直接使用 clang,编译得到目标平台可执行程序:
clang hello.c -o hello.exe
这样子实际上是直接将生成的中间产物丢给 llvm,最终得到了目标平台的可执行程序。可以使用 emit-llvm 参数略过这个过程。
所以,当笔者使用上述命令时,实际上是针对 i686-pc-windows-msvc 编译的。可以向 clang 传递 --verbose 参数查看这些细节。
如果要生成针对 x86_64 平台的可执行程序,应当使用 -target 选项:
clang hello.c -o hello.exe -target x86_64-pc-windows-msvc
根据 LLVM 的 Getting Started 页,LLVM 很依赖宿主机的 C++ 编译器。或者换句话说,就算 Clang 默认支持跨平台编译,也需要有对应平台的 Headers 和 Libraries 才能生成可执行程序(正确进行系统调用等)。
在我们 x86_64-pc-windows-msvc 或者 i386-pc-windows-msvc 的最末一条为 MSVC,即需要 Windows 的 SDK 才能进行开发。
在安装 MSVC 时,自然也是安装了 Windows 的 SDK。如果没有安装 Windows 的 SDK,或者,想针对 MinGW-w64 的平台,则需将 msvc 修改为 gnu,Clang 便会在 PATH 中寻找对应的 include path 和 Libraries 等。
参见:https://stackoverflow.com/questions/39871656/how-to-use-clang-with-mingw-w64-headers-on-windows/47148323#47148323
另请参见:
- https://zhuanlan.zhihu.com/p/342916589
- https://marvinsblog.net/post/2019-01-08-clang-on-windows/



