Flashcard Rust: Cargo

Cargo is the one ring to rule them all, the one build tool that:

  • builds our rust project
  • downloads dependencies
  • build dependencies
  • help release optimized code

Let’s see how cargo helps us in packaging and releasing our code, get it? cargo.. packaging… ah ohkay, not the right time for terrible jokes I guess..

Using cargo to create Rust projects

Cargo should be installed as part of rust installation, to ensure cargo is installed run

> cargo --version
cargo 1.41.0

you should be able to see something like above… to create a wireframe for a new project hworld run:

> cargo new hworld

This creates a directory hworld, with few files and one directory:

>
|-- Cargo.toml
|-- src
    |-- main.rs

Cargo goes one step ahead and adds versioning to the project, git is used by default, so if you do a ls -la you can see few more files, but for now let’s ignore that and focus on the main files.

  • Cargo.toml - This is called the manifest file of our Rust project and is the file where we configure stuff like name, version of the project, Rust edition, the, author's, email address, and also there is a section to include the dependencies required by the project.

A sample Cargo.toml looks like:

[package]
name = "hworld"
version = "0.1.0"
authors = ["rahulunair <rahulunair@gmail.com>"]
edition = "2018"

[dependencies]
time = "0.1.12"

There are a lot more options that can be included in the manifest file, for an extensive list, see. Here I have specified one dependency time with version 0.1.12, we wont use it for anything now, but just for kicks eh?

  • ./src/main.rs - It is a placeholder to add our code, cargo has populated it with:
fn main() {
    println!("Hello, world!");
}

Building the project with Cargo

It’s just as simple as running the below command from inside hworld directory:

> cargo build

If you are running it for the first time, you would see something like:

Updating crates.io index
  Downloaded time v0.1.42
  Downloaded libc v0.2.67
   Compiling libc v0.2.67
   Compiling time v0.1.42
   Compiling hworld v0.1.0 (hworld)
    Finished dev [unoptimized + debuginfo] target(s) in 49.31s

That’s it, we have built our first program using cargo.

Running the program

After cargo has built the project successfully, it creates a directory ./target/debug/ to save the binary, we can just cd to ./target/debug and run:

> ./hworld
Hello, world!

Yay! we have run our first Rust program, that was created using Cargo.

Releasing our code

Release version ideally should be an optimized binary, to obtain such a binary, it is as simple as running:

> cargo build --release

Running the above command on my system from hworld directory, Cargo prints:

   Compiling libc v0.2.67
   Compiling time v0.1.42
   Compiling hworld v0.1.0 (hworld)
    Finished release [optimized] target(s) in 8.42s

And, lo and behold there is an optimized binary hworld in hworld/target/release/, in later posts, we can see the difference between debug and release versions of binaries generated by Cargo.

The eligance of Cargo is that, everything is named as we would expect, no gotcha’s .. I really like that about Cargo.

The end

As a closing note, let’s recap Cargo mainly does two things for us,

  • builds our project using - cargo build or cargo build –release
  • builds and runs our project using - cargo run

Now, there is a third and final command I use, to check for compilation issues fast, without really building the binary, which can be slow at times.

The command to check if everything is alright is:

> cargo check

On my system it gives me this:

    Checking libc v0.2.67
    Checking time v0.1.42
    Checking hworld v0.1.0 (hworld)
    Finished dev [unoptimized + debuginfo] target(s) in 3.61s

That’s it, so we saw what cargo can do, it is a tool that can be used when we are building a Rust project, but if it is a simple file, with no dependencies we can still use rustc as we saw earlier in Flashcard Rust.