Log in to access Rust Adventure videos!

Lesson Details

This workshop starts after you have Rust installed. If you haven’t installed Rust yet, go install it from the Rustup website.

The very first action we’ll take is to use Cargo, Rust’s package manager, to scaffold a new binary application.

cargo new first

Because we’ve used first as the name for our application, Cargo will create a folder named first/ and place a few files into it.

❯ tree .
.
├── Cargo.toml
└── src
    └── main.rs

Cargo.toml

The Cargo.toml file is our package manager file. Any dependencies we would use would get defined here. This file also includes

  • the name of our application, first
  • the version of the binary, 0.1.0
  • the edition of Rust we’re using, 2021
[package]
name = "first"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

src/main.rs

The other file we get is src/main.rs. This is where our application’s code will live. It is the entrypoint to our application.

The src/main.rs file location is the default location Cargo will look for the entrypoint to our binary when we build it.

fn main() {
    println!("Hello, world!");
}

Functions

We define functions in Rust using the fn syntax. In this case we have a function called main that doesn’t return anything.

The main function is special because that’s the function Rust will look for to run our application.

Printing to the console

Inside of the main function we have println, which is a macro. We know it’s a macro because when we call it it’s using the ! at the end of the name.

Macros are a topic for another day but using this one is much the same as using a function. It will take the string we give it and print that string to the console when our program runs. println will also print a newline out at the end of our string automatically.

Running the program

Our package manager, Cargo, contains a number of subcommands that are useful for building, testing, and running our applications.

In the most straightforward example, we can run our application using cargo run.

❯ cargo run
   Compiling first v0.1.0 (/rust-adventure/first)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33s
     Running `target/debug/first`
Hello, world!

On the first line Cargo tells us

  • the name of the program its compiling
  • the version of that program, which comes from Cargo.toml
  • and the filepath that program is located in

In the future this information can be useful if we have many binaries in one project.

On the second line, we see the profile information and how long the compilation took.

In our case the only two profiles we need to worry about are dev and release.

The Dev Profile

The dev profile is the default, and includes all of the extra debugging information you’d want when working on an application. Information like source code lines, function names, and other symbols. It is often a bigger filesize because of this added information and doesn’t include optimizations.

The Release Profile

The release profile on the other hand, will optimize our program and remove debug symbols. This results in a smaller, faster binary and is the profile you should use for production.

You can use the production profile by using the --release flag.

❯ cargo run --release
   Compiling first v0.1.0 (/Users/chris/github/rust-adventure/first-cli)
    Finished release [optimized] target(s) in 0.44s
     Running `target/release/first`
Hello, world!

Notice that the second line now says [optimized].

Finally the third line shows us which binary is being run.

The Target Directory

After taking all of our code and compiling it into a single binary file, that file is placed under either target/debug/first or target/release/first.

You can see this for yourself by running the binary we built directly. Pick either the debug or release binary and type the filepath into your terminal.

❯ ./target/debug/first
Hello, world!

In fact, all of the intermediary compilation artifacts that Cargo produces get placed in the target directory, which was created when we built and ran our program.

Cargo.lock

The other file that got created when we built our program was Cargo.lock. Cargo.lock is a file that records the version of the dependencies you used, so that builds in CI and other environments can replicate the same build.

This “lockfile” is similar to many other ecosystems such as package-lock.json in the JavaScript ecosystem.

Next Steps

And that’s it, you’ve run what could have been your first Rust program!

Congrats!

The rest of this workshop will build on this foundation to create a brand new CLI tool for scaffolding new files.