Building Multiple Binaries in Rust

1. Overview

In Rust, a binary is an executable file that serves as an entry point to a program. By default, a typical Rust project consists of a single binary. However, with some configurations, we can create multiple binaries, each with its own entry point.

In this tutorial, we’ll explore different methods to build multiple binaries in Rust with sample codes.

2. Using the workspace

The workspace is a feature in Rust that groups two or more packages together. Individual packages in a workspace are referred to as members.

For the workspace feature to work as expected, we need to define our project structure correctly. In this section, we’ll examine a sample project that builds multiple binaries using the workspace.

To begin with, let’s create a directory named “space-project“.

Here’s the propose project directory structure:

space-project/
├── Cargo.toml
├── planet-mars/
│   ├── Cargo.toml
│   └── src/
│       └── main.rs
├── planet-venus/
│   ├── Cargo.toml
│   └── src/
          └── main.rs

Next, let’s create a Cargo.toml file in the root directory with workspace attribute:

[workspace]
members = []

Now the workspace is set up with no member. Next, let’s create a new project in the root directory named “planet-mars“:

$ cargo init planet-mars

Then, let’s modify the main.rs to output “Welcome to Mars”:

fn main() {
    println!("Welcome to Mars!");
}

Additionally, let’s create another project in “space-project” directory and named it “planet-venus“:

$ cargo init planet-venus

Next, let’s edit the main.rs file to output “Welcome to Venus”:

fn main() {
    println!("Welcome to Venus!");
}

The two binary projects are now set up in the root directory of space-project. Next, let’s modify the Cargo.toml file in the root directory to declare members of the workspace:

[workspace]
members = [ "planet-mars", "planet-venus"]

Here, we modify the workspace attribute to include the two binary projects will create earlier.

Next, let’s build the project:

$ cargo build

Here’s the terminal output:

Compiling planet-venus v0.1.0 (/path/space-project/planet-venus)
Compiling planet-mars v0.1.0 (/path/space-project/planet-mars)
Finished dev [unoptimized + debuginfo] target(s) in 0.54s

In the above output, the location of the executable for the two binaries is specified. We can run the individual binary with the cargo run command. For example, to execute planet-venus, we’ll use cargo run and specify the binary:

$ cargo run -p planet-venus

We can now execute individual binary with the cargo run command.

3. Using a bin Directory

Another proven way to build multiple binaries in Rust is to create bin folder in the src folder of a project. All the binaries for the project will be in the bin folder. This approach work for only single project with multiple binaries.

Before we dive into the code, let’s understand the directory structure:

my_project/
├── Cargo.toml
└── src/
    ├── bin/
    │   ├── binary1.rs
    │   └── binary2.rs
    └── main.rs

In this structure, Cargo.toml is the package manifest, main.rs is the main library file, and binary1.rs and binary2.rs are the binary files.

To build each binaries, we need to place each binary in src/bin directory. Each .rs file in the directory will be built as a separate binary.

Let’s create two binaries to demonstrate this approach. First, let’s create a binary named binary1.rs to print “Hello Japan”:

fn main() {
    println!("Hello Japan!");
}

Next, let’s create the second binary named binary2.rs to print “Hello USA”:

fn main() {
    println!("Hello USA!");
}

To build the two binaries, we can use the cargo build command:

$ cargo build

This command will compile all binaries and libraries in the project. The resulting binaries will be place in the target/debug directory.

To run a specific binary, we can use the cargo run –bin command followed by the binary name:

$ cargo run --bin binary1
Hello from Japan!

5. Conclusion

In this article, we learned two ways to build multiple binaries in Rust. The choice between the two depends on the size of the project.

The complete source code for the examples is available on GitHub.