Setup

Rust

We will be using Rust to implement a programmatic incremental build system. Therefore, first make sure Rust is installed.

If you already have Rust installed, make sure to update to at least Rust 1.65.0 (Nov 2022), as we’re using features only available from that release.

Once Rust is installed, you should have access to cargo. Cargo is Rust’s package manager but also the command-line tool that ties everything together. As a consequence, Rust and Cargo are often used interchangeably when talking about developing Rust code.

Verify your Rust installation by running cargo from the command-line, which will show the help page for the cargo command.

Rust Editor / IDE

This tutorial does not require a specific Rust editor or IDE. All you need is some way to edit files, and some way to run cargo.

If you like to work in a terminal, rust-analyzer, the primary Language Server Protocol (LSP) implementation of Rust, can be used in Emacs and Vim/Neovim.

If you prefer a graphical editor, a popular choice is Visual Studio Code with the rust-analyzer plugin.

Personally, I am using the RustRover IDE, as it provides (in my opinion) the most polished and feature-full Rust editor/IDE. At the time of writing, RustRover is still in early access preview, meaning that it is free to use, but is still technically beta software. However, it is very stable despite being in preview. Once RustRover comes out of preview, you will need to pay for it though (or apply for a free educational or open source license).

Creating a new Rust project

In this tutorial, we will create a subset of the PIE in Rust library, so we want to create a Rust package called pie. However, later on in the tutorial we will also create an additional package (for unit testing utilities), so we need to set up a Rust workspace that supports multiple packages.

Therefore, first create a pibs directory, which will serve as the workspace directory of the project. This does not have to be called pibs, you can use a different name, but this tutorial will use pibs. Then create the pibs/Cargo.toml file with the following contents:

[workspace]
members = [
  "pie",
]
default-members = [
  "pie",
]
resolver = "2"

This Cargo.toml file marks the pibs directory as a Cargo workspace, with one (default) member package called pie. This package does not exist yet, but we will create it shortly. Because this pibs directory is now marked as a workspace, we can run cargo commands in this directory, and they will be automatically forwarded to the default members: currently only the pie package.

Now let’s set up the pie package. Create the pibs/pie directory, and then create the pibs/pie/Cargo.toml file with the following contents:

[package]
name = "pie"
version = "0.1.0"
edition = "2021"

Then create the pibs/pie/src directory and create the pibs/pie/src/lib.rs file, which will be left empty for now. This marks pie as a Cargo package, with version “0.1.0” and using Rust edition 2021. The lib.rs file is the main library file of the pie package.

The directory structure should look as follows:

pibs
├── pie
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
└── Cargo.toml

Now we can build the workspace to see if it was set up correctly. Open up a terminal, go back into the pibs workspace directory, and run cargo build. If all is well, the output should look something like:

   Compiling pie v0.1.0 (/pie)
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s

If you’re using a Rust editor or IDE, it probably also has a mechanism for running cargo on your project. You can of course use that in place of running cargo from a terminal.

Important

In the rest of the tutorial, we assume that you are in your pibs workspace directory. So if you are instructed to create files or directories, they are always relative to your pibs workspace directory!

Also, if you are instructed to run cargo commands, always run them inside the pibs workspace directory!

Cargo Workspaces, Packages, and Crates; Rust Editions

Cargo workspaces enable development of Rust projects with multiple libraries (which are called crates in Rust). The reference page on workspaces has more info regarding workspaces.

Cargo packages can have up to one library crate, and many binary crates. A crate is the smallest amount of code that the Rust compiler considers at a time. However, the word crate is often used interchangeably with library.

Rust editions enable new features as an opt-in, without breaking existing code. We use Rust edition 2021, which is the latest edition at the time of writing.

I recommend storing your code in a source control system such as Git, and uploading it to a source code hub such as GitHub. A source control system allows you to look at changes and to go back to older versions, and uploading to a source code hub then provides a convenient backup.

If you use Git, create the .gitignore file with:

/target

This ignores the target directory that Cargo uses to store intermediate and binary files.

Continue to the next chapter where we will start implementing the “programmatic” part of programmatic incremental build systems.

Download source code