cargo is the Rust package manager, and is as well used to manage a Rust
project as to install applications (crates) from the official repository.
The different actions provided by cargo are accessed through a set of
sub-commands. See Table 1 for a list of the main
sub-commands.
To get the full list of sub-commands, run the following command:
cargo --listTable 1:Main sub-commands of cargo
Sub-command | Shortcut | Description |
|---|---|---|
| Add dependencies to a Cargo.toml manifest file. | |
| Compile a local package and all of its dependencies. | |
| Check a local package and all of its dependencies for errors. | |
| Remove artifacts that cargo has generated in the past. | |
| Check a package to catch common mistakes and improve your Rust code. | |
| Inspect configuration values. | |
|
| Build a package’s documentation. |
| Automatically fix lint warnings reported by rustc. | |
| Create a new cargo package in a new or existing directory. | |
| Install a Rust binary. | |
| Create a new cargo package in a new directory. | |
|
| Remove dependencies from a Cargo.toml manifest file. |
|
| Run a binary or example of the local package. |
| Search packages in the registry. Default registry is crates.io. | |
|
| Execute all unit and integration tests and build examples of a local package. |
| Display a tree visualization of a dependency graph. | |
| Remove a Rust binary. | |
| Show version information. |
3.4.1Installing an application¶
Rust public packages are called crates and provide binaries as well
as libraries. Very useful Rust applications are available today on
the official crate repository
(https://crates.io/).
We present in Table 2 a list of some of them.
Most of them are replacement for standard Unix commands (e.g.: ls,
find, cat, tree) that run faster and propose colourful
outputs.
Table 2:Useful Rust applications
Crate | Command | Description |
|---|---|---|
| Replacement for | |
| Replacement for | |
| Replacement for | |
| Replacement for | |
| Replacement for | |
| Replacement for | |
| Replacement for | |
| Replacement for | |
| Rendering of MiniJinja/Jinja2 templates. | |
| An application to learn Rust through exercises. |
See Install a crate with Cargo to learn how to search for a crate and how to install it.
3.4.2Initializing a project¶
3.4.2.1Creating a new project from scratch¶
This is easily done with Cargo.
To initialize a new project inside a new directory named foo, we run:
cargo init --bin foo Creating binary (application) package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
This will create a project file Cargo.toml and a source file src/main.rs
that contains a default main() function:
eza -T foofoo
├── Cargo.toml
└── src
└── main.rs
The project file defines a project name, a project version and the
edition year of the cargo tool to use for managing this project:
bat foo/Cargo.toml[package]
name = "foo"
version = "0.1.0"
edition = "2024"
[dependencies]
If we look at the hidden files inside the project folder, we find that two Git related files have also been created:
ls -a foo. .. .git .gitignore Cargo.toml src
The .git folder means a Git database has been created.
The .gitignore file contains a single line that makes Git ignore the
target folder that is used by Cargo for its building outputs:
bat foo/.gitignore/target
Note that, however, the created Git database is left empty. All created files are list as untracked. This is up to us to include them or not inside the Git repository:
pushd foo
git status/tmp/tmp.Ic2WIzFr1b/foo /tmp/tmp.Ic2WIzFr1b
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
Cargo.toml
src/
nothing added to commit but untracked files present (use "git add" to track)
3.4.3Building the project¶
To compile a whole project, we use the build sub-command:
cargo build Compiling foo v0.1.0 (/tmp/tmp.Ic2WIzFr1b/foo)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s
To build in release (i.e.: no debug information) mode:
cargo build -r Compiling foo v0.1.0 (/tmp/tmp.Ic2WIzFr1b/foo)
Finished `release` profile [optimized] target(s) in 0.11s
3.4.4Running the application¶
To run the application, we use the run sub-command:
cargo run Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/foo`
Hello, world!
If there are multiple binaries in the project, we use the --bin option to
set the binary to run:
cargo run --bin foo Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/foo`
Hello, world!
To pass, argument to our binary, we would set them after a double dash --:
cargo run --bin foo -- arg1 arg2 arg3 ...3.4.5Adding dependencies¶
To use external dependencies (e.g.: packages from
crates.io), like in the following example with the
colour package, we need first to declare it with cargo:
bat src/main.rsuse colour::*;
fn main() {
magenta_ln!("My coloured message.");
}
To declare the dependency, we use the add sub-command:
cargo add colour Updating crates.io index
warning: failed to write cache, path: /usr/local/cargo/registry/index/index.crates.io-1949cf8c6b5b557f/.cache/co/lo/colour, error: Permission denied (os error 13)
Adding colour v2.1.0 to dependencies
Updating crates.io index
warning: failed to write cache, path: /usr/local/cargo/registry/index/index.crates.io-1949cf8c6b5b557f/.cache/co/lo/colour, error: Permission denied (os error 13)
Locking 4 packages to latest Rust 1.95.0 compatible versions
Adding colour v2.1.0
Adding winapi v0.3.9
Adding winapi-i686-pc-windows-gnu v0.4.0
Adding winapi-x86_64-pc-windows-gnu v0.4.0
The dependencies section now contains a line for the colour package with
a version requirement:
bat Cargo.toml[package]
name = "foo"
version = "0.1.0"
edition = "2024"
[dependencies]
colour = "2.1.0"
Cargo also creates a lock file that contains the version used for each
dependency. Here is an excerpt from the Cargo.lock file:
bat -r 5:27 Cargo.lock[[package]]
name = "colour"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b536eebcabe54980476d120a182f7da2268fe02d22575cca99cee5fdda178280"
dependencies = [
"winapi",
]
[[package]]
name = "foo"
version = "0.1.0"
dependencies = [
"colour",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
Running the application, will trigger the installation of the dependencies, as well as compilation, before running:
cargo run Updating crates.io index
warning: failed to write cache, path: /usr/local/cargo/registry/index/index.crates.io-1949cf8c6b5b557f/.cache/co/lo/colour, error: Permission denied (os error 13)
Downloading crates ...
Downloaded colour v2.1.0
error: failed to open `/usr/local/cargo/registry/cache/index.crates.io-1949cf8c6b5b557f/colour-2.1.0.crate`
Caused by:
Permission denied (os error 13)
3.4.6Running tests¶
We suppose we have implemented some test inside the tests folder:
eza -T testsRunning this test, is as simple as running the test sub-command.
Compiling of both the application and the tests will be triggered prior to
running the tests:
cargo test3.4.7Checking the project¶
The check sub-command checks for errors inside the local packages and its
dependencies. To do that, it runs a compiling up to, but excluding, the code
generation. This means that most of compiling errors will be detected, but not
all. However, it performs faster that the build sub-command, and thus is
interesting for quick error checking:
cargo check3.4.8Linting the project¶
The clippy sub-command catches common mistakes, and gives advice to
correct them. It helps us improve the quality of our code.
In the following example, we define a Book structure:
bat src/main.rsThe program compiles perfectly:
cargo buildHowever, clippy finds some issues in it:
cargo clippyIn this other example, plain clippy misses the possible style improvement:
bat src/main.rsNothing is pointed out by clippy:
cargo clippyTo get the hint, we need to use the pedantic mode:
cargo clippy -- -W clippy::pedantic3.4.9Fixing automatically linting issues¶
The fix sub-command is able to solve automatically some of the warnings
pointed out by the Rust compiler.
In the following example we have introduced a useless mut (mutable)
specifier:
bat src/main.rsThe check sub-command catches the mistake:
cargo checkRunning the fix sub-command will solve the issue for us:
cargo fixThe mut keyword has been removed:
bat src/main.rs