Using Cargo
Crates and Packages
- Rust code is arranged into packages
- a package is described by a
Cargo.toml
file - building a package can produce a single library, and 0 or more executables
- these are called crates
- unlike C/C++ compilers that compile code file by file,
rustc
treat all files for a crate as a single compilation unit
- Cargo calls
rustc
to build each crate in the package.
Cargo
- standard build toolchain for Rust projects
- shipped with
rustc
What Cargo does
- resolves and installs project dependencies
- runs
rustc
to compile your code - runs a linker to produce libraries and executables
- runs tests and benchmarks
- builds documentation and runs documentation tests
- runs additional tools like code formatter and linter
- can be extended with additional custom commands
Cargo does Everything!
Cargo commands
cargo new my-app
cargo run
- runs a debug build of your program, builds it if necessarycargo fmt
- formats your codecargo check
- only reports errors, doesn't actually compile your codecargo clippy
- runs a lintercargo test
- builds your project if necessary and runs tests- by default runs unit tests, integration tests, and documentation tests
- you can select which tests to run
cargo build --release
- produces an optimized version of your application or library
Cargo commands (cont)
There are many more!
cargo bench
- builds an optimized version of your project and runs benchmarkscargo doc --open
- builds documentation for your project and all its dependencies and opens it in a browsercargo run --example ...
- runs an example from yourexamples/
directory
See Cargo Book for more.
Cargo command arguments
Most cargo commands accept a few common arguments:
+toolchain
--target
--features
,--all-features
, and--no-default-features
--timings
Putting it all together:
cargo +nightly run --target x86_64-apple-darwin --features "a b c dependency/feature" --timings
- use nightly Rust
- enable features
a
,b
,c
, and afeature
feature of adependency
crate - (assuming we use Apple Silicon computer) build a macOS executable for x86 processor and run it using built-in emulation (Rosetta2)
- collect statistics during the build process and generate a report
Features
- allows conditional compilation
- support for different operating systems
- adapters for different libraries
- optional extensions
- can expose features from transitive dependencies
Using Features
-
in code:
#[cfg(feature = "json")] mod json_support;
-
in
Cargo.toml
[features] json = [] # list of features that this feature depends on default = [] # "json" feature is not enabled by default
-
when someone uses your dependency
my-lib = { version: "1.0.0", features = ["json"] }
Anatomy of Rust package
cargo new hello-world
├── Cargo.lock
├── Cargo.toml
└── src/
└── main.rs
Anatomy of Rust package
├── Cargo.lock
├── Cargo.toml
├── build.rs
├── src/
│ ├── lib.rs
│ ├── main.rs
│ ├── ...
│ └── bin/
│ ├── additional-executable.rs
│ └── multi-file-executable/
│ ├── main.rs
│ └── ...
├── benches/
│ └── ...
├── examples/
│ └── ...
└── tests/
├── some-integration-tests.rs
└── multi-file-test/
├── main.rs
└── ...
Cargo.toml - A manifest file
[package]
name = "tcp-mailbox"
version = "0.1.0"
[dependencies]
async-std = "1" # would also choose 1.5
clap = "2.2" # would also choose 2.3