首页
/ 深入 Rust 编译器源码:rust-lang/rust 仓库结构、crate 依赖与构建体系全景解析

深入 Rust 编译器源码:rust-lang/rust 仓库结构、crate 依赖与构建体系全景解析

2026-09-10 14:13:55作者:庞眉杨Will

导读

本文基于 rustc-dev-guide 的 "High-level overview of the compiler source" 章节(原文档位于 src/doc/rustc-dev-guide/src/compiler-src.md),结合本仓库(rust-lang/rust 源码镜像)的实际目录与源码,系统梳理 rustc 编译器的整体代码布局:包括单一大 Cargo 工作区下的三大核心目录、约 50 个 rustc_* crate 的依赖层级、rustc 二进制入口与 rustc_driver/rustc_interface/rustc_middle 的分层设计、rustdoc 的实现位置、测试体系与 bootstrap 构建系统。读完本文,你将能够像查阅地图一样在数万文件级的仓库中快速定位编译器各个阶段、标准库、测试与构建工具对应的代码位置,并理解为何编译器要以如此多 crate 拆分组织。

从整体视角出发:仓库是一个巨型 Cargo 工作区

rust-lang/rust 仓库整体上是一个单一的大型 Cargo 工作区(workspace),其中同时容纳了编译器、标准库(coreallocstdproc_macro 等)、rustdoc、构建系统以及一大批用于构建完整 Rust 发行版的工具与子模块。这一点可以通过仓库根目录的 Cargo.toml 得到印证:其 [workspace] 声明了 resolver = "2",并将 compiler/rustcsrc/rustdoc-json-typessrc/tools/rustdocsrc/tools/compiletestsrc/tools/tidy 等成员纳入统一管理,同时通过 exclude 排除了 buildobjsrc/bootstrap 以及两个可选的 codegen 后端 crate(compiler/rustc_codegen_craneliftcompiler/rustc_codegen_gcc,它们在独立目录中自成一体的工作区)。

按原文档的分类,仓库主体由三大目录构成,外加一个承载工具与文档的 src/ 目录:

