Home Explore Blog CI



rustc

4th chunk of `src/building/bootstrapping/what-bootstrapping-does.md`
bfc3755fd4164cdd4a486fc8325662ae576d2929aeab2ba40000000100000fa7
1. The library _linked_ to `stageN/rustc`, which was built by stage N-1 (stage
   N-1 `std`)
2. The library _used to compile programs_ with `stageN/rustc`, which was built
   by stage N (stage N `std`).

Stage N `std` is pretty much necessary for any useful work with the stage N
compiler. Without it, you can only compile programs with `#![no_core]` -- not
terribly useful!

The reason these need to be different is because they aren't necessarily
ABI-compatible: there could be new layout optimizations, changes to `MIR`, or
other changes to Rust metadata on `nightly` that aren't present in beta.

This is also where `--keep-stage 1 library/std` comes into play. Since most
changes to the compiler don't actually change the ABI, once you've produced a
`std` in `stage1`, you can probably just reuse it with a different compiler. If
the ABI hasn't changed, you're good to go, no need to spend time recompiling
that `std`. The flag `--keep-stage` simply instructs the build script to assumes
the previous compile is fine and copies those artifacts into the appropriate
place, skipping the `cargo` invocation.

### Cross-compiling rustc

*Cross-compiling* is the process of compiling code that will run on another
architecture. For instance, you might want to build an ARM version of rustc
using an x86 machine. Building `stage2` `std` is different when you are
cross-compiling.

This is because `./x` uses the following logic: if `HOST` and `TARGET` are the
same, it will reuse `stage1` `std` for `stage2`! This is sound because `stage1`
`std` was compiled with the `stage1` compiler, i.e. a compiler using the source
code you currently have checked out. So it should be identical (and therefore
ABI-compatible) to the `std` that `stage2/rustc` would compile.

However, when cross-compiling, `stage1` `std` will only run on the host. So the
`stage2` compiler has to recompile `std` for the target.

(See in the table how `stage2` only builds non-host `std` targets).

### What is a 'sysroot'?

When you build a project with `cargo`, the build artifacts for dependencies are
normally stored in `target/debug/deps`. This only contains dependencies `cargo`
knows about; in particular, it doesn't have the standard library. Where do `std`
or `proc_macro` come from? They come from the **sysroot**, the root of a number
of directories where the compiler loads build artifacts at runtime. The
`sysroot` doesn't just store the standard library, though - it includes anything
that needs to be loaded at runtime. That includes (but is not limited to):

- Libraries `libstd`/`libtest`/`libproc_macro`.
- Compiler crates themselves, when using `rustc_private`. In-tree these are
  always present; out of tree, you need to install `rustc-dev` with `rustup`.
- Shared object file `libLLVM.so` for the LLVM project. In-tree this is either
  built from source or downloaded from CI; out-of-tree, you need to install
  `llvm-tools-preview` with `rustup`.

All the artifacts listed so far are *compiler* runtime dependencies. You can see
them with `rustc --print sysroot`:

```
$ ls $(rustc --print sysroot)/lib
libchalk_derive-0685d79833dc9b2b.so  libstd-25c6acf8063a3802.so
libLLVM-11-rust-1.50.0-nightly.so    libtest-57470d2aa8f7aa83.so
librustc_driver-4f0cc9f50e53f0ba.so  libtracing_attributes-e4be92c35ab2a33b.so
librustc_macros-5f0ec4a119c6ac86.so  rustlib
```

There are also runtime dependencies for the standard library! These are in
`lib/rustlib/`, not `lib/` directly.

```
$ ls $(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/lib | head -n 5
libaddr2line-6c8e02b8fedc1e5f.rlib
libadler-9ef2480568df55af.rlib
liballoc-9c4002b5f79ba0e1.rlib
libcfg_if-512eb53291f6de7e.rlib
libcompiler_builtins-ef2408da76957905.rlib
```

Directory `lib/rustlib/` includes libraries like `hashbrown` and `cfg_if`, which
are not part of the public API of the standard library, but are used to
implement it. Also `lib/rustlib/` is part of the search path for linkers, but
`lib` will never be part of the search path.

Title: Sysroot and Cross-compilation
Summary
The sysroot contains the compiler and standard library artifacts necessary for compilation. It includes libraries like `libstd`, `libtest`, `libproc_macro`, compiler crates (when using `rustc_private`), and the `libLLVM.so` file. The sysroot also contains runtime dependencies for the standard library in `lib/rustlib/`, like `hashbrown` and `cfg_if`. Cross-compilation, compiling code for a different architecture, requires recompiling the standard library for the target architecture in stage2, unlike when `HOST` and `TARGET` are the same, in which `stage1` `std` is reused.