cargo.toml
Cargo.toml格式
1.package字段
设置包信息,
cargo new <package-name>会自动生成Cargo.toml文件
[package]
name = "testA" # 包裹的名称
description = "this is a test package" # 包裹的描述
version = "0.0.1" # 软件包的版本
authors = ["Graydon Hoare", "Fnu Lnu <no-reply@rust-lang.org>"] # 该软件包的作者(此字段已弃用)
edition = '2024' # Rust版本
rust-version = "1.70" # 支持的最低Rust版本(至少需要 Rust 1.70 或更高版本)
documentation = "https://docs.rs/bitflags" # 软件包文档的 URL
readme = "README.md" # 软件包的README文件路径(相对Cargo.toml文件)
homepage = "https://serde.rs" # 软件包主页的 URL
repository = "https://github.com/rust-lang/cargo" # 软件包源代码仓库的URL
keywords = ["gamedev", "graphics"] # 包裹的关键词,最多设置5个关键字
categories = ["command-line-utilities", "development-tools::cargo-plugins"] # 包裹的类别,https://crates.io/category_slugs查询分类信息
build = "build.rs" # 构建脚本路径(相对于 Cargo.toml)
links = "my_native_lib" # 链接的本地 C 库名称(用于与系统库交互)
## 发布操作
exclude = ["ci/", ".*", "*.md"] # 发布时排除的文件(支持 glob 模式)
include = ["src/**/*", "Cargo.toml", "LICENSE"] # 发布时显式指定只包含哪些文件(优先级高于 exclude),如果指定,默认的include规则将被忽略。
publish = false # 控制是否可发布到crates.io
publish = ["crates-io"] # 可发布到 crates.io
# 许可证设置(推荐使用第一中)
license = "MIT OR Apache-2.0" # 软件包许可证(# 使用 SPDX 标识符)
license-file = "LICENSE.txt" # 许可证文本的路径(相对Cargo.toml文件)
resolver说明
默认值1
resolver = "1"
包 A 依赖 serde = { version = "1.0", features = ["derive"] }
包 B 依赖 serde = { version = "1.0", features = ["std"] }
serde 会被同时启用 derive 和 std 特性
resolver = "2"
包 A 只在使用 serde 时启用 derive 特性
包 B 只在使用 serde 时启用 std 特性
更精确的特性控制
resolver = "3" # 需要Rust 1.84以上版本(Edition2024默认值3)
# 需要设置incompatible-rust-versions
当遇到不兼容的 Rust 版本要求时,会尝试回退到兼容的版本
[package.metadata]
resolver = { incompatible-rust-versions = "allow" }
2.workspace字段
统一管理多个相互关联的 Rust 包(crates)。这是 Cargo 提供的一种组织大型项目的机制
2.1基础用法
[workspace]
members = ["crates/a", "crates/b"] # 必需字段,定义哪些目录下的包属于这个工作区
exclude = ["crates/deprecated"] # 排除某些路径(不常用)
resolver = "2" # 控制依赖解析行为(1,2,3),和 package.resolver一样
default-members = ["crates/core"] # 默认构建的目标(当在工作区根执行 cargo build 时不指定 --all 时,默认构建的包列表)
2.2 workspace.package
所有成员包提供共享的元数据模板,成员包可以通过 workspace = true 继承
[workspace.package]
version = "0.1.0"
edition = "2021"
authors = ["author@example.com"]
crates/xxx/Cargo.toml继承
继承workspace.package
[package]
name = "my-package"
version.workspace = true # 继承 workspace.package.version
edition.workspace = true # 继承 workspace.package.edition
2.3 workspace.dependencies
定义全局依赖,成员包可通过
{ workspace = true }引用,确保版本统一
[workspace.dependencies]
tokio = "1.0"
serde = { version = "1.0", features = ["derive"] }
my-local-crate = { path = "crates/local" }
crates/xxx/Cargo.toml继承
[dependencies]
tokio = { workspace = true } # 使用 workspace.dependencies.tokio
my-local-crate = { workspace = true } # 使用 workspace.dependencies.my-local-crate
2.4 workspace.lints
定义全局 lint 规则,成员包可通过 [lints] workspace = true 继承
[workspace.lints.rust]
unexpected_cfgs = "warn"
[workspace.lints.clippy]
pedantic = "warn"
crates/xxx/Cargo.toml继承
[lints]
workspace = true # 继承 workspace.lints 中的所有规则
3.dependencies
指定项目依赖关系
3.1 基本用法
[dependencies]
serde = "1.0"
tokio = { version = "1.0", features = ["full"] }
3.2 版本控制
[dependencies]
# 精确版本
serde = "1.0.197"
# 版本范围
serde = ">=1.0, <2.0"
serde = "1.0.*" # 等同于 1.0.x
# 比较操作符
serde = "=1.0.197" # 精确匹配
serde = ">1.0" # 大于 1.0
serde = ">=1.0" # 大于等于 1.0
serde = "<1.0" # 小于 1.0
serde = "<=1.0" # 小于等于 1.0
3.3 registry
要指定来自crates.io以外的注册表的依赖项,请将registry键设置为要使用的注册表的名称
在registry在.cargo/config.toml的配置中
[dependencies]
private-crate = { version = "1.0", registry = "my-registry" }
3.4 git仓库依赖
[dependencies]
serde = { git = "https://github.com/serde-rs/serde" }
serde = { git = "https://github.com/serde-rs/serde", rev = "abc123" }
serde = { git = "https://github.com/serde-rs/serde", tag = "v1.0.197" }
serde = { git = "https://github.com/serde-rs/serde", branch = "main" }
3.5 本地路径依赖
[dependencies]
my-local-crate = { path = "../my-local-crate" }
utils = { path = "./utils" }
3.6 功能特性(Features)
[dependencies]
tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] }
serde = { version = "1.0", features = ["derive"], default-features = false }
3.7 指定平台的依赖
[target.'cfg(windows)'.dependencies]
winhttp = "0.4.0"
[target.'cfg(unix)'.dependencies]
openssl = "1.0.1"
[target.'cfg(target_arch = "x86")'.dependencies]
native-i686 = { path = "native/i686" }
[target.'cfg(target_arch = "x86_64")'.dependencies]
native-x86_64 = { path = "native/x86_64" }
3.8 package重命名
[dependencies]
foo = "0.1"
bar = { git = "https://github.com/example/project.git", package = "foo" }
baz = { version = "0.1", registry = "custom", package = "foo" }
3.9optional可选依赖
需要配合features使用
[dependencies]
# serde 不会自动被引入,除非用户明确启用相关的 feature
serde = { version = "1.0", optional = true }
[dependencies]
serde = { version = "1.0", optional = true }
serde_json = { version = "1.0", optional = true }
tokio = { version = "1.0", optional = true }
[features]
default = ["json"] # 默认启用 json 功能
json = ["dep:serde", "dep:serde_json"] # json 功能需要这两个库
async = ["dep:tokio"]
full = ["json", "async"] # full 包含所有功能
3.10 build-dependencies
构建时依赖 - 仅在build.rs中使用
[build-dependencies]
cc = "1.0" # C 编译器包装器
bindgen = "0.60" # C/C++ 绑定生成器
3.11 dev-dependencies
只在运行测试、基准测试或文档测试时使用
cargo test、cargo bench、cargo doc、cargo check --test时测试、基准测试和文档测试的依赖
[dev-dependencies]
# 仅开发时使用的依赖
tokio-test = "0.4" # 异步测试工具
serial_test = "2.0" # 串行测试执行
pretty_assertions = "1.0" # 更好的断言输出
mockito = "0.31" # HTTP mocking
criterion = "0.5" # 基准测试
4.patch替换
patch作用是把原本dependencies从create.io的查找的,去git、本地、私有仓库查找
4.1 替换来自crates.io的包
[patch.crates-io]
4.1.1 git替换
[dependencies]
my-package = "0.1.0"
[patch.crates-io]
# 基本 Git 仓库
my-package = { git = "https://github.com/user/repo" }
# 指定分支
my-package = { git = "https://github.com/user/repo", branch = "develop" }
# 指定标签
my-package = { git = "https://github.com/user/repo", tag = "v2.1.0" }
# 指定提交
my-package = { git = "https://github.com/user/repo", rev = "a1b2c3d4" }
# 带有子模块
my-package = { git = "https://github.com/user/repo", submodule = true }
4.1.2 本地路径替换
[dependencies]
serde = "0.1.0"
tokio = "0.1.0"
[patch.crates-io]
serde = { path = "../forks/serde" }
tokio = { path = "/home/user/local-tokio" }
4.2 替换指定git源的包
[patch.<URL>]
[dependencies]
# 来自 Git 仓库的依赖
lib-from-git = { git = "https://github.com/example/repo", rev = "original" }
# 想要替换来自 https://github.com/example/repo 的包
[patch."https://github.com/example/repo"]
lib-from-git = { git = "https://github.com/user/repo", rev = "improved" }
4.3 替换来自特定注册表的包
# ~/.cargo/config.toml
[registries]
internal = { index = "https://cargo.internal.company.com/index" }
# Cargo.toml
[dependencies]
internal-lib = { version = "2.0", registry = "internal" }
# patch
[patch."https://cargo.internal.company.com/index"]
internal-lib = { path = "../local-fixes/internal-lib" }
5.features
项目提供给他人使用的特性
一般填写别人的特性,如:feature1、feature2
5.1 核心命名惯例
5.1.1 default - 默认启用的特性
[features]
default = ["feature1", "feature2"]
5.1.2 std - 标准库支持
[features]
std = [] # 启用依赖标准库的功能
no_std = [] # 启用无标准库支持
5.1.3 full - 完整功能
[features]
default = ["std"]
full = ["std", "async", "serialize", "crypto"] # 启用所有功能
5.1.4 组合功能
可以复用features中的
key
⚠️dep:前缀的作用是明确告诉Cargo这里要启用的是依赖本身,而不是依赖内部的某个特性,能有效避免命名冲突的问题
[dependencies]
serde = { version = "1.0", optional = true }
serde_json = { version = "1.0", optional = true }
serde_yaml = { version = "0.9", optional = true }
tokio = { version = "1.0", optional = true }
[features]
# 基础功能
serialize = ["dep:serde"]
# 基于基础功能扩展
json = ["serialize", "dep:serde_json"]
yaml = ["serialize", "dep:serde_yaml"]
# 组合使用
all_formats = ["json", "yaml"]
5.1.5 自定义命名
[features]
aa_bb = ["feature1", "feature2"]
test_aa = ["feature1-test", "feature2-test"]
5.1.6 案例说明
.
├── aaa
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── bbb
├── Cargo.lock
├── Cargo.toml
└── src
└── main.rs
aaa/Cargo.toml
[package]
name = "aaa"
version = "0.1.0"
edition = "2024"
publish = ["aliyun"]
[features]
mytest = []
aaa/src/lib.rs
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#[cfg(feature = "mytest")]
pub fn add_test(left: u64, right: u64) -> u64 {
left + right
}
bbb/Cargo.toml
[package]
name = "bbb"
version = "0.1.0"
edition = "2024"
publish = ["aliyun"]
[dependencies]
aaa = {path = "../aaa"}
bbb/src/main.rs
use aaa;
fn main() {
// 报错,未开启mytest特性
println!("{}", aaa::add_test(1, 2));
}
5.1.7 #[cfg(feature = "xxx")]说明
xxx填的就是[features]段里的键名(key值)
[features]
serialize = ["dep:serde"]
my_json = ["serialize", "dep:serde_json"]
my_yaml = ["serialize", "dep:serde_yaml"]
all_formats = ["my_json", "my_yaml"]
#[cfg(feature = "serialize")]
#[cfg(feature = "my_json")]
#[cfg(feature = "my_yaml")]
#[cfg(feature = "all_formats")] // 组合 feature 一样能判断
5.1.7.1 其他判断写法
#[cfg(feature = "my_json")] // 开my_json
#[cfg(not(feature = "my_json"))] // 没开my_json
#[cfg(all(feature = "my_json", feature = "my_yaml"))] // 都开
#[cfg(any(feature = "my_json", feature = "my_yaml"))] // 任一开
#[cfg_attr(feature = "serialize", derive(serde::Serialize))] // 条件加属性
#[cfg_attr(docsrs, doc(cfg(feature = "my_json")))] // doc文档标注
// 两个分支都会被编译`cfg!(feature = "my_json")`只返回true / false
fn f() {
if cfg!(feature = "my_json") { /* xxx1 */ } else { /* xxx2 */}
}
5.1.7.2 条件加属性说明
| 情况 | 展开结果 |
|---|---|
启用了 serialize |
#[derive(serde::Serialize)] pub struct Config { … } → 有 Serialize 实现 |
| 没启用 | pub struct Config { … } → 就是普通结构体,没有 Serialize |
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
pub struct Config { pub name: String }
// 这样的写发错误
// 没开 feature 时 Config 整个不存在!
// #[cfg(feature = "serialize")]
// #[derive(serde::Serialize)]
// pub struct Config { … }
// 可以一次性附加多个属性
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(rename_all = "camelCase"))]
5.1.7.3 doc文档标注说明
doc(cfg(feature = "my_json")):rustdoc 的标注属性,效果是在文档页上给这个 API 打一个标签
Available on crate feature my_json only.
①②是「一次性配置」,③是「按需重复」
| 步骤 | 粒度 | 作用 | 能省吗 |
| --- | --- | --- | --- |
| ① Cargo.toml 的[package.metadata.docs.rs]| 每个要发布的 crate 一份 | 让 docs.rs 开全 feature + 传--cfg docsrs| 不能(docsrs要由它来定义) |
| ②#![cfg_attr(docsrs, feature(doc_cfg))]| 每个 crate 的 lib.rs 顶部一次 | 打开 rustdoc 的doc_cfg能力(否则doc(cfg(...))在 stable 上编不过) | 不能 |
| ③ 每个 API 上的#[cfg(feature=…)]+#[cfg_attr(docsrs, doc(cfg(…)))]| 每个需要标注的 API 各一次 | 决定「这个 API 存不存在」+「文档里打什么标签」 | 按需 |
- Cargo.toml定义
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
targets = [ # 平台类(可选)
"x86_64-unknown-linux-gnu",
"x86_64-pc-windows-msvc",
"aarch64-apple-darwin",
]
- lib.rs
// 必须在顶部
#![cfg_attr(docsrs, feature(doc_cfg))]
mod xxx1;
mod xxx2;
- xxx.rs
#[cfg(feature = "my_json")] // 这个 API 只在开了 my_json 时存在
#[cfg_attr(docsrs, doc(cfg(feature = "my_json")))] // 在 docs.rs 上标注「需要 my_json」
impl Config {
pub fn to_json(&self) -> String { /* ... */ }
}
- 命令说明
[package.metadata.docs.rs] 里的配置 |
等价于 docs.rs 执行的命令 | 文档里出现的 API |
|---|---|---|
| 什么都不写 | cargo doc(用 default features) |
只有 default 打开的 |
all-features = true |
cargo doc --all-features |
全部 |
features = ["my_json"] |
cargo doc --features my_json |
default + my_json |
features = [...] + no-default-features = true |
cargo doc --no-default-features --features ... |
只有列出的 |
6.profile
主要用来调整编译优化级别、调试信息、代码生成等参数
Cargo 提供几个预定义的 profile:
- dev: 开发模式,默认 cargo build
- release: 发布模式,默认 cargo check 和 cargo test
- test: 测试专用
- bench: 基准测试专用
- doc: 文档生成专用
6.1 opt-level优化级别
- 0: 无优化,编译快
- 1: 基本优化
- 2: 常规优化
- 3: 最大优化(默认发布模式)
- s: 优化代码大小
- z: 更积极地优化代码大小
[profile.dev]
opt-level = 0 # 开发模式通常为 0,无优化
# opt-level = 3 # 发布模式默认为 3,最大优化
[profile.release]
opt-level = 3 # 0-3, s, z
6.2 debug调试信息
[profile.dev]
debug = true # 包含完整调试信息
[profile.release]
debug = false # 不包含调试信息
# debug = true # 可选,保留调试信息但优化代码
6.3 debug-assertions调试断言
[profile.dev]
debug-assertions = true
[profile.release]
debug-assertions = false
6.4 overflow-checks溢出检查
[profile.dev]
overflow-checks = true # 开启整数溢出检查
[profile.release]
overflow-checks = false # 关闭以提升性能
6.5 lto链接时优化
[profile.release]
lto = false # 关闭 LTO
# lto = true # 开启 LTO
# lto = "fat" # 全面 LTO
# lto = "thin" # 薄 LTO
6.6 codegen-units代码生成单元
[profile.release]
codegen-units = 16 # 默认值
# codegen-units = 1 # 单元,更优优化但编译慢
6.6 panic恐慌处理策略
[profile.release]
panic = "unwind" # 展开栈(默认)
# panic = "abort" # 直接终止
6.7 incremental增量编译
[profile.dev]
incremental = true # 开启增量编译(开发模式默认)
[profile.release]
incremental = false # 关闭(发布模式默认)
6.8 默认配置
6.8.1 dev默认配置
[profile.dev]
opt-level = 0
debug = true
split-debuginfo = '...' # Platform-specific.
strip = "none"
debug-assertions = true
overflow-checks = true
lto = false
panic = 'unwind'
incremental = true
codegen-units = 256
rpath = false
6.8.2 release默认配置
[profile.release]
opt-level = 3
debug = false
split-debuginfo = '...' # Platform-specific.
strip = "none"
debug-assertions = false
overflow-checks = false
lto = false
panic = 'unwind'
incremental = false
codegen-units = 16
rpath = false
6.8.4 其他默认配置
- test默认配置继承dev
- bench默认配置继承release
6.9 构建依赖
build-override影响[build-dependencies], 也就是build.rs
[profile.dev.build-override]
opt-level = 0
codegen-units = 256
debug = false # when possible
[profile.release.build-override]
opt-level = 0
codegen-units = 256

浙公网安备 33010602011771号