Cargo 包管理工具

2022-10-26 rust language

Rust 提供了 Cargo 的构建系统和软件包管理器,可以用来构建代码、下载库或依赖项等等,在安装 Rust 时会同时安装 Cargo 相关的程序。

这里详细介绍 Cargo 的使用方式。

简介

这是 Rust 的包管理工具,可以用来编译、下载相关的包,通过 Cargo 用来管理 Rust 项目,包括了构建代码、下载依赖库等。

$ cargo new hello
     Created binary (application) `hello` package
$ tree hello/
hello/
├── Cargo.toml
└── src
    └── main.rs
1 directory, 2 files

通过 new 子命令创建一个项目后,会自动生成两个文件,包括了项目信息 Cargo.toml 以及源码示例 main.rs 文件中。

----- 查看项目信息配置文件,也就是包含了名称、版本等信息
$ cat Cargo.toml
[package]
name = "hello"
version = "0.1.0"
edition = "2021"

[dependencies]
----- 以及对应的源码文件
$ cat src/main.rs
fn main() {
    println!("Hello, world!");
}

其它常见命令有:

  • cargo init 在某个目录下初始化,或者 cargo init your_crate --bin/--lib 新建子目录;
  • cargo add 添加依赖包,通过 --dev 只添加到开发环境,-F 可指定特性;
  • cargo build 编译成二进制文件,会在 target/debug 目录下生成;
  • cargo run 编译后同时运行,会在 target/debug 目录下生成;
  • cargo clean 清理编译过程中的文件、目录信息;
  • cargo check 仅检查并不编译;
  • cargo build --release 会使用更多的优化选项,编译慢但是运行快,最终在 target/release 目录下生成;
  • cargo update 更新所有的包,可以通过 -p package 指定特定的包进行更新。

在编译阶段,会将包的信息更新到 Cargo.lock 文件中,其中包含了依赖的版本信息,这样可以保证可重复编译的可执行文件。

这里简单添加一个依赖。

$ cat Cargo.toml
[package]
name = "hello"
version = "0.1.0"
edition = "2021"

[dependencies]
rand = "0.8.5"
$ cat src/main.rs
fn main() {
    println!("Hello World! Random {}", rand::random::<u8>());
}

默认包含了开发 (cargo build)和发布 (cargo build --release) 两种模式,可以据此配置不同的参数,

依赖管理

支持从多种源下载依赖包:A) 包管理仓库,默认使用 crates.io 仓库,还可以指定其它仓库,允许指定具体版本;B) 指定 GitHub 中的代码库,包括某个分支、Tag 等。

如果要依赖其它仓库,可以在 ~/.cargo/config.toml 中增加如下配置。

[registries]
ustc = { index = "https://mirrors.ustc.edu.cn/crates.io-index/" }

如下是常用的使用方式。

[dependencies]
time = "0.1.12"                # 默认从crates.io中下载
time = {  registry = "ustc" }  # 从指定仓库下载

# 可以依赖 GitHub 的仓库
regex = { git = "https://github.com/rust-lang/regex" }

# 以及使用本地文件
hello_utils = { path = "hello_utils" }

此时的包会缓存在 ~/.cargo/registry 目录下。

Workspace

由多个 Package 组成的集合,共享一个 Cargo.lock 文件、输出目录、配置等,支持 Root PackageVirtual Manifest 两种类型,区别于根 Cargo.toml 是否存在 [package] 配置项。有 workspace 但没有 package 就是虚拟清单,此时只用于子 crate 文件的管理,本身不包含 package 包。

另外,还支持一些包信息、依赖的共享,例如如下的根配置。

[workspace]
members = [
    "examples"
    "crates/*"
    "tests"
    "repos"
]

[workspace.package]
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
rust-version = "1.75.0"
keywords = ["xxx", "yyy"]
readme = "README.md"
description = "Some information"
homepage = "https://github.com/your/repos"
repository = "https://github.com/your/repos"

[workspace.package]
serde = { version = "1.0.201" }
tokio = { version = "1", features = ["rt-multi-thread"] }

然后其它 crateCargo.toml 可以配置如下。

[package]
name = "your-crate-name"
version = {workspace = true} # or version.workspace = true

[dependencies]
your-crate = { path = "../core" }

[dev-dependencies]
tokio = { workspace = true }

其它

打包发布

crate.io/settings/tokens 中可以创建 Token,然后通过如下命令登陆、发布包。

----- 会提示输入生成的Token
cargo login --registry crates-io

----- 会在 target/package 目录下生成相应的文件
cargo package

----- 如果配置了其它代理需要通过如下方式指定 crates 地址
cargo publish --registry crates-io

参考