SerenityOS 如何切换到 Clang 工具链构建:BuildClang.sh 与 SERENITY_TOOLCHAIN 说明
2026/9/21 8:28:15 网站建设 项目流程

SerenityOS 如何切换到 Clang 工具链构建:BuildClang.sh 与 SERENITY_TOOLCHAIN 说明

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

SerenityOS 默认使用 GNU 工具链构建。如果你想改用实验性的 Clang 工具链——官方文档给出的理由有两点:减少对编译器特定行为的依赖,以及利用 Clang 内置静态分析器发现更多 bug——整个过程分两步:先用Toolchain/BuildClang.sh构建出一套能同时编译宿主机与 Serenity 目标的 Clang 工具链,再让构建系统选择Clang而不是默认的GNU。两种工具链编出的代码在大多数情况下行为一致,但当前有一个明确限制:ports 尚不能用 Clang 构建。

构建 Clang 工具链前的准备

BuildClang.sh 开头会检查一批宿主机依赖,缺失时直接退出并给出提示:

  • ninjacmake:必需,脚本检查不到就退出;
  • GNUpatch:脚本会检查,缺失时只提示安装、不退出;
  • 可用的 C 与 C++ 编译器:脚本会实际编译一个空程序来验证,失败则退出;
  • LLD 链接器:可选。检测到可用时输出Using LLD for linking LLVM.,否则输出LLD not found. Using the default linker.并回退默认链接器。

脚本还会从 LLVM 上游下载源码包到Toolchain/Tarballs/,内置固定的 commit 与 MD5 校验;如果本地已有 MD5 匹配的包,会跳过下载并显示Skipped downloading LLVM

执行前需要知道三件事:

  1. 不要用 root 运行。脚本检测到 root 会直接退出(Do not run BuildClang.sh as root),否则Toolchain/下的部分文件会变成 root 所有。
  2. 脚本会删除已有的Toolchain/Local/clang/再重建,所以重跑脚本就是完整的“重建工具链”;重新打补丁时它还会删除Toolchain/Build/clang
  3. 编译负载很高。AdvancedBuildInstructions.md 提醒:构建期间机器可能明显变慢甚至短暂卡死,尤其当 CPU 核心数多于空闲内存(GB 数)时。解决办法是把MAKEJOBS环境变量设为小于核心数的值以限制并行编译数;不设时脚本默认使用全部核心。

运行 BuildClang.sh

在项目根目录执行(等价于进入Toolchain目录运行BuildClang.sh):

# 常规构建 Toolchain/BuildClang.sh # CPU 核心数多于空闲内存(GB)时,限制并行任务数 MAKEJOBS=4 Toolchain/BuildClang.sh # 需要 clangd 时(可选,见“编辑器集成”一节) CLANG_ENABLE_CLANGD=ON Toolchain/BuildClang.sh

脚本接受--dev--ci两个互斥参数,同时传会报错退出:--dev改用 git 方式应用Toolchain/Patches/llvm/下的补丁并启用 ccache,方便迭代补丁;--ci面向 CI runner,启用 ccache(使用LLVM_CCACHE_DIR)并放弃-march=native,因为共享缓存的 runner 之间 CPU 可能不同。

脚本的实际工作大致是:为x86_64aarch64riscv64三个架构链接 LibC 头文件(写入Build/<arch>clang/Root),用 Ninja 编译并执行ninja install/strip把 LLVM/Clang 安装到Toolchain/Local/clang/,最后在Toolchain/Local/clang/bin/下为每个架构生成clang/clang++符号链接(如x86_64-serenity-clang)以及记录 sysroot 的<arch>-unknown-serenity.cfg

让构建系统选择 Clang 工具链

工具链就位后,有三种等价方式选 Clang。

方式一:给Meta/serenity.sh传 TOOLCHAIN 参数(文档示例用法)

Meta/serenity.sh run x86_64 Clang

