---
# System prepended metadata

title: Commandinomicon

---

# The Art and Science of Rust Compiler Flags
## Mostly copy-pasta from various sources: Zulip, URLO, IRLO, Discord, Blogs, Docs, Github.

### `BOOTSTRAP`
- `RUSTFLAGS_BOOTSTRAP` - environment variable is passed as `RUSTFLAGS` to the bootstrap stages (`stage0`) and `RUSTFLAGS_NOT_BOOTSTRAP` is passed when building artifacts for later stages

### `cargo`
- `cargo doc --document-private-items` - if an `impl` block contains no `pub` items it doesn't show up in docs
- `cargo clean -p rustdoc && cargo rustc --lib -- -Z self-profile -Z time-llvm-passes=yes -Z self-profile-events=default,args  -Z human-readable-cgu-names -C codegen-units=2000`
- `cargo rustc -v --lib -- -Z self-profile -v`
  - `-Z time-llvm-passes=yes`
- `cargo +nightly -Z timings` - produces a timings report
- `cargo build -Zbuild-std=core -Zbuild-std-features=compiler-builtins-mem` - get the Rust implementation for `memcpy`
  - without `-Zbuild-std` links against LLVM-compiled distributed standard library
- `-Z{llvm-time-trace,print-mono-items}` - helps profile which code in the crate is driving the compilation time
- `cargo rustc --release -- --emit asm <ARGS>`
  - `-C llvm-args=--x86-asm-syntax=intel`
  - `-C target-cpu=native -C opt-level=3`
  - `RUSTFLAGS="--emit asm -C opt-level=3 -C target-cpu=native" cargo build --release`
  - `find . -name "*.s" -type f | xargs cat | rustfilt`
- `-Zfeatures=itarget` - causes the feature resolver to ignore features for target-specific dependencies for targets that don't match the current compile target
- `-Zsplit-dwarf=split` - will output a `.dwo` file per codegen-unit which is referenced by the DWARF in the binary
- `cargo doc` does `cargo check` to create `rmeta`s for all the crates

### `cranelift`
- `RUSTFLAGS="-Zcodegen-backend=cranelift" cargo +nightly build`

### `macros`
- `+nightly -Zunpretty=expand` - expands macros

### `mir`
- `RUSTC_LOG=rustc_mir::dataflow=true` or
`-Z dump-mir={all,MIR-body of interest} -Z dump-mir-dataflow`
  - dot-files will be saved in `mir_dump/`
- `miri --stage 1` - means use the `stage1` compiler/miri as produced during `stage0` builds
- `RUSTC_LOG=rustc_mir::transform::const_goto ./x.py build --stage 2 > stage2.log` - checking for instances of success
- `-Zalways-encode-mir -Zmir-opt-level=3`
`ar x librust_out.rlib && objdump -s rust_out.rust_out.3a1fbbbh-cgu.*`
- `-Zdump-mir-graphviz -Zdump-mir=all` - get MIR CFG of an intermediate pass or the initial MIR using
- `env RUSTFLAGS='-Zdump-mir=new_v1 -Zdump-mir-dir=/tmp/mir cargo build -Zbuild-std --target x86_64-unknown-linux-gnu'` - dumps MIR for `stdlib`

### `rustc`
- `rustc +nightly --print=target-spec-json -Zunstable-options --target x86_64-unknown-linux-musl` - emit whether the native `C` library is being statically linked
- `rustc --print cfg $RUSTFLAGS` - to get the list of all enabled cfgs
- `env RUSTC_LOG=compiletest=debug` - enables logging in `compiletest`
- `+nightly -Zpretty=expand` - shows what the macro expands to not *where* in the compiler it was expanded
- `+nightly -Zunpretty=expand` - shows a pretty-printed version of the AST node which `assert!` was replace with
- `-Zalways-encode-mir=yes` - to get the MIR for all functions
- `-Zrandomize-layout` - if enabled can shuffle offsets of each field while still keeping each field well-aligned preventing two identically written structs filled with the same field type being transmuted between each other
- `--target` - allows `rustc` to choose which sysroot to use
- `debug-logging = true` - unless logging for tests is being swallowed by `compiletest` then use `-vv
- `RUSTDOC_LOG=rustc_metadata::creader=debug,rustdoc::passes::collect=debug RUSTFLAGS_NOT_BOOTSTRAP='-Z treat-err-as-bug' xpy doc --stage 1 library/std --keep-stage 1`

### `thir`
-`-Zthir-unsafeck` - `THIR` `unsafeck` feature gate 

### `wasm`
- `-C target-feature=+multivalue` - multivalue support is a target feature need to pass

### `./x.py`
- `x.py build --keep-stage 0` - is a good default for building
- `x.py build --stage 1` - builds the standard library and creates a `sysroot`
- `./x.py build library/std --stage=1` - builds rust once
- `./x.py clean` - invalidates the build config cache
    - doesn't clean LLVM cache
- `./x.py dist rustc-dev` - to build `rustc-dev`
- `./x.py test --exclude tidy`
- `./x.py test tidy -v`
- `./x.py test --stage 0 src/tools/miri`
- `./x.py test --stage 0 library/std` - tests the standard library
- `./x.py check library/std` - only checks `library/std`
- `./x.py check` or `./x.py check --stage 1` - to check `compiler/rustc`
- `./x.py check --all-targets` - does cross-compilation for a lot of different targets
  - can be made less failure-prone by putting the imports inside the function where they're used rather than using separate configs
    - creates a problem of missing functions
- `./x.py build --stage 0 library/std` - if only working on the standard library
  - builds `library/std` then `compiler/rustc` then `library/std` again
- `./x.py test --stage 1` - tests the compiler
- `./x.py test --stage 1 --keep-stage-std 1 src/test/ui` - uses a cached version of the compiler `--keep-stage-std 0` picks up changes to the compiler and `std`
-`rustup toolchain link` - use `./x.py build --stage 2`
- `./x.py test --bless src/test/mir-opt` - automatically generates `mir` dumps
- `./x.py test --stage 1 --compare-mode chalk`