Chapter 1
Getting Started
Install the Rust toolchain with rustup, write and run a “Hello, world!” program with the compiler rustc, and then manage the same program as a project with cargo, Rust’s build system and package manager.
- 1.1 Installation
- 1.2 Hello, World!
- 1.3 Hello, Cargo!
The Rust Programming Language · Ch.1 Getting Started
1
Chapter 1 · 1.1 Installation
Installing Rust through rustup
The first step is to install Rust. The book downloads it through rustup, a command line tool for managing Rust versions and associated tools. The download needs an internet connection.
Definition 1.1 (rustup). A command line tool that installs Rust and manages Rust versions and their associated tools.
The steps install the latest stable version of the Rust compiler. Rust’s stability guarantees ensure that every example in the book that compiles will continue to compile with newer Rust versions. Output may differ slightly between versions, because Rust often improves its error messages and warnings — so any newer stable version installed this way works with the book.
Remark. If you prefer not to use rustup, the “Other Rust Installation Methods” page (forge.rust-lang.org/infra/other-installation-methods.html) lists more options.
The Rust Programming Language · Ch.1 Getting Started
2
Chapter 1 · 1.1 Installation
Command line notation
Throughout the book, terminal sessions follow one convention:
- Lines you should enter start with $. Do not type the $; it is the prompt marking the start of each command.
- Lines that do not start with $ typically show the output of the previous command.
- PowerShell-specific examples use > rather than $.
Example 1.2. In the session below, the first line is a command you type (without the $), and the second line is what the terminal prints back.
$ rustc --version
rustc x.y.z (abcabcabc yyyy-mm-dd)
The Rust Programming Language · Ch.1 Getting Started
3
Chapter 1 · 1.1 Installation
Installing rustup on Linux or macOS
Open a terminal and enter the command below. It downloads a script that installs the rustup tool, which in turn installs the latest stable Rust. You might be prompted for your password. On success it prints Rust is installed now. Great!
$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
Definition 1.3 (Linker). A program that Rust uses to join its compiled outputs into one file.
You probably already have a linker. If you get linker errors, install a C compiler, which typically includes one. A C compiler is useful anyway, because some common Rust packages depend on C code.
macOS — get a C compiler with:
$ xcode-select --install
Linux — install GCC or Clang as your distribution documents; on Ubuntu, install the build-essential package.
The Rust Programming Language · Ch.1 Getting Started
4
Chapter 1 · 1.1 Installation
Installing on Windows, and troubleshooting
Windows
Go to rust-lang.org/tools/install and follow the instructions. At some point you are prompted to install Visual Studio, which provides a linker and the native libraries needed to compile programs. More help: rust-lang.github.io/rustup/installation/windows-msvc.html.
The rest of the book uses commands that work in both cmd.exe and PowerShell, and explains any differences.
Still stuck? The community page (rust-lang.org/community) lists where to reach other Rustaceans — the nickname Rust users call themselves.
Troubleshooting
Check the install: you should see the version number, commit hash and commit date of the latest stable release.
$ rustc --version
rustc x.y.z (abcabcabc yyyy-mm-dd)
If not, check that Rust is in your %PATH% system variable:
| Shell | Command |
|---|---|
| Windows CMD | > echo %PATH% |
| PowerShell | > echo $env:Path |
| Linux, macOS | $ echo $PATH |
The Rust Programming Language · Ch.1 Getting Started
5
Chapter 1 · 1.1 Installation
Updating, uninstalling, local docs and editors
Updating
Once Rust is installed via rustup, updating to a newly released version is one command:
$ rustup update
Uninstalling
To remove both Rust and rustup, run the uninstall script:
$ rustup self uninstall
Reading the local documentation
The installation includes a local copy of the documentation for offline reading; rustup doc opens it in your browser. Whenever you are unsure what a standard-library type or function does or how to use it, look it up in the API (application programming interface) documentation.
Text editors and IDEs
The book assumes no particular tool: almost any text editor will do. Many editors and IDEs have built-in Rust support; the tools page (rust-lang.org/tools) keeps a fairly current list.
The Rust Programming Language · Ch.1 Getting Started
6
Chapter 1 · 1.1 Installation
Working offline with this book
Several examples use Rust packages beyond the standard library. To work through them you need either an internet connection or the dependencies downloaded ahead of time. These commands download and cache them (what cargo is and what each command does is explained later):
$ cargo new get-dependencies
$ cd get-dependencies
$ cargo add rand@0.10.1 trpl@0.2.0
- The downloads of these packages are cached, so you will not need to download them later.
- After running the commands you do not need to keep the get-dependencies folder.
- Once cached, pass the --offline flag to every cargo command in the rest of the book to use the cached versions instead of the network.
The Rust Programming Language · Ch.1 Getting Started
7
Chapter 1 · 1.2 Hello, World!
Project directory setup
Traditionally, the first program in a new language prints Hello, world! to the screen. Rust doesn’t care where your code lives; the book suggests a projects directory in your home directory, with one directory per project inside it.
Remark. The book assumes basic familiarity with the command line, but Rust makes no demands about editors or tooling: an IDE works just as well. The Rust team focuses IDE support on rust-analyzer (Appendix D).
Linux, macOS, and PowerShell on Windows:
$ mkdir ~/projects
$ cd ~/projects
$ mkdir hello_world
$ cd hello_world
Windows CMD:
> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world
The Rust Programming Language · Ch.1 Getting Started
8
Chapter 1 · 1.2 Hello, World!
Writing and running the first program
Create a source file named main.rs. Rust files always end in .rs; for multi-word names, separate words with an underscore (hello_world.rs, not helloworld.rs).
Listing 1.1: A program that prints Hello, world! — main.rs
fn main() {
println!("Hello, world!");
}
Compile and run on Linux or macOS:
$ rustc main.rs
$ ./main
Hello, world!
On Windows, run .\main instead:
> rustc main.rs
> .\main
Hello, world!
Whatever your OS, Hello, world! should print. If it did, you have officially written a Rust program — welcome, Rust programmer! If not, see “Troubleshooting”.
The Rust Programming Language · Ch.1 Getting Started
9
Chapter 1 · 1.2 Hello, World!
Anatomy of a Rust program: the main function
fn main() {
}
These lines define a function named main.
Definition 1.4 (main function). The special function that is always the first code to run in every executable Rust program.
- This main has no parameters and returns nothing. Parameters, if any, would go inside the parentheses ().
- The function body is wrapped in {}: Rust requires curly brackets around every function body.
- Good style puts the opening bracket on the same line as the declaration, with one space in between.
Remark. To keep a standard style across Rust projects, use the automatic formatter rustfmt (Appendix D). It ships with the standard Rust distribution, like rustc, so it is already installed.
The Rust Programming Language · Ch.1 Getting Started
10
Chapter 1 · 1.2 Hello, World!
Anatomy of a Rust program: println!
The body of main holds the one line that does all the work — printing text to the screen:
println!("Hello, world!");
Three details matter here:
- println! calls a Rust macro. A function call would be written println, without the !. The ! means you are calling a macro, and macros don’t always follow the same rules as functions (Chapter 20 covers them).
- "Hello, world!" is a string, passed as an argument to println!, which prints it to the screen.
- The line ends with a semicolon ;, which says this expression is over and the next one is ready to begin. Most lines of Rust code end with a semicolon.
Definition 1.5 (Macro). A way to write code that generates code, extending Rust’s syntax.
The Rust Programming Language · Ch.1 Getting Started
11
Chapter 1 · 1.2 Hello, World!
Compilation and execution are separate steps
First compile with rustc, passing the source file — much like gcc or clang for C/C++. It outputs a binary executable.
$ rustc main.rs
$ ls
main main.rs
With CMD on Windows (PowerShell shows the same three files); the /B option shows only the file names:
> dir /B
main.exe
main.pdb
main.rs
You see the source (.rs), the executable (main.exe on Windows, main elsewhere) and, on Windows, a .pdb file of debugging information. Then run it:
$ ./main # or .\main on Windows
Definition 1.6 (Ahead-of-time compiled). Compiled into an executable that can be given to someone else and run without Rust installed.
A .rb, .py or .js file needs a Ruby, Python or JavaScript implementation installed, but needs only one command to compile and run. Everything is a trade-off in language design. As projects grow, plain rustc gets unwieldy — hence Cargo.
The Rust Programming Language · Ch.1 Getting Started
12
Chapter 1 · 1.3 Hello, Cargo!
Cargo: Rust’s build system and package manager
Definition 1.7 (Cargo). Rust’s build system and package manager. It builds your code, downloads the libraries your code depends on, and builds those libraries. The libraries your code needs are its dependencies.
- Most Rustaceans use Cargo to manage their Rust projects, because it handles so many tasks for you.
- The simplest programs, like “Hello, world!”, have no dependencies; built with Cargo, they would use only the part of Cargo that builds your code.
- As programs grow more complex you add dependencies — and a project started with Cargo makes that much easier.
- Because the vast majority of Rust projects use Cargo, the rest of the book assumes you do too. The official installers include it.
If you installed Rust some other way, check for Cargo. A version number means you have it; an error such as command not found means you should consult your installation method’s documentation to install Cargo separately.
$ cargo --version
The Rust Programming Language · Ch.1 Getting Started
13
Chapter 1 · 1.3 Hello, Cargo!
Creating a project with cargo new
Go back to your projects directory and, on any operating system, run:
$ cargo new hello_cargo
$ cd hello_cargo
The first command creates a new directory and project named hello_cargo; Cargo creates its files in a directory of the same name. Inside you find:
- a Cargo.toml file;
- a src directory with a main.rs file inside;
- a newly initialized Git repository, with a .gitignore file.
Git files are not generated when you run cargo new inside an existing Git repository; override that with cargo new --vcs=git.
Remark. Git is a common version control system. The --vcs flag makes cargo new use a different version control system, or none. Run cargo new --help to see the options.
The Rust Programming Language · Ch.1 Getting Started
14
Chapter 1 · 1.3 Hello, Cargo!
The Cargo.toml manifest
Listing 1.2: Contents of Cargo.toml generated by cargo new
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2024"
[dependencies]
Definition 1.8 (TOML). Tom’s Obvious, Minimal Language, the format of Cargo’s configuration (toml.io).
Definition 1.9 (Crate). A package of Rust code.
- [package] is a section heading: the statements after it configure a package. More sections are added as the file grows.
- The next three lines give the information Cargo needs to compile the program: its name, its version, and the edition of Rust to use (editions: Appendix E).
- [dependencies] starts the section listing the project’s dependencies. This project needs no other crates; the Chapter 2 project will use this section.
The Rust Programming Language · Ch.1 Getting Started
15
Chapter 1 · 1.3 Hello, Cargo!
The generated src/main.rs and project layout
Cargo has generated a “Hello, world!” program for you, just like Listing 1.1:
src/main.rs
fn main() {
println!("Hello, world!");
}
So far the differences from the hand-made project are that the code lives in the src directory and there is a Cargo.toml configuration file in the top directory.
- Cargo expects source files inside src.
- The top-level directory is for README files, license information, configuration files and anything else not related to your code.
- Cargo helps you organize projects: a place for everything, and everything in its place.
To convert a project that doesn’t use Cargo, move its code into src and create a suitable Cargo.toml; cargo init creates that file for you.
The Rust Programming Language · Ch.1 Getting Started
16
Chapter 1 · 1.3 Hello, Cargo!
Building with cargo build
From the hello_cargo directory, build the project:
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
The executable goes to target/debug/hello_cargo (target\debug\hello_cargo.exe on Windows), not the current directory. The default build is a debug build, hence the directory name. Run it with:
$ ./target/debug/hello_cargo # or .\target\debug\hello_cargo.exe on Windows
Hello, world!
Definition 1.10 (Cargo.lock). A file created at the top level by the first cargo build. It keeps track of the exact versions of the project’s dependencies. Cargo manages it; you never need to change it by hand. With no dependencies, this project’s lock file is sparse.
The Rust Programming Language · Ch.1 Getting Started
17
Chapter 1 · 1.3 Hello, Cargo!
Compiling and running in one step: cargo run
cargo run compiles the code and then runs the resulting executable, all in one command. It is more convenient than remembering cargo build plus the whole path to the binary, so most developers use it.
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
This time there was no “Compiling” line: Cargo saw that the files hadn’t changed, so it didn’t rebuild and just ran the binary. After a change to the source, Cargo rebuilds before running:
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
The Rust Programming Language · Ch.1 Getting Started
18
Chapter 1 · 1.3 Hello, Cargo!
Checking without building: cargo check
cargo check quickly checks that your code compiles, but doesn’t produce an executable:
$ cargo check
Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Why not want an executable?
- cargo check is often much faster than cargo build, because it skips producing an executable.
- While you are writing code and continually checking your work, it speeds up learning whether the project still compiles.
- Many Rustaceans therefore run cargo check periodically as they write, and run cargo build when they are ready to use the executable.
The Rust Programming Language · Ch.1 Getting Started
19
Chapter 1 · 1.3 Hello, Cargo!
Recap of the Cargo commands so far
Table 1.1: Cargo commands introduced in this chapter
| Command | What it does |
|---|---|
| cargo new <name> | Creates a project (Cargo.toml, src/main.rs, Git repository) |
| cargo build | Builds the project; output goes to target/debug |
| cargo run | Builds (if needed) and runs the project in one step |
| cargo check | Checks for errors without producing a binary |
| cargo build --release | Builds with optimizations; output goes to target/release |
Instead of saving the build result in the same directory as the code, Cargo stores it in target/debug.
A further advantage: Cargo’s commands are the same on every operating system. From here on, the book no longer gives separate instructions for Linux and macOS versus Windows.
The Rust Programming Language · Ch.1 Getting Started
20
Chapter 1 · 1.3 Hello, Cargo!
Building for release, and Cargo’s conventions
Building for release
When the project is ready for release, cargo build --release compiles it with optimizations into target/release instead of target/debug. Optimizations make the code run faster but lengthen compile time. Hence two profiles: one for development, rebuilt quickly and often; one for the final program given to users, built once and run as fast as possible. When benchmarking running time, build with --release and benchmark the executable in target/release.
Leveraging Cargo’s conventions
For simple projects Cargo adds little over rustc, but it proves its worth once programs grow to multiple files or need a dependency. Even hello_cargo already uses the real tooling of a Rust career: to work on any existing project, check it out, enter its directory and build:
$ git clone example.org/someproject
$ cd someproject
$ cargo build
More about Cargo: its documentation at doc.rust-lang.org/cargo.
The Rust Programming Language · Ch.1 Getting Started
21
Chapter 1 · Summary
Chapter summary
You’re already off to a great start on your Rust journey. In this chapter you learned how to:
- install the latest stable version of Rust using rustup;
- update to a newer Rust version (rustup update);
- open the locally installed documentation (rustup doc);
- write and run a “Hello, world!” program using rustc directly;
- create and run a new project using the conventions of Cargo (cargo new, build, run, check, build --release).
Remark. Next, Chapter 2 builds a more substantial program — a guessing game — to get used to reading and writing Rust code. If you would rather first learn how common programming concepts work in Rust, read Chapter 3 and then return to Chapter 2.
The Rust Programming Language · Ch.1 Getting Started
22