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.