Skip to main content
The Rust bootstrap system (src/bootstrap/) manages the complex process of building a self-hosting compiler. Since Rust is written in Rust, a sophisticated bootstrapping mechanism is required.

The Bootstrap Problem

The fundamental challenge: How do you compile a Rust compiler when you need a Rust compiler to compile Rust code?The solution: Use a previously-built compiler (stage 0) to compile the current source code (stage 1), then use that to recompile itself (stage 2) for verification.

Three-Stage Bootstrap Process

From src/bootstrap/README.md:
Bootstrap build system goes through a few phases to actually build the compiler.
1

Stage 0: Download Prebuilt Compiler

The entry point script (x, x.ps1, or x.py) downloads prebuilt compiler binaries:
# Entry point scripts
./x        # Unix-like systems
./x.ps1    # Windows PowerShell
./x.py     # Cross-platform Python
These scripts:
  • Download the stage 0 compiler/Cargo binaries from CI
  • Extract them to build/<host-triple>/stage0/
  • Compile the bootstrap system itself
  • Invoke the compiled bootstrap binary
2

Stage 1: Build with Stage 0

Use the prebuilt stage 0 compiler to build the current source:
  1. Build the stage 1 standard library using stage 0
  2. Build the stage 1 compiler (links against stage 0 std)
  3. Use stage 1 compiler to rebuild the stage 1 standard library
Output: A working compiler in build/<host-triple>/stage1/
3

Stage 2: Rebuild with Stage 1

Use the stage 1 compiler to rebuild everything:
  1. Build the stage 2 standard library using stage 1
  2. Build the stage 2 compiler (links against stage 1 std)
Output: A verified compiler in build/<host-triple>/stage2/
Stage 2 ensures the compiler can compile itself correctly. This is the compiler distributed to users.

Bootstrap System Architecture

Entry Points

The bootstrap system has multiple entry points:
bootstrap.py is the Python entry point:
# Responsibilities:
# 1. Download stage0 compiler if needed
# 2. Compile the bootstrap binary
# 3. Execute the bootstrap binary
Location: src/bootstrap/bootstrap.pyThis is the “outer” bootstrap - it bootstraps the bootstrap!

Bootstrap Crate Structure

[package]
name = "bootstrap"
version = "0.0.0"
edition = "2024"
default-run = "bootstrap"

[lib]
path = "src/lib.rs"

[[bin]]
name = "bootstrap"
path = "src/bin/main.rs"

[[bin]]
name = "rustc"          # Wrapper for stage0 rustc
path = "src/bin/rustc.rs"

[[bin]]
name = "rustdoc"        # Wrapper for stage0 rustdoc  
path = "src/bin/rustdoc.rs"
Bootstrap includes wrapper binaries for rustc and rustdoc to intercept and instrument compilation during the build process.

Source Organization

The bootstrap source is organized in src/bootstrap/src/:
src/bootstrap/src/
├── lib.rs              # Main library entry point
├── bin/
│   ├── main.rs         # Bootstrap binary
│   ├── rustc.rs        # rustc wrapper
│   └── rustdoc.rs      # rustdoc wrapper
├── core/               # Core bootstrap functionality
│   ├── build_steps/    # Build step implementations
│   ├── builder/        # Build orchestration
│   ├── config/         # Configuration parsing
│   ├── download.rs     # Downloading artifacts
│   ├── sanity.rs       # Sanity checks
│   └── ...
└── utils/              # Utility modules

Build Steps

Bootstrap organizes compilation into discrete build steps in src/core/build_steps/:

compile.rs

Compiling rustc and the standard library
  • Std compilation
  • Rustc compilation
  • Tool compilation

check.rs

Fast checking without codegen
  • cargo check integration
  • Faster feedback

test.rs

Test suite execution
  • Compiletest harness
  • Unit tests
  • Integration tests
  • UI tests

doc.rs

Documentation generation
  • Rustdoc invocation
  • Book building
  • API documentation

dist.rs

Creating distribution artifacts
  • Tarball creation
  • Installation packages
  • Cross-compilation

install.rs

Installing to system
  • System installation
  • Sysroot setup

llvm.rs

Building LLVM
  • LLVM compilation
  • CMake integration
  • Caching

clippy.rs

Running Clippy linter

tool.rs

Building tools
  • rustfmt
  • cargo
  • Other tools

