本页目录

Cargo.toml 详解

Cargo.toml 不只是"列出依赖"——features 做条件编译和可选功能,profile 控制 debug/release 的优化级别,build scripts 在编译前执行任意代码(生成 bindings、编译 C 库)。每项配置的正确写法都对应一个常见的踩坑。

[dependencies]: 版本指定

[dependencies]
serde = "1"                          # ^1.0.0: >=1.0.0, <2.0.0 (semver compatible)
tokio = { version = "1", features = ["full"] }
anyhow = "1.0"                       # ^1.0.0

[dev-dependencies]
criterion = "0.5"                    # 只在 tests/benches 可用

[build-dependencies]
cc = "1"                             # 只在 build.rs 中可用

[target.'cfg(target_os = "linux")'.dependencies]
x11 = "2"                            # linux only

版本规则:Cargo 用 semver(语义化版本)。"1.2.3" = 精确匹配,"^1.2.3" (默认) = >=1.2.3 且 <2.0.0。Cargo.lock 锁定精确版本——库 crate 不应该 commit lockfile,binary crate 应该 commit。

[features]: 条件编译

[features]
default = ["std", "tls"]
std = []
tls = ["tokio", "rustls"]            # 激活 tokio + rustls
json = ["serde", "serde_json"]
nightly = []

使用时:cargo build --no-default-features --features "json,nightly"。feature 是加法性的⁠——只能添加代码,不能删除。两个独立 feature 不能互相冲突。

[profile]: 编译优化

[profile.release]
opt-level = 3                        # 最大优化 (0-3, s=size, z=size aggressively)
lto = "fat"                          # Link-Time Optimization
codegen-units = 1                    # 单个 codegen unit → 更多内联, 更慢编译
panic = "abort"                      # 不 unwinding (小 binary, 适合嵌入式)

[profile.dev]
opt-level = 0                        # 快编译, 无优化
debug = true

release 配置的 tradeoff:opt-level=3 + lto=fat + codegen-units=1 = 最小最快的 binary,但编译时间最久(可能 10-30 分钟)。日常开发用默认(opt-level=3, thin lto, codegen-units=16),CI 中用最高。

[workspace.dependencies]: 共享版本

# root Cargo.toml:
[workspace.dependencies]
serde = "1"
tokio = "1"

[dependencies]
serde = { workspace = true }         # 引用 workspace 版本

这个特性 (1.64+) 解决了"多个 crate 中依赖版本不一致"的经典问题——升级 serde 只需改一处。

build.rs: 编译期脚本

// build.rs — Cargo 编译主代码**之前**执行:
fn main() {
    println!("cargo:rustc-link-lib=z");      // 链接 libz
    println!("cargo:rerun-if-changed=wrapper.h");  // 仅在 header 变化时重跑
    cc::Build::new().file("src/c/wrapper.c").compile("wrapper");
}

build.rs 常用于:编译 C/C++ 依赖、检测系统库、代码生成(protobuf,OpenAPI)、设置环境变量。输出在 OUT_DIR 环境变量中——由 Cargo 管理,不需要手动清理。

参考

  • Cargo Book: doc.rust-lang.org/cargo
  • The Cargo Book: profiles, features, build scripts

Keywords: Cargo.toml, features, dependencies, profile, LTO, build.rs, workspace