Meta/serenity.sh 的用法是COMMAND [TARGET] [TOOLCHAIN] [ARGS...],TOOLCHAIN 只接受GNUClang,传错值会报ERROR: unknown toolchain '...'并退出。该参数只对非lagom目标生效——Lagom 是宿主机构建,不涉及目标工具链选择。

方式二:用SERENITY_TOOLCHAIN环境变量

SERENITY_TOOLCHAIN=Clang Meta/serenity.sh run x86_64

脚本的取值顺序是:命令行 TOOLCHAIN 参数 >SERENITY_TOOLCHAIN环境变量 > 默认GNU。适合想固定用 Clang 而不必每次敲参数的场景。

方式三:手动走 CMake 时传-DSERENITY_TOOLCHAIN

SERENITY_TOOLCHAIN同时是 Superbuild 中的 CMake 缓存选项(默认GNU)。手动构建时按文档给出的等效命令,把工具链换成Clang、构建目录换成带clang后缀的目录:

cmake -GNinja -S Meta/CMake/Superbuild -B Build/superbuild-x86_64clang -DSERENITY_ARCH=x86_64 -DSERENITY_TOOLCHAIN=Clang cmake --build Build/superbuild-x86_64clang ninja -C Build/x86_64clang setup-and-run

选 Clang 后,Superbuild 会把 ClangToolchain.txt.in 实例化成构建目录中的CMakeToolchain.txt:C/C++ 编译器指向Toolchain/Local/clang/bin/下的clang/clang++,目标三元组为<arch>-serenity,链接器为ld.lld,sysroot 指向Build/<arch>clang/Root

另外,如果Toolchain/Local/clang目录还不存在,Meta/serenity.sh在构建前会自动调用Toolchain/BuildClang.sh把工具链建好,不必手动先跑一遍。

验证切换是否生效

  • 构建目录:GNU 构建位于Build/x86_64,Clang 构建位于Build/x86_64clang(Superbuild 对应Build/superbuild-x86_64Build/superbuild-x86_64clang)。带clang后缀的目录出现并开始在其中编译,说明工具链选择已生效;两套工具链的产物互不干扰,可以共存。
  • 工具链产物:构建完成后Toolchain/Local/clang/bin/下应能查到clangclang++、各架构的x86_64-serenity-clang等符号链接及<arch>-unknown-serenity.cfg(内容为--sysroot=Build/<arch>clang/Root)。
  • 运行验证Meta/serenity.sh run x86_64 Clang会编译镜像并在 QEMU 中启动,能正常进入系统即说明 Clang 构建的系统可用。
  • 编译器指向:构建目录中的CMakeToolchain.txtCMAKE_C_COMPILER等变量指向Toolchain/Local/clang/bin/,可据此确认本次编译用的是自建 Clang 而非宿主机编译器。

编辑器集成与已知限制

构建 Clang 工具链时会一并构建意识到 SerenityOS 目标的 libTooling 工具:clang-formatclang-tidy以及(可选的)clangd,它们安装到Toolchain/Local/clang/bin。要把 clangd 包含进构建,需先设CLANG_ENABLE_CLANGD=ON再运行Toolchain/BuildClang.sh。把这些工具连同一次 Clang 构建产生的compile_commands.json配到编辑器插件中,可以获得比宿主机自带工具更丰富的错误报告;使用工具链里编译出的Toolchain/Local/clang/bin/clang-format时,meta-lint-ci的 pre-commit hook 也会自动拾取它。

限制方面,文档明确了两点:

  • ports 还不能用 Clang 构建;
  • CMake 选项ENABLE_USERSPACE_COVERAGE_COLLECTION(用户态覆盖率收集)目前只支持 Clang 构建。

此外,Meta/serenity.sh在构建前会检查Toolchain/Local/下是否残留旧三元组命名的文件(*-pc-serenity*),发现即中止并提示删除工具链与Build目录;GNU 路径特有的 binutils ld 版本检查(期望GNU ld (GNU Binutils) 2.46.0,不符时提示rebuild-toolchain)在 Clang 路径下不执行。

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询