Build Directory Structure

From src/bootstrap/README.md, all output goes under build/:
build/
├── cache/                          # Downloaded stage0 tarballs
│   ├── 2015-12-19/
│   ├── 2016-01-15/
│   └── ...

├── bootstrap/                      # Bootstrap binary itself
│   ├── debug/
│   └── release/

├── misc-tools/                     # Host-only tools
│   ├── bin/
│   └── target/

├── node_modules/                   # JS dependencies
│   └── .bin/

├── dist/                           # Distribution artifacts

├── tmp/                            # Temporary files

└── <host-triple>/                  # Per-host build artifacts
    ├── stage0/                     # Extracted stage0 compiler
    │   ├── bin/
    │   │   ├── rustc
    │   │   └── cargo
    │   └── lib/

    ├── stage0-sysroot/             # Stage0 sysroot for building stage1
    │   └── lib/

    ├── stage1/                     # Stage1 compiler sysroot
    │   ├── bin/
    │   │   └── rustc
    │   └── lib/

    ├── stage2/                     # Stage2 compiler sysroot
    │   ├── bin/
    │   │   └── rustc
    │   └── lib/

    ├── stageN-std/                 # Cargo output for std
    ├── stageN-test/                # Cargo output for test
    ├── stageN-rustc/               # Cargo output for rustc
    ├── stageN-tools/               # Cargo output for tools

    ├── llvm/                       # LLVM build
    │   ├── build/
    │   ├── bin/
    │   ├── lib/
    │   └── include/

    ├── compiler-rt/                # Compiler runtime
    │   └── build/

    ├── doc/                        # Generated documentation

    ├── test/                       # Test outputs
    │   ├── ui/
    │   ├── debuginfo/
    │   └── ...

    └── bootstrap-tools/            # Host tools (stage0)
The build system uses hard links when possible to avoid copying large artifacts between stage directories.

Configuration

Bootstrap is configured through multiple mechanisms:
Main configuration file config.toml (or bootstrap.toml):
[build]
# Number of parallel jobs
jobs = 8

# Target triples to build
target = ["x86_64-unknown-linux-gnu"]

# Host triples
host = ["x86_64-unknown-linux-gnu"]

[rust]
# Optimization level
optimize = true

# Debug info
debug = true

# Use incremental compilation
incremental = true

[llvm]
# Download prebuilt LLVM
download-ci-llvm = true
Configuration is parsed in src/core/config/:
  • config.rs: Main configuration struct
  • flags.rs: Command-line flag parsing

Dependency Management

Bootstrap has pinned dependencies for reliability:
[dependencies]
# Pinned to prevent breakage
cc = "=1.2.28"
cmake = "=0.1.54"

# Build utilities
build_helper = { path = "../build_helper" }
clap = { version = "4.4" }
serde = "1.0"
serde_json = "1.0"
toml = "0.5"

