跳转至

在 Arch Linux 上编译 bloomberg/clang-p2996 小记

本文简要记录笔者在 Arch Linux 上编译一个部分支持 C++ 反射的 clang 编译器的过程。

期待 Reflection 能正式被编译器实现的那一天。 :)

本次实验受群友 Yiran Wang 启发。

克隆仓库

GitHub 仓库在 这里,有关这个编译器的介绍详情请看仓库(默认是 purpose 分支,代码在 p2996 分支上)。

先克隆仓库到本地:

$ git clone https://github.com/bloomberg/clang-p2996 --depth 1 --branch=p2996

使用 --depth 1 选项只克隆最新版本的 commit,可大大减小仓库体积(好像只有两百多兆)。

有的仓库有很多分支(比如 llvm 或者 gcc 官方仓库),使用 --branch=xxx 指定克隆某一个分支也可以减小体积。本仓库只有两个分支,作用不大。

建议上网搜一下镜像站,在高级搜索中调整搜索范围为近一周左右,基本就可以找到可用的镜像站,实测有助于提高网速。

编译 Clang

编译选项和步骤可以参考 llvm 官网手册中的介绍,此处给出我的生成命令,供参考:

$ cd clang-p2996
$ mkdir build
$ cd build
$ cmake -DLLVM_ENABLE_PROJECTS=clang \
        -DCMAKE_C_COMPILER=clang \
        -DCMAKE_CXX_COMPILER=clang++ \
        -DLLVM_ENABLE_RUNTIMES="libc;libcxx;libcxxabi;libunwind" \
        -DCMAKE_C_FLAGS="-O3 -march=native -mtune=native" \
        -DCMAKE_CXX_FLAGS="-O3 -march=native -mtune=native" \
        -DCMAKE_BUILD_TYPE=Release \
        -DLLVM_USE_LINKER=lld \
        -DLLVM_BUILD_TOOLS=OFF \
        -DLLVM_BUILD_EXAMPLES=OFF \
        -DLLVM_BUILD_TESTS=OFF \
        -DLLVM_INCLUDE_TESTS=OFF \
        -DLLVM_INCLUDE_DOCS=OFF \
        -DLLVM_TARGETS_TO_BUILD="X86" \
        -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-build \
        -G "Unix Makefiles" \
        ../llvm

具体每一个选项是什么意思以及有哪些可选参数,自己 STFW 或者问 AI。此处仅为精简编译(仅编译 clang),没有添加其他的各种工具。有需者请自选。

值得注意的是,-DLLVM_ENABLE_RUNTIMES 应该至少有 libc;libcxx;libcxxabi;libunwind(感谢群友 Yiran Wang)。

强行添加了 -O3 -march=native -mtune=native,纯属个人喜好。

-DCMAKE_INSTALL_PREFIX=/usr/local/llvm-build 的结果是 llvm-build 下有 binlib 等等这些。以免有人怀疑是否会出现重叠安装目录的情况。

如果有提示缺少依赖就安装相应的依赖(貌似是不缺)。

编译的时候,需要注意一下编译使用的任务数,因为可能会遇到内存瓶颈。我在 14 核心 20 线程的笔记本 U 上使用 make -j20 编译会在进度到 55% 左右时直接吃满 32G 内存 + 9G 交换内存导致桌面卡死。解决方法之一是改为 make -j14

测试运行

先贴一个简单的编译命令:

$ /usr/local/llvm-build/bin/clang++ main.cpp \
                          --std=c++26 \
                          -I/usr/local/llvm-build/include/c++/v1 \
                          -I/usr/local/llvm-build/include/x86_64-unknown-linux-gnu/c++/v1 \
                          -freflection \
                          -stdlib=libc++ \
                          -Wl,-rpath,/usr/local/llvm-build/lib/x86_64-unknown-linux-gnu \
                          -g3 -Og -march=native -mtune=native

别忘了使用 -freflection

-stdlib=libc++ 必不可少,否则一顿 -I 也会报错。

仅仅 -L/usr/local/llvm-build/lib/x86_64-unknown-linux-gnu 貌似不行。

贴一段简单的测试程序:

main.cpp
#include <experimental/meta>
#include <print>

int main()
{
    constexpr auto r = ^int;
    typename[:r:] x = 42;      // Same as: int x = 42;
    typename[:^char:] c = '*'; // Same as: char c = '*';
    std::println("{}", std::same_as<decltype(x), int>);
    std::println("{}", std::same_as<decltype(c), char>);
}

输出结果为:

true
true