TLDR; this article covers how to work with Rust projects using Cargo. As soon as you are dealing with more than one file, it's a good idea to adopt Cargo.
Project management
When you develop software, you have a few things you want need to consider. The following are some of the major things you need to keep track of:
- Many files. For reasons of order, you quickly grow out of using more than one file to code in. Dividing up you code in many files enables you to get a clearer picture of what you're building, which creates order but makes it easier to collaborate with others and other benefits.
- 3rd party libraries. You can definitely write all the code yourself but it will take you a while, especially if your project is complicated. A better approach is to write business related code yourself and rely on standard libraries as well as 3rd party libraries for the remaining code.
- Building your project. As your project grows, it becomes more and more complicated to build. You might need to build it differently for different operating systems and for development vs production for example.
- Run tasks. As part of creating a large project with many files, you will find yourself wanting to run various tasks on your project, like building, testing, linting and so on.
Resources
- Cargo book
- Learning path on Rust
- Crates.io Here you can find crates, i.e. packages you can use for your projects. You can also search for packages via the command line. Refer to Cargo book for how to search for that.
- Rust path on Learn
Cargo
Ok, now that we know a little more about projects and what we're expected to manage, how does Rust approach project management? The answer is Cargo. Cargo comes with your Rust install and helps you with a lot of things like:
- Creating a project. Cargo helps you create a project and helps you track things like name, version, your dependencies, and other concepts.
- Build and run your code. Cargo can help you compile and run your code.
- Feature management. You can also divide up your project in features, if you say have a client that only paid for a subset of features. In such a case you only want to ship part of the code to said client. Read more here on feature management
- Dependency management. Your project will likely consist of dependencies, libraries or binaries that you use to build your app. You don't want to write code if there is code out there that already solves what you're trying to do.
- Package management. When you create a project with Cargo, it assumes your project will be a package. A package is something you can theoretically share with others
- Running tests. Cargo can run tests. Read more here on running tests
The above is some of Cargo's features, but hopefully right now, you know that Cargo is your best friend and that it's fantastic that a tool like this comes built-in with a Rust install.
The topic of Cargo is so large there's a whole book dedicated to it, Cargo book
Exercise - Your first project
To create your first project using Cargo, you invoke the cargo
executable with keyword new
and lastly with the name of the project like so:
cargo new project-name
Creates a project-name subdirectory. In said directory we get the following files:
src/
main.rs
.gitignore
Cargo.toml
Here's what the files mean:
- main.rs, The main.rs is our projects main file, the entry for our app. Here's what main.rs contains:
fn main() {
println!("Hello, world!");
}
- Cargo.toml, this project file that does two things, manage meta information on this project and manage any dependencies your app needs to function. Here's what the file looks like:
[package]
name = "project-name"
version = "0.1.0"
authors = ["email, inferred from Git"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
As you can see, you've got information on your project under the [package]
portion like name, version, authors, and edition. There's another section [dependencies]
that's empty for now, as you don't have any external dependencies.
Build and run your code
To build and run your project, call cargo run
in your project directory root:
cargo run
You should see an output resembling this text:
Compiling project-name v0.1.0 (/<path>/project-name)
Finished dev [unoptimized + debuginfo] target(s) in 21.51s
Running `target/debug/project-name`
Hello, world!
What you see is Cargo building and running your code and it ends up showing the text "Hello world!".
Exercise - Make a change
We've decided to make a nice looking CLI, command line application. For that, we will use an external library termion
that gives us a colored output.
- Add
termion
by opening up Cargo.toml and located the [dependencies] section and make the following alteration:
[dependencies]
termion = "*"
Great, now we're telling Cargo we want the library termion
, next let's leverage that library in our code.
- Open up main.rs and change the code to the following:
extern crate termion;
use termion::{color};
fn main() {
println!("{}Red", color::Fg(color::Red));
println!("{}Blue", color::Fg(color::Blue));
println!("Hello, world!");
}
- Run your project with
cargo run
:
cargo run
What you see now is your project going to "crates.io", where the "termion" package is located and attempt to download it
Updating crates.io index
Downloaded termion v1.5.6
Downloaded numtoa v0.1.0
Downloaded libc v0.2.108
Downloaded 3 crates (591.2 KB) in 0.52s
Compiling libc v0.2.108
Compiling numtoa v0.1.0
Compiling termion v1.5.6
Compiling project-name v0.1.0 (/<path>/project-name)
last in your terminal output, you see the colored output:
I read somewhere that this might not work on Windows, please let me know in the comments if you have issues getting this to work.
Summary
In this article, we looked at a "grow up" story, when we went from using rustc
to compile our code and starting using Cargo for that and many other things. Project management means you have a lot of things to consider, and Cargo handles many of them. Cargo is your new best friend and hopefully you can learn more about using Cargo by the links provided in the resources section in this article. All future parts in this series will use Cargo.