Open-Source Wikis

/

Rust

/

Tools

/

Bootstrap

rust-lang/rust

Bootstrap

src/bootstrap/ is the build system for rustc, std, and all in-tree tools. It's a Rust binary fronted by x.py (and the x / x.ps1 shims). Its job is to invoke Cargo with the right environment, in the right order, with the right artifact moves and copies, to produce a working Rust toolchain.

The authoritative description is in src/bootstrap/README.md; this page is a navigation aid.

Why bootstrap exists

Rustc is written in Rust, so building rustc requires a Rust compiler. Bootstrap solves this by:

  1. Downloading a pre-built stage 0 compiler (pinned in src/stage0)
  2. Using stage 0 to build stage 1 (the compiler currently in source)
  3. Using stage 1 to build stage 2 (the same compiler, now built by itself — the version that ships)

Each stage builds its own copy of the standard library. Cargo and rustc each are built across stages this way.

graph LR
    DL[Download stage 0 from<br/>static.rust-lang.org]
    DL --> S0Std[Stage 0 std<br/>downloaded]
    DL --> S0Rustc[Stage 0 rustc<br/>downloaded]
    S0Rustc -->|builds| S1Std[Stage 1 std]
    S0Rustc -->|builds| S1[Stage 1 rustc]
    S1 -->|builds| S2Std[Stage 2 std]
    S1 -->|builds| S2[Stage 2 rustc<br/>= shipped]

Layout

src/bootstrap/
├── README.md                # Authoritative docs
├── Cargo.toml               # Bootstrap is a Rust binary itself
├── bootstrap.py             # Pre-rustc downloader (Python)
├── configure.py             # Generates bootstrap.toml from CLI flags
├── bootstrap_test.py        # Tests for bootstrap.py
├── defaults/
│   └── bootstrap.<profile>.toml  # Profiles offered by `x setup`
├── mk/
│   └── ...                  # Makefile-driven build
└── src/
    ├── lib.rs               # Bootstrap library entry
    ├── bin/
    │   ├── main.rs          # The bootstrap binary
    │   └── ...
    ├── core/
    │   ├── builder/         # The Step/Builder trait — heart of bootstrap
    │   ├── build_steps/     # Concrete steps (compile.rs, doc.rs, test.rs, ...)
    │   ├── config/          # bootstrap.toml parsing (config.rs, flags.rs)
    │   ├── download.rs      # Stage 0 / CI artifact downloads
    │   └── sanity.rs        # Pre-build sanity checks
    └── utils/
        ├── change_tracker.rs # Detect breaking config changes between bootstrap revisions
        ├── helpers.rs
        └── ...

The Step abstraction

Bootstrap is structured around the Step trait. Each Step represents one buildable thing:

  • Step::Std { compiler, target } — build std with a given compiler for a given target
  • Step::Rustc { compiler, target } — build rustc
  • Step::Test { suite } — run a test suite
  • Step::Doc { … }, Step::Install { … }, etc.

A Builder walks the requested top-level steps, recursively resolving dependencies (build the std for stage N if you need rustc for stage N), and runs each unique step exactly once. The full listing of Step types is in src/bootstrap/src/core/build_steps/.

bootstrap.py vs the Rust binary

There's a chicken-and-egg problem: bootstrap is itself a Rust program. Solving it involves two pieces:

  • bootstrap.py (src/bootstrap/bootstrap.py) — Python script run before rustc exists. Downloads the stage 0 toolchain, then invokes Cargo to compile the bootstrap binary, then hands off to it.
  • The bootstrap binary — the Rust code under src/bootstrap/src/. Owns all the build logic from that point on.

Both bootstrap.py and the Rust binary parse bootstrap.toml, so they have to stay in sync — bootstrap.py mirrors a small subset of the configuration. Major changes to bootstrap usually touch both.

Configuration: bootstrap.toml

User-supplied configuration lives in bootstrap.toml at the repo root. The fully-documented schema is in bootstrap.example.toml — every option, with its default and description, in commented form.

Major sections:

[build]
build = "x86_64-unknown-linux-gnu"     # host triple
target = ["..."]                        # targets to cross-compile for
extended = false                        # build cargo + clippy + rustfmt + rust-analyzer too
docs = true                             # build docs
locked-deps = true                      # use Cargo.lock as-is

[llvm]
download-ci-llvm = true                 # don't build LLVM from source
ccache = true                           # use ccache when building LLVM

[rust]
debug = false                           # debug build of rustc itself
debuginfo-level = 0                     # debuginfo for rustc itself
incremental = false                     # rustc's own incremental cache
parallel-compiler = true                # multi-threaded query system

[install]
prefix = "/usr/local"
sysconfdir = "/etc"

change_tracker.rs

Because bootstrap evolves, breaking config changes need to be communicated to existing developers. src/bootstrap/src/utils/change_tracker.rs has a CONFIG_CHANGE_HISTORY vec; on each run, bootstrap diffs your local revision against the most recent and warns about removed/renamed options. Major changes get a new entry.

x setup profiles

./x setup writes a bootstrap.toml based on a profile. Profiles live in src/bootstrap/defaults/:

Profile For What it sets
library std/core/alloc work download-ci-llvm, download-rustc, fast incremental
compiler rustc work Same as library + compiler-friendly debug flags
tools rustdoc/clippy/miri work Library setup, plus build extended tools
codegen LLVM work Forces in-tree LLVM build
dist Distribution-style Everything; slow
none Manual configuration Empty file

Stage selection

./x build --stage N:

  • --stage 0 — use only the downloaded stage 0 compiler. Useful for ./x doc --stage 0 library/std (very fast).
  • --stage 1 — build rustc + std once with stage 0. The default for most subcommands.
  • --stage 2 — build twice (stage 0 → 1 → 2). Distribution-quality. Required for some tests.

--keep-stage N — skip rebuilding stage N when iterating on a later stage.

Common entry points for modification

  • A new build step → src/bootstrap/src/core/build_steps/
  • A new config option → src/bootstrap/src/core/config/{flags.rs,config.rs}, then update bootstrap.example.toml and add a change_tracker entry
  • A new tool to build → src/bootstrap/src/core/build_steps/tool.rs
  • A new sanity check → src/bootstrap/src/core/sanity.rs
  • Stage 0 bump → src/tools/bump-stage0/ and the resulting src/stage0

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Bootstrap – Rust wiki | Factory