# Platform operations
tar = { version = "0.4.44" }
xz2 = "0.1"
sha2 = "0.10"
From Cargo.toml comments:
Most of the time updating these dependencies requires modifications to the bootstrap codebase (e.g., https://github.com/rust-lang/rust/issues/124565); otherwise, some targets will fail. That’s why these dependencies are explicitly pinned.

Build Performance Optimizations

Compilation Speed

No Debug Info for Deps

[profile.dev]
debug = 0  # No debug info for dependencies

[profile.dev.package.bootstrap]
debug = 1  # Only for bootstrap itself

Incremental Bootstrap

Bootstrap leverages Cargo’s incremental compilation:
  • Only recompile changed crates
  • Cache build artifacts
  • Parallel compilation

Downloading Pre-built Artifacts

Pre-built LLVM can be downloaded instead of building:
[llvm]
download-ci-llvm = true
Managed by src/core/download.rs:
  • Downloads from CI artifacts
  • Verifies checksums (SHA-256)
  • Caches in build/cache/

Sanity Checks

src/core/sanity.rs performs extensive validation:
1

Verify Toolchains

  • Check for C/C++ compiler
  • Verify linker is available
  • Confirm CMake for LLVM builds
  • Check Python version
2

Validate Paths

  • Ensure source directories exist
  • Verify build directory is writable
  • Check stage0 compiler
3

Check Configuration

  • Validate target triples
  • Verify feature compatibility
  • Confirm LLVM settings

Parallel Execution

Bootstrap orchestrates parallel builds:
The -j parameter to bootstrap gets forwarded to Cargo and test harnesses for parallel execution.
./x build -j 8  # Use 8 parallel jobs
Orchestration in src/core/builder/:
  • Dependency graph construction
  • Parallel step execution
  • Resource management

Testing Infrastructure

test.rs implements the test infrastructure:
Multiple test suites:
  • UI tests: Compiler diagnostic tests
  • Codegen tests: Code generation verification
  • Assembly tests: Assembly output tests
  • Debuginfo tests: Debug information tests
  • Incremental tests: Incremental compilation tests
  • Rustdoc tests: Documentation tests
  • Unit tests: Compiler unit tests

Cross-Compilation Support

Bootstrap supports building for multiple targets:
[build]
host = ["x86_64-unknown-linux-gnu"]
target = [
  "x86_64-unknown-linux-gnu",
  "aarch64-unknown-linux-gnu",
  "x86_64-pc-windows-gnu",
]
Each target gets its own build directory under build/<host-triple>/.

Distribution Creation

dist.rs creates distribution artifacts:
1

Component Packaging

  • Package rustc binary
  • Package standard library
  • Package documentation
  • Package tools (cargo, clippy, rustfmt)
2

Tarball Creation

  • Create tar.xz archives
  • Generate manifests
  • Calculate checksums
3

Installation Packages

  • rustup-compatible packages
  • Platform-specific installers
Output in build/dist/.

Extending Bootstrap

From the README:
Some general areas that you may be interested in modifying:
See bootstrap/src/core/build_steps/tool.rs for examples.Steps:
  1. Define a new step struct
  2. Implement the Step trait
  3. Register in the builder
  1. Create directory with Cargo.toml
  2. Configure all Cargo.toml files
  3. Add to workspace members
No bootstrap changes needed!
  1. Modify bootstrap/src/core/config/flags.rs for CLI flags
  2. Modify bootstrap/src/core/config/config.rs for config struct
  3. Update CONFIG_CHANGE_HISTORY in src/utils/change_tracker.rs
Add to bootstrap/src/core/sanity.rs

Two Codebases in Sync

Bootstrap has two separate codebases that must stay synchronized:
  1. bootstrap.py (Python)
  2. bootstrap binary (Rust)
Both parse bootstrap.toml and command-line arguments. They communicate via environment variables.
Synchronization mechanisms:
  • Environment variables set by bootstrap.py
  • Explicitly ignored arguments
  • Shared configuration format

Platform-Specific Handling

Bootstrap handles platform differences:
[target.'cfg(windows)'.dependencies]
junction = "1.3.0"    # Junction/symlink support
windows = { version = "0.61", features = [...] }
Windows-specific:
  • Different file extensions (.exe)
  • Path separators
  • Junction support

Debugging Bootstrap

1

Enable Verbose Output

./x build --verbose
./x build -vv  # Very verbose
2

Inspect Build Commands

Bootstrap prints Cargo invocations in verbose mode.
3

Test Bootstrap Itself

./x test bootstrap
Uses snapshot testing with cargo-insta:
cargo install cargo-insta
cargo insta review --manifest-path src/bootstrap/Cargo.toml

Change Tracking

Bootstrap tracks configuration changes in src/utils/change_tracker.rs:
Add entries to CONFIG_CHANGE_HISTORY when making major changes:
  • New configuration options
  • Changes to default behavior
  • Breaking configuration changes

Design Philosophy

Leverage Cargo

Defer most compilation logic to Cargo itself

Incremental by Default

Each build step is incremental and parallelizable

Hard Links

Use hard links instead of copying to save space

Fail Fast

Sanity checks catch problems early

Common Build Commands

# Build stage 1 compiler (faster for development)
./x build --stage 1

# Build stage 2 compiler (for distribution)
./x build --stage 2

# Build only the standard library
./x build --stage 1 library/std

# Check without building
./x check

# Run tests
./x test

# Build documentation
./x doc

# Clean build artifacts
./x clean

# Install to system
./x install

Further Reading

Compiler Architecture

What bootstrap compiles: the compiler crates

Standard Library

The standard library built by bootstrap

Contributing

CONTRIBUTING.md in the repository

Build docs developers (and LLMs) love