Dependency Management with Cargo
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
Cargo.lock - A lock file
- contains a list of all project dependencies, de-facto versions and hashes of downloaded dependencies
- when a version is yanked from Crates.iobut you have the correct hash for it in a lock file Cargo will still let you download it and use it- still gives you warning about that version being problematic
 
- should be committed to your repository for applications
Dependency resolution
- uses "Zero-aware" SemVer for versioning
- 1.3.5is compatible with versions- >= 1.3.5and- < 2.0.0
- 0.3.5is compatible with versions- >= 0.3.5and- < 0.4.0
- 0.0.3only allows- 0.0.3
 
- allows version-incompatible transitive dependencies
- except C/C++ dependencies
 
- combines dependencies with compatible requirements as much as possible
- allows path, git, and custom registry dependencies
How a dependency version is selected
- for every requirement Cargo selects acceptable version intervals
- [1.1.0; 1.6.0),- [1.3.5, 2.0.0),- [2.0.0; 3.0.0)
 
- Cargo checks for interval intersections to reduce the number of unique intervals
- [1.3.5; 1.6.0),- [2.0.0; 3.0.0)
 
- for every unique interval it selects the most recent available version
- =1.5.18,- =2.7.11
 
- selected versions and corresponding package hashes are written into Cargo.lock
Dependency resolution: Example
└── my-app                      May install:
    ├── A = "1"
    │   ├── X = "1"             A = "1.0.17"
    │   └── Y = "1.3"     =>    B = "1.5.0"
    └── B = "1"                 X = "2.0.3"
        ├── X = "2"             X = "1.2.14"
        └── Y = "1.5"           Y = "1.8.5"
Where do dependencies come from?
- Crates.io
- Private registries (open-source, self-hosted, or hosted)
- Git and Path dependencies
- dependencies can be vendored
Notes:
- private registries
Shipyard and Kellnr will also generate API docs for you
Crates.io
- default package registry
- 100k crates and counting
- every Rust Beta release is tested against all of them every week
 
- packages aren't deleted, but yanked
- if you have a correct hash for a yanked version in your Cargo.lockyour build won't break (you still get a warning)
 
- if you have a correct hash for a yanked version in your 
Docs.rs
- complete API documentation for the whole Rust ecosystem
- automatically publishes API documentation for every version of every crate on Crates.io
- documentation for old versions stays up, too. Easy to switch between versions.
- links across crates just work
Other kinds of dependencies
- git dependencies
- both git+httpsandgit+sshare allowed
- can specify branch, tag, commit hash
- when downloaded by Cargo exact commit hash used is written into Cargo.lock
 
- both 
- path dependencies
- both relative and absolute paths are allowed
- common in workspaces
 
C Libraries as dependencies
- Rust can call functions from C libraries using unsafecode- integrate with operating system APIs, frameworks, SDKs, etc.
- talk to custom hardware
- reuse existing code (SQLite, OpenSSL, libgit2, etc.)
 
- building a crate that relies on C libraries often requires customization
- done using build.rsfile
 
- done using 
build.rs file
- compiled and executed before the rest of the package
- can manipulate files, execute external programs, etc.
- download / install custom SDKs
- call cc,cmake, etc. to build C++ dependencies
- execute bindgento generate Rust bindings to C libraries
 
- output can be used to set Cargo options dynamically
println!("cargo:rustc-link-lib=gizmo"); println!("cargo:rustc-link-search=native={}/gizmo/", library_path);
-sys crates
- often Rust libraries that integrate with C are split into a pair of crates:
- library-name-sys- thin wrapper around C functions
- often all code is autogenerated by bindgen
 
- library-name- depends on library-name-sys
- exposes convenient and idiomatic Rust API to users
 
- depends on 
 
- examples:
- openssland- openssl-sys
- zstdand- zstd-sys
- rusqliteand- libsqlite3-sys