Loading

Rust: Cargo.toml Configs

[!NOTE]

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.rssrc/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"] } # 追加特性
posted @ 2025-11-10 09:51  RioTian  阅读(20)  评论(0)    收藏  举报