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.
#### `-Z force-unstable-if-unmarked`
Since `lib/rustlib/` is part of the search path we have to be careful about
which crates are included in it. In particular, all crates except for the
standard library are built with the flag `-Z force-unstable-if-unmarked`, which
means that you have to use `#![feature(rustc_private)]` in order to load it (as
opposed to the standard library, which is always available).
The `-Z force-unstable-if-unmarked` flag has a variety of purposes to help
enforce that the correct crates are marked as `unstable`. It was introduced
primarily to allow rustc and the standard library to link to arbitrary crates on
crates.io which do not themselves use `staged_api`. `rustc` also relies on this
flag to mark all of its crates as `unstable` with the `rustc_private` feature so
that each crate does not need to be carefully marked with `unstable`.
This flag is automatically applied to all of `rustc` and the standard library by
the bootstrap scripts. This is needed because the compiler and all of its
dependencies are shipped in `sysroot` to all users.
This flag has the following effects:
- Marks the crate as "`unstable`" with the `rustc_private` feature if it is not
itself marked as `stable` or `unstable`.
- Allows these crates to access other forced-unstable crates without any need
for attributes. Normally a crate would need a `#![feature(rustc_private)]`
attribute to use other `unstable` crates. However, that would make it
impossible for a crate from crates.io to access its own dependencies since
that crate won't have a `feature(rustc_private)` attribute, but *everything*
is compiled with `-Z force-unstable-if-unmarked`.
Code which does not use `-Z force-unstable-if-unmarked` should include the
`#![feature(rustc_private)]` crate attribute to access these forced-unstable
crates. This is needed for things which link `rustc` its self, such as `MIRI` or
`clippy`.
You can find more discussion about sysroots in:
- The [rustdoc PR] explaining why it uses `extern crate` for dependencies loaded
from `sysroot`
- [Discussions about sysroot on
Zulip](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/deps.20in.20sysroot/)
- [Discussions about building rustdoc out of
tree](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/How.20to.20create.20an.20executable.20accessing.20.60rustc_private.60.3F)
## Passing flags to commands invoked by `bootstrap`
Conveniently `./x` allows you to pass stage-specific flags to `rustc` and
`cargo` when bootstrapping. The `RUSTFLAGS_BOOTSTRAP` environment variable is
passed as `RUSTFLAGS` to the bootstrap stage (`stage0`), and
`RUSTFLAGS_NOT_BOOTSTRAP` is passed when building artifacts for later stages.
`RUSTFLAGS` will work, but also affects the build of `bootstrap` itself, so it