rust中的Cargo.toml文件
Cargo.toml又称清单( manifest ),是 Rust项目的核心配置文件,采用TOML格式(Tom’s Obvious Minimal Language);定义了一个包(crate)的:
- 名称、版本、作者、许可证;
- 依赖项;
- 编译特性;
- 目标配置;
- 构建脚本;
- 工作区设置等
Cargo.toml vs Cargo.lock
- Cargo.toml:描述依赖的广义信息,由开发者编写
- Cargo.lock:包含依赖的确切信息,由Cargo自动生成,不应手动编辑
| 特性 | Cargo.toml | Cargo.lock |
|---|---|---|
| 作用 | 源配置(声明意图) | 锁定文件(记录实际依赖版本) |
| 手动编辑 | 是(开发者编写 / 修改) | 否(Cargo 自动生成 / 更新) |
| 提交 Git | 需提交 | 库的不需提交;二进制的需提交 |
| 核心内容 | 项目元信息、依赖、构建规则 | 精确的依赖版本树、校验和 |
基础结构
Cargo.toml 按「区段(Section)」组织,每个区段用 [区段名] 标识,核心区段包括:
[package]:定义项目元信息(必选)[dependencies]:生产依赖(必选 / 可选,视项目类型)[dev-dependencies]:开发依赖(测试、文档测试用)[build-dependencies]:构建脚本依赖[lib]:库目标配置[[bin]]:二进制目标配置(支持多个)[profile.*]:构建配置文件(编译优化、调试信息等)[features]:特性开关(条件编译、可选依赖)[workspace]:工作空间配置(多包项目)
示例
[package]
name = "my-rust-app"
version = "0.1.0"
edition = "2024"
description = "A full-featured Rust application"
license = "MIT"
repository = "https://github.com/foo/my-rust-app"
readme = "README.md"
keywords = ["rust", "app", "cli"]
categories = ["command-line-utilities"]
rust-version = "1.75.0"[workspace]
members = ["crates/*", "cli"]
default-members = ["cli"][workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
rand = "0.8"
anyhow = "1.0"[dependencies]
# 工作空间共享依赖
serde = { workspace = true }
rand = { workspace = true }
anyhow = { workspace = true }# 可选依赖(关联特性)
tokio = { version = "1.0", features = ["full"], optional = true }
local-crate = { path = "../local-crate", version = "0.1.0" }
git-crate = { git = "https://github.com/foo/git-crate", tag = "v0.2.0" }# 目标依赖(仅 Windows 平台启用)
[target.'cfg(target_os = "windows")'.dependencies]
winapi = "0.3"# 开发依赖
[dev-dependencies]
rstest = "0.18"
assert-json-diff = "2.0"# 构建脚本依赖(项目根目录有 build.rs)
[build-dependencies]
cc = "1.0"
bindgen = "0.66"# 特性配置
[features]
default = ["tokio", "cli"]
cli = []
advanced = ["cli", "rand/small_rng"]# 二进制目标配置
[[bin]]
name = "my-app"
path = "src/bin/main.rs"
required-features = ["cli"]# 库目标配置
[lib]
name = "my-app-core"
path = "src/lib.rs"
crate_type = ["rlib", "cdylib"]# 构建配置文件
[profile.release]
opt-level = 3
lto = "thin"
strip = "debuginfo"
panic = "abort"
codegen-units = 1[profile.dev]
opt-level = 1
debug = true
incremental = true
package元信息
定义项目的基本信息
| 字段名 | 作用 | 格式 / 要求 | 示例 |
|---|---|---|---|
name | 项目名称(crates.io 唯一) | 字符串:小写字母 + 连字符 | name = "my-rust-project" |
version | 版本号(语义化版本) | 遵循 MAJOR.MINOR.PATCH | version = "0.1.0" |
edition | Rust 版本 edition | 支持 2018/2021/2024 | edition = "2024" |
maintainers | 维护者信息(替代 authors,推荐) | 数组,格式 ["姓名 <邮箱>"] | maintainers = ["Bob <bob@example.com>"] |
description | 项目描述(crates.io 展示) | 字符串,简洁明了(≤100 字符) | description = "A simple Rust utility" |
license | 开源许可证(SPDX 标识符) | 字符串,如 MIT、Apache-2.0、GPL-3.0 | license = "MIT" |
license-file | 自定义许可证文件路径 | 字符串,当 license 无法用 SPDX 标识时使用 | license-file = "LICENSE.txt" |
repository | 代码仓库地址 | 字符串(Git 地址或网页链接) | repository = "https://github.com/foo/bar" |
homepage | 项目主页 | 字符串(HTTP/HTTPS 链接) | homepage = "https://foo.example.com" |
readme | README 文件路径 | 字符串,默认 README.md/README.rst,可省略路径 | readme = "README.md" |
keywords | 搜索关键词(crates.io 用) | 字符串数组,最多 5 个 | keywords = ["rust", "utility", "cli"] |
categories | 分类(crates.io 用) | 字符串数组,需从 官方分类 选择 | categories = ["command-line-utilities"] |
exclude | 构建 / 发布时排除的文件 | 字符串数组(支持 glob 模式) | exclude = ["docs/*", "tests/*.txt"] |
include | 构建 / 发布时强制包含的文件 | 字符串数组(优先级高于 exclude) | include = ["src/**/*", "Cargo.toml"] |
publish | 是否允许发布到 crates.io | 布尔值(true/false) | publish = false(私有项目) |
rust-version | 最低支持的 Rust 版本 | 字符串(如 1.70.0),确保项目在低版本 Rust 上可编译 | rust-version = "1.70.0" |
dependencies普通依赖
定义项目的运行时依赖,支持多种版本约束语法:
| 版本符号 | 含义 | 示例 | 允许的版本范围 |
|---|---|---|---|
^x.y.z | 兼容更新(默认,推荐) | serde = "^1.0.188" | 1.0.188 ≤ 版本 < 2.0.0 |
~x.y.z | 补丁更新(仅允许 PATCH 版本升级) | rand = "~0.8.5" | 0.8.5 ≤ 版本 < 0.9.0 |
>=x.y.z | 最低版本(允许所有更高版本) | tokio = ">=1.20.0" | 1.20.0 及以上 |
=x.y.z | 精确版本(禁止任何升级) | log = "=0.4.20" | 仅 0.4.20 |
* | 任意版本(不推荐,风险高) | foo = "*" | 所有版本 |
依赖支持多种声明方式:
- crates.io:默认,直接指定crate 名称和版本
- git:依赖 Git 仓库中的 crate,支持指定分支、标签、提交哈希
- path:依赖本地 crate,指定本地库的路径
[dependencies]
# 简洁版本约束(等价于 ^1.0)
serde = "1.0"# 明确指定版本约束
rand = "=0.8.5" # 精确版本
tokio = "~1.0" # 允许patch版本更新(1.0 <= version < 1.1)# 使用特性(features)
serde = { version = "1.0", features = ["derive"] }# 依赖来自Git仓库
custom-fork = { git = "https://github.com/user/repo", branch = "fix" }# 本地路径依赖
my-lib = { path = "../my-lib" }
注,其他依赖:
[dev-dependencies]: 仅在cargo test/cargo bench等开发模式下使用[build-dependencies]: 在build.rs文件中使用的依赖[target.'cfg(windows)'.dependencies]/[target.'cfg(unix)'.dependencies]:指定特定平台依赖
Features特性
Features是 Cargo 提供的一种条件编译机制:
- 启用 / 禁用可选依赖
- 控制代码中的条件编译(
cfg(feature = "xxx")) - 组合多个特性(特性继承)
[features]
default = ["tls-rustls"] # 默认启用的特性
tls-rustls = ["rustls", "reqwest-rustls"] # 启用Rustls TLS实现
tls-native = ["native-tls", "reqwest-native"] # 启用系统TLS实现
compression = ["dep:flate2"] # 依赖其他包的特性# 空特性(仅用于条件编译,不关联依赖)
feat1 = []# 特性继承(feat2 启用时,自动启用 feat1 和 "advanced-dep" 依赖)
feat2 = ["feat1", "advanced-dep"]# 关联可选依赖(需先在 [dependencies] 中声明 optional = true)
optional-dep = [] # 与 [dependencies] 中 optional-dep 的 optional = true 对应
advanced-dep = ["dep3"] # 关联 dep3 依赖
说明:
default:默认启用的特性。- 启用时:
cargo build --features "async,json" - 关闭默认特性:
cargo build --no-default-features
在代码中使用特性:
// 仅当 "feat1" 特性启用时编译此模块
#[cfg(feature = "feat1")]
mod feat1_module {// ...
}// 特性启用时执行不同逻辑
fn do_something() {#[cfg(feature = "feat2")]println!("Feat2 is enabled!");#[cfg(not(feature = "feat2"))]println!("Feat2 is disabled!");
}
目标配置
Rust 项目支持两种目标类型:库(lib) 和 二进制可执行文件(bin)
lib库配置
仅当项目是库(或同时是库 + 二进制)时需要,定义库的构建规则
| 字段名 | 作用 | 示例 |
|---|---|---|
name | 库名称(默认与 package.name 一致) | name = "my-lib" |
path | 库源文件路径(默认 src/lib.rs) | path = "src/my_lib.rs" |
crate_type | 生成的库类型(支持多个) | crate_type = ["rlib", "cdylib"] |
crate_name | 编译后的 crate 名称(链接时使用) | crate_name = "my_custom_lib" |
库类型说明:
rlib:Rust 静态库(默认,供 Rust 项目依赖)dylib:Rust 动态库(供 Rust 项目动态链接)cdylib:C 兼容动态库(供 C/C++ 等其他语言调用)staticlib:C 兼容静态库(供其他语言静态链接)proc-macro:过程宏库(仅当项目是过程宏时使用)
bin二进制配置
定义可执行文件的构建规则,[[bin]] 是数组语法([[ ]]),支持多个二进制目标(一个项目可生成多个可执行文件)
| 字段名 | 作用 | 示例 |
|---|---|---|
name | 可执行文件名称(默认与源文件名称一致) | name = "my-cli" |
path | 源文件路径(默认 src/bin/*.rs) | path = "src/cli/main.rs" |
required-features | 启用该二进制目标所需的特性 | required-features = ["cli"] |
默认约定:
- 单个二进制目标:源文件放在
src/main.rs,无需配置[[bin]] - 多个二进制目标:源文件放在
src/bin/目录下(如src/bin/cli.rs、src/bin/utils.rs),Cargo 自动识别,无需配置[[bin]](除非需要自定义名称 / 路径)
# 自定义单个二进制目标(源文件不是 src/main.rs)
[[bin]]
name = "my-cli"
path = "src/custom_main.rs"# 多个二进制目标(自定义名称和路径)
[[bin]]
name = "cli"
path = "src/cli.rs"[[bin]]
name = "daemon"
path = "src/daemon.rs"
required-features = ["daemon"] # 仅当启用 "daemon" 特性时才构建
profile.*构建配置
控制编译优化、调试信息、代码生成等规则,Cargo 提供 5 个默认配置文件;
| 配置文件 | 用途 | 默认优化级别 | 适用场景 |
|---|---|---|---|
dev | 开发模式(cargo build 默认) | opt-level = 0(无优化) | 本地开发、调试(编译快) |
release | 发布模式(cargo build --release) | opt-level = 3(全优化) | 生产环境(运行快,编译慢) |
test | 测试模式(cargo test 默认) | opt-level = 0 | 运行测试(兼顾编译速度) |
bench | 基准测试模式(cargo bench) | opt-level = 3 | 性能测试(需要最优性能) |
doc | 文档模式(cargo doc) | opt-level = 0 | 生成文档(编译依赖快) |
可配置字段(常用),参数细节参见《Rust编译参数与优化控制》Profile部分。
| 字段名 | 作用 | 取值范围 / 说明 |
|---|---|---|
opt-level | 优化级别 | 0(无优化)、1(基础优化)、2(中等优化)、3(全优化)、s(代码体积优化)、z(极致体积优化) |
debug | 是否生成调试信息 | true/false(dev 默认为 true,release 默认为 false) |
debug-assertions | 是否启用调试断言(如 debug_assert!) | true/false(dev 默认为 true,release 默认为 false) |
strip | 是否剥离符号信息(减小二进制体积) | “none”(不剥离)、“debuginfo”(仅剥离调试信息)、“all”(剥离所有符号) |
lto | 链接时优化(LTO,提升性能 / 减小体积) | false(禁用)、true(全 LTO)、“thin”(增量 LTO,编译更快) |
codegen-units | 代码生成单元数量(影响编译速度 / 优化) | 整数(默认 dev=256,release=16;值越小优化越好,但编译越慢) |
panic | panic 处理方式 | “unwind”(默认,栈展开,支持 catch_unwind)、“abort”(直接终止进程,体积更小) |
incremental | 是否启用增量编译(加速二次编译) | true/false(dev 默认为 true,release 默认为 false) |
workspace工作区
当项目包含多个 crate(如核心库、CLI 工具、测试工具)时,用工作空间统一管理依赖和构建。
工作区配置
# 工作空间根目录的 Cargo.toml
[workspace]
# 包含的子包(支持 glob 模式)
members = ["crates/*", # 所有 crates 目录下的子包"cli", # 单个子包
]# 默认构建的子包(cargo build 时默认构建这些)
default-members = ["crates/core", "cli"]# 工作空间共享依赖版本(子包可直接引用,避免版本重复)
[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
rand = "0.8"
子包中引用工作区依赖
# 子包(crates/core/Cargo.toml)
[dependencies]
# 直接引用工作空间定义的依赖版本
serde = { workspace = true }
rand = { workspace = true, features = ["small_rng"] } # 追加特性