目录 内容 本仓库中的对应路径
compiler/ rustc 编译器的全部源码,由众多 crate 组成 compiler/
library/ 标准库(coreallocstdproc_macrotest)以及 Rust 运行时组件(backtracertstartuplang_start library/
tests/ 编译器测试套件 tests/
src/ rustdocclippycargo、构建系统、语言文档等 src/

需要说明的是,原文档中列举的四个目录实际上 src/ 与三大目录并列;本仓库目录树中可以看到 compiler/library/tests/src/ 四个顶级目录并存,其中 src/bootstrapsrc/toolssrc/docsrc/etc 分别承载构建引导、各类工具、文档与杂项脚本。

编译器:约 50 个 rustc_* crate 的分层拼图

rustc 二进制:只负责把控制权交给 rustc_driver

编译器的主体实现散布在 compiler/ 目录下的大量 crate 中。几乎所有 crate 都以 rustc_ 前缀命名,总数约 50 个,规模从小到大不一而足。除此之外还有一个名为 rustc 的 crate,它才是真正的编译器二进制(即包含 main 函数),但它自身几乎不做任何编译工作,只是调用 rustc_driver,由后者驱动其他 crate 完成编译的各个阶段。

本仓库的实现印证了这一设计,并揭示了近年的一次结构调整:根工作区成员 compiler/rustcCargo.toml 中包名实际为 rustc-main,而其 main.rs 仅有寥寥几行:

rustc_driver::override_c_allocator_in_binary!();

fn main() -> ExitCode {
    rustc_driver::main()
}

同时,rustc_driver 本身也变成了一个"再导出壳": compiler/rustc_driver/src/lib.rs 的注释说明该 crate 故意保持为空,仅仅 pub use rustc_driver_impl::*;,以便让 rustc_driver_impl 的代码能够与其他 crate 并行编译。真正的驱动逻辑(命令行解析、编译流程编排、信号处理、分配器选择等)位于 compiler/rustc_driver_impl/src/lib.rs,其第 1663 行定义了 pub fn main() -> ExitCode 入口,并依次完成 start time 记录、RSS 采集、参数解析与后续编译驱动。文章后续提及的 rustc_driver 均指这条以 rustc_driver 为名的再导出链路及其背后的 rustc_driver_impl 实现。

依赖层次:从底层基础设施到顶层驱动

这些 crate 之间的依赖关系相当复杂,但大致呈如下金字塔结构(对应原文档的 5 步描述):

  1. rustc(二进制)调用 rustc_driver::main
  2. rustc_driver 依赖大量其他 crate,其中最主要的是 rustc_interface
  3. rustc_interface 依赖其余大多数编译器 crate,是驱动整个编译过程的通用接口层;
  4. 其余绝大多数 rustc_* crate 都依赖 rustc_middle,后者定义了编译器中的大量核心数据结构;
  5. rustc_middle 与多数 crate 又依赖一小批代表编译器早期阶段(如解析器)、基础数据结构(如 Span)或错误报告的 crate,即 rustc_data_structuresrustc_spanrustc_errors 等。

在本仓库中,各层的实体均可直接找到:

  • 顶层驱动rustc_driver_impl 中通过 use rustc_interface::passes::collect_crate_types;use rustc_interface::util::{self, get_codegen_backend};use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes};(见 compiler/rustc_driver_impl/src/lib.rs)调用 rustc_interface
  • 接口层rustc_interfaceinterface.rs 定义了通用编译入口 pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> Rpasses.rs 则定义了 pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>——这正是进入查询系统全局上下文(TyCtxt)的关键通道;
  • 核心数据结构层rustc_middlequeries.rs 通过 rustc_queries! 宏集中声明并缓存了编译器的各类查询(例如 #[derive] proc macro 展开缓存等),查询修饰符文档位于 compiler/rustc_middle/src/query/modifiers.rs

cargo tree 查看精确依赖

与原文档一致,你可以在仓库中像查看任何普通 Rust 包那样查看这些 crate 的精确依赖:

cargo tree --package rustc_driver

需要提醒的是,该命令依赖本地已安装的 Rust 工具链(cargo),并需要仓库处于可被 cargo 解析的工作区状态;且由于编译器自身大量使用 unstable 特性,更常见的做法是在 rustc 官方 nightly 工具链环境下配合 x.py 构建后使用,或借助 cargo tree--depth-i(反向依赖)参数缩小输出范围。本文写作环境未安装 cargo,因此无法在此贴出实际输出,读者可自行在具备工具链的环境中执行验证。

依赖结构背后的两大动因

原文档明确指出,这种依赖结构主要由两个因素决定:

  1. 组织性(Organization):编译器是一个体量巨大的代码库,若做成单个 crate 将大到不可维护;依赖结构在一定程度上反映了编译器的代码结构。
  2. 编译时间(Compile-time):拆分为多个 crate 后,可以更好地利用 cargo 的增量编译与并行编译能力;同时尽量降低 crate 间的依赖数量,这样修改某一个 crate 时无需重编大量下游 crate。

依赖树的最底层是一小批被全体编译器使用的 crate(如 rustc_span),编译早期的环节(例如解析与 AST 构建)只依赖这些底层 crate。AST 构建完成、早期分析结束后,编译器的查询系统(query system,参见 query.md)才被搭建起来。查询系统借助函数指针巧妙地打破了 crate 之间的依赖,从而支持更多并行编译;它定义在 rustc_middle 中,因此几乎后续所有编译器阶段都依赖这个规模庞大、编译耗时的 crate。原文档也坦承:由于历史原因,有时相关的功能会被打散到不同 crate(例如 lint 相关逻辑分散在早期阶段、rustc_lintrustc_middle 等多处),并展望"理想情况下更少、内聚性更强的 crate 配合成熟的增量/并行编译才是长期方向,但目前拆分仍是现实解"。

依赖树的最顶端rustc_driverrustc_interface——后者是一个围绕查询系统的 unstable 封装,用于驱动编译各阶段;编译器之外的其他消费者(如 rustdoc,未来或许还有 rust-analyzer)也可以按不同方式使用这一接口。rustc_driver 先解析命令行参数,再借助 rustc_interface 将编译驱动到底。

与 LLVM 的交界:rustc_llvmsrc/llvm-project

还有一个值得单独说明的点:src/llvm-project 是 Rust 官方 LLVM fork 的 git submodule。在 bootstrap 过程中 LLVM 会被构建出来,而 compiler/rustc_llvm 这个 crate 提供了针对 LLVM(C++ 编写)的 Rust 封装,使编译器能够与之对接(其 llvm-wrapper 子目录下的 C++ 桥接代码见 compiler/rustc_llvm/llvm-wrapper)。从目录结构看,除官方 LLVM 后端外,仓库还并行维护着两个备选 codegen 后端:compiler/rustc_codegen_craneliftcompiler/rustc_codegen_gcc,它们均自带独立的 Cargo 工作区与构建脚本,被根工作区 exclude,属于"锦上添花"的探索性实现,本文不作展开。

rustdoc:二进制入口极薄,主体在 librustdoc

rustdoc 的主体代码位于 src/librustdoc(即原文档所称的 librustdoc),而 rustdoc 二进制本身在 src/tools/rustdoc,其 main.rs 除了调用 rustdoc::main 之外几乎不做什么——这与 rustc 二进制"只做转发"的设计如出一辙。工作区根 Cargo.tomlsrc/tools/rustdocsrc/rustdoc-json-types 均被列为 workspace 成员,印证了它们作为独立 crate 的存在。

围绕 rustdoc 的配套资源还包括:

关于 rustdoc 的更深入内容,原文档指向专门的章节 rustdoc.md

测试体系:tests/ 与 compiletest

上述所有组件的测试套件都集中在 tests/。从本仓库目录看,其覆盖范围极广,包括 tests/ui(编译 UI 测试,约数万文件)、tests/mir-opttests/codegen-unitstests/run-maketests/run-make-cargotests/debuginfotests/incrementaltests/rustdoc-guitests/rustdoc-uitests/rustdoc-jsontests/assembly-llvmtests/codegen-llvmtests/crashestests/pretty 等类别。

测试的驱动/执行框架(harness)位于 src/tools/compiletest。关于测试套件的完整介绍,原文档指向 tests/intro.md

构建系统:bootstrap 与 src/tools

仓库中存在一大批仅为构建编译器、标准库、rustdoc 等而存在的工具,同时还负责测试、构建完整 Rust 发行版等任务。其中最主要的工具是 src/bootstrap:它实现了分阶段的 bootstrap 构建(其入口脚本 x.pysrc/bootstrap/bootstrap.py 配合,日常可用 ./x.py build./x.py test 等命令驱动)。构建过程中还会用到 src/tools 下的其他工具,例如 src/tools/tidy(代码风格与仓库卫生检查)和 src/tools/compiletest(测试执行器)。bootstrap 的详细原理见 building/bootstrapping/intro.md

标准库:特殊构建方式与 "standard facade"

标准库代码(library/)在写法上与普通 Rust crate 差别不大,但构建方式特殊:它必须能够使用 unstable(nightly)特性。原文档还指出,标准库有时被称作 libstd 或 "standard facade"(标准门面)——即 std 只是一个薄薄的再导出层,实际实现分布在 coreallocproc_macro 等子库中,再统一汇集到 std 表面。本仓库 library/ 下可以看到 coreallocstdproc_macrotestpanic_abortpanic_unwindunwindrtstartup(其 rsbegin.rsrsend.rs 提供程序启动/收尾的运行时例程)、backtracestd_detectstdarchportable-simdwindows-sys 等 crate,以及三个薄封装 library/rustc-std-workspace-corelibrary/rustc-std-workspace-alloclibrary/rustc-std-workspace-std,它们用于在 std 构建期间将外部依赖重定向到内部实现,是 facade 机制在 Cargo 层面的体现。

其他:构建完整发行版所需的杂项

仓库里还有大量与"构建完整 Rust 发行版"相关的其他内容,日常开发大多无需关心,主要包括:

速查地图:从文档到源码的路径对照

关注点 仓库相对路径
编译器 crate 集合 compiler/
rustc 二进制(转发 rustc_driver::main compiler/rustc/src/main.rs
rustc_driver 再导出壳 compiler/rustc_driver/src/lib.rs
驱动实现(main、参数解析、流程编排) compiler/rustc_driver_impl/src/lib.rs
通用编译接口(run_compiler 等) compiler/rustc_interface/src/interface.rs
查询系统核心数据结构 compiler/rustc_middle/src
查询声明宏 compiler/rustc_middle/src/queries.rs
标准库 library/
测试套件 tests/
测试执行器 compiletest src/tools/compiletest
bootstrap 构建系统 src/bootstrapx.py
rustdoc 主体 src/librustdoc
rustdoc 二进制入口 src/tools/rustdoc/main.rs
LLVM fork 子模块 src/llvm-project
LLVM Rust 封装 compiler/rustc_llvm
CI 配置 src/ci
杂项工具 src/etc

以上所有路径均可在本仓库中直接打开核对,便于你在阅读后续 rustc-dev-guide 各章节(如 overview.mdquery.md)时按图索骥。

热门项目推荐
相关项目推荐

项目优选

收起
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.15 K
2.77 K
kernelkernel
deepin linux kernel
C
34
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
929
1.85 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.94 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.47 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
534
603
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
398
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Markdown
77
23