Cargo

The basic Rust tooling is composed of three programs:

  • cargo: The Rust package manager
  • rustc: The Rust compiler
  • rustup: The Rust toolchain manager

Most users will never touch (or even see) rustc directly, but will usually use rustup to install it and then let cargo orchestrate the compilation.

Running cargo without any arguments reveals the subcommands it provides:

$ cargo
Rust's package manager

USAGE:
cargo [OPTIONS] [SUBCOMMAND]

OPTIONS:
-V, --version Print version info and exit
--list List installed commands
--explain <CODE> Run `rustc --explain CODE`
-v, --verbose Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color <WHEN> Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z <FLAG>... Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
-h, --help Prints help information

Some common cargo commands are (see all commands with --list):
build Compile the current project
check Analyze the current project and report errors, but don't build object files
clean Remove the target directory
doc Build this project's and its dependencies' documentation
new Create a new cargo project
init Create a new cargo project in an existing directory
run Build and execute src/main.rs
test Run the tests
bench Run the benchmarks
update Update dependencies listed in Cargo.lock
search Search registry for crates
publish Package and upload this project to the registry
install Install a Rust binary
uninstall Uninstall a Rust binary

There are a few clues here as to what the package manager can do. Other than resolving different types of dependencies for projects, it acts as a test runner for benchmarks and unit/integration tests, and provides access to registries such as crates.io (https://crates.io/). Many of these properties can be configured in a .cargo/config file in the TOML (https://github.com/toml-lang/toml) syntax, either in your home directory, the project directory, or the hierarchy in between.

The individual properties that can be configured can easily evolve over time, so we'll focus on some core parts.

Local repositories can be customized with a paths property (an array of paths) in the root section of the file, whereas any command-line arguments for the cargo new command can be found in the [cargo-new] section of the file. If these custom repositories are remote, this can be configured in [registry] and [http] for the proxy address and port, custom certificate authority (cainfo), or high latencies (timeout) .

These are handy configurations for enterprise systems with private repositories, or CI builds with shared drives acting as caches. However, there are options to customize the toolchain, by letting the user provide some configuration in a [target.$triple] section (for example, [target.wasm32-unknown-unknown] to customize a Wasm target). Each of those sections contains the following properties:

  • A linker specific to the selected triple
  • Another archiver by customizing ar
  • A runner for running the program and associated tests
  • Flags for the compiler in rustflags

Lastly, the build configuration is set within the [build] section, where the number of jobs, binaries, such as rustc or rustdoc, the target triple, rustflags, or incremental compilation can be set. To learn more about configuring cargo and to obtain a sample of this configuration, go to https://doc.rust-lang.org/cargo/reference/config.html.

In the next sections, we are going to explore the core of cargo: the project.