Rust Compiler

rustc cheatsheet — compile Rust programs directly. rustc main.rs, rustc -O, rustc --edition 2021, rustc --emit. Usually prefer cargo, but here are the direct flags.

4 min read

What it is

The Rust compiler (rustc) translates Rust source code into executable binaries. You reach for it whenever you write Rust code.

Installation

Linux:

curl --proto '=https' --tlsv1.2 -sSF https://sh.rustup.rs | sh
rustup install stable
rustup default stable

Mac:

curl --proto '=https' --tlsv1.2 -sSF https://sh.rustup.rs | sh
rustup install stable
rustup default stable

Windows:

Download rustup-init.exe from https://rustup.rs/ and run it.

Core Concepts

  • Crates: The smallest compilation unit in Rust. A crate can be a library or an executable.
  • Modules: A way to organize code within a crate, controlling visibility and namespacing.
  • Packages: A collection of crates that provide a certain functionality. A package typically contains one library crate and/or multiple binary crates. cargo is used to manage packages.
  • Targets: The combination of an architecture, operating system, and environment for which code is compiled.

Commands / Usage

rustc is typically invoked via cargo, but you can use it directly for simple cases or understanding the compilation process.

Compiling a Single File

rustc main.rs

Compiles main.rs into an executable named main (or main.exe on Windows).

Specifying Output Name

rustc --outdir target/debug main.rs

Compiles main.rs and places the executable in the target/debug/ directory.

rustc -o my_program main.rs

Compiles main.rs and names the executable my_program.

Enabling Optimizations

rustc -O main.rs

Compiles main.rs with optimizations enabled (equivalent to --opt-level=3).

rustc --debug main.rs

Compiles main.rs with debug information enabled (the default).

Specifying Target Architecture

rustc --target x86_64-unknown-linux-gnu main.rs

Compiles main.rs for the x86_64-unknown-linux-gnu target. You need to have the target installed via rustup target add x86_64-unknown-linux-gnu.

Enabling Warnings

rustc -W clippy::pedantic main.rs

Enables specific lints from Clippy. Many other -W flags exist for various lint groups.

rustc -W all main.rs

Enables all lints.

rustc -A clippy::pedantic main.rs

Allows specific lints from Clippy, suppressing warnings.

rustc -D clippy::pedantic main.rs

Treats specific lints from Clippy as errors.

Controlling Output

rustc --emit=llvm-ir main.rs

Emits LLVM intermediate representation instead of an executable.

rustc --emit=asm main.rs

Emits assembly code instead of an executable.

rustc --pretty=expanded main.rs

Pretty-prints the expanded macro code.

Linking Libraries

rustc main.rs -L native=/path/to/libs -l dylib=my_lib

Links against a dynamic library named my_lib found in /path/to/libs.

rustc main.rs -L static=/path/to/libs -l static=my_static_lib

Links against a static library named my_static_lib found in /path/to/libs.

Dependencies

rustc main.rs --extern rand=target/release/librand.rlib

Manually specifies an external crate named rand located at target/release/librand.rlib. This is rarely needed when using cargo.

Verbosity and Debugging

rustc -v main.rs

Prints verbose output during compilation.

rustc --print cfg main.rs

Prints the configured build cfg flags.

rustc --crate-name my_crate --crate-type bin main.rs

Explicitly sets the crate name and type.

Common Patterns

Compiling with optimizations and debug symbols (often done by cargo build --release):

rustc -O main.rs

Compiling a library:

rustc --crate-type lib src/lib.rs -o target/debug/libmylib.rlib

Checking for compilation errors without producing an executable:

rustc --emit=metadata main.rs

This is a faster way to check if your code compiles.

Using rustc with make (for simple projects without cargo):

SRC = main.rs
TARGET = my_program

$(TARGET): $(SRC)
	rustc $(SRC) -o $(TARGET)

clean:
	rm -f $(TARGET)

Gotchas

  • rustc vs. cargo: For any project beyond a single file, you should almost always use cargo. cargo handles dependency management, building, testing, and more, abstracting away many of rustc’s complexities.
  • Error Messages: Rust’s compiler errors are notoriously helpful, but sometimes the suggested fixes might not be exactly what you intended. Read carefully!
  • Target Triplets: When cross-compiling, ensure you have the correct target triplet installed via rustup target add <target-triplet>.
  • Linking: Manually linking libraries with rustc can be tricky. cargo’s build.rs scripts and [dependencies] in Cargo.toml are the idiomatic way to handle external libraries.
  • Crate Types: Be mindful of --crate-type. If you intend to create a library that can be used by other crates, you need to specify lib or dylib. The default for a single file is usually bin.