Cargo.toml 是 Cargo 项目的清单文件(TOML 格式),描述包名、版本、依赖、特性、编译目标等。本文给出常用配置速查。

最小示例

1
2
3
4
5
6
7
[package]
name = "myapp"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "1", features = ["derive"] }

[package] 项目元信息

1
2
3
4
5
6
7
8
9
10
11
12
13
[package]
name = "myapp" # 必填,crate 名
version = "0.1.0" # 必填,SemVer
edition = "2021" # edition:2015/2018/2021
rust-version = "1.74" # MSRV:最低 Rust 版本
authors = ["Alice <a@example.com>"]
description = "一句话描述"
license = "MIT OR Apache-2.0"
repository = "https://github.com/user/myapp"
readme = "README.md"
keywords = ["cli", "parser"] # 最多 5 个
categories = ["command-line-utilities"] # 取自 crates.io 预定义列表
publish = false # 禁止发布(私有项目)

依赖版本指定

1
2
3
4
5
[dependencies]
serde = "1.0" # 默认 ^,等同 >=1.0.0, <2.0.0
serde = "~1.2.3" # >=1.2.3, <1.3.0
serde = "=1.2.3" # 精确版本
serde = ">=1.0, <2.0" # 区间
前缀1.2.3 展开为说明
^(默认)>=1.2.3, <2.0.0兼容更新
~>=1.2.3, <1.3.0仅 patch 升级
==1.2.3精确

注意 ^0.2.3 展开为 >=0.2.3, <0.3.0——0.x 的 minor 视为不兼容边界,不会自动升到 0.3

依赖来源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[dependencies]
# registry
serde = "1"

# git
mylib = { git = "https://github.com/user/mylib", branch = "dev" }
# 也可用 tag = "v0.3" 或 rev = "abc123"

# 本地路径
mylib = { path = "../mylib" }
# path + version:本地用 path,发布时回退到 version
mylib = { path = "../mylib", version = "0.2" }

# 可选依赖(配合 features)
serde = { version = "1", optional = true }

# 重命名(代码中用 json 引入 serde_json)
json = { package = "serde_json", version = "1" }

# 禁用默认 feature 并启用指定 feature
serde = { version = "1", default-features = false, features = ["derive"] }

dev / build 依赖

1
2
3
4
5
[dev-dependencies]      # 仅测试/示例/bench,不进发布产物
pretty_assertions = "1"

[build-dependencies] # 仅 build.rs 使用
cc = "1"

平台特定依赖

1
2
3
4
5
6
7
8
[target.'cfg(windows)'.dependencies]
winapi = "0.3"

[target.'cfg(unix)'.dependencies]
nix = "0.27"

# 组合表达式
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]

常用 cfg 键:target_os(linux/macos/windows)、target_family(unix/windows)、target_arch(x86_64/aarch64/wasm32)。

[features] 特性开关

1
2
3
4
5
6
[features]
default = ["tls"] # 默认启用
tls = [] # 空开关,由代码 #[cfg(feature = "tls")] 检测
json = ["dep:serde"] # 启用可选依赖(dep: 不带其 default features)
full-async = ["tokio/full"] # 启用依赖的 feature
compression = ["flate2", "json"] # 依赖其他 feature

cargo build --no-default-features --features "tls,json" 控制。dep: 语法(Cargo 1.60+)避免与依赖同名 feature 冲突。

编译目标

1
2
3
4
5
6
7
8
9
10
11
12
13
[lib]
name = "mylib"
path = "src/lib.rs"
crate-type = ["lib"] # lib/rlib/cdylib/staticlib/proc-macro
proc-macro = false

[[bin]]
name = "myapp"
path = "src/main.rs" # 默认 src/main.rs 或 src/bin/<name>.rs

[[bench]]
name = "my_bench"
harness = false # 用 criterion 等自带 main 时关闭

crate-type 常用值:lib(被 Rust 依赖)、cdylib(给 C/Python 调用)、staticlib(C 静态库)、proc-macro(过程宏)。

自动发现:src/bin/*.rsexamples/*.rstests/*.rsbenches/*.rs 各自识别为目标。

[profile.*] 编译配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[profile.release]
opt-level = 3 # 0-3 / "s" / "z"
debug = false # true/false/0-2/"line-tables-only"
strip = "symbols" # 去符号减小体积
lto = "thin" # false/"thin"/"fat",跨 crate 内联
codegen-units = 1 # 1 最优优化但编译慢
panic = "abort" # 体积更小,但 Drop 不保证执行
incremental = false

# dev 模式优化依赖、本 crate 不优化(开发加速)
[profile.dev.package."*"]
opt-level = 2

# 自定义 profile(cargo build --profile release-lto)
[profile.release-lto]
inherits = "release"
lto = "fat"

环境变量覆盖:CARGO_PROFILE_RELEASE_LTO=fat cargo build --release

[workspace] 工作空间

1
2
3
4
5
6
7
8
9
10
11
12
# 根 Cargo.toml
[workspace]
members = ["crate-a", "crate-b"]
resolver = "2"

[workspace.package]
version = "0.4.0"
edition = "2021"
license = "MIT OR Apache-2.0"

[workspace.dependencies]
serde = { version = "1", features = ["derive"] }

子 crate 继承:

1
2
3
4
5
6
7
[package]
name = "crate-a"
version.workspace = true
edition.workspace = true

[dependencies]
serde.workspace = true

[patch] 覆盖依赖

1
2
3
4
5
# 用 fork/本地路径临时替换 crates.io 上的 crate
[patch.crates-io]
serde = { git = "https://github.com/user/serde", branch = "fix" }
# 或
serde = { path = "../serde-fork" }

发布到 crates.io[patch] 会被忽略,仅本地/workspace 生效。

[lints] lint 配置

1
2
3
4
5
6
[lints.rust]
unsafe_code = "deny"

[lints.clippy]
all = "warn"
pedantic = "warn"

级别:forbid > deny > warn > allow。workspace 中可用 [workspace.lints],子 crate 用 [lints] workspace = true 继承。

速查要点

  • 二进制项目提交 Cargo.lock,库项目不提交
  • cargo tree -d 查看重复版本依赖
  • cargo package --list 检查发布包内容
  • 发布到 crates.io 不能有 git/path 依赖
  • 0.x 依赖不会自动升 minor,需手动升
  • feature 会在依赖图中合并(unification),取并集

完整字段参考:https://doc.rust-lang.org/cargo/reference/manifest.html