强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Rust 系统编程语言完全教程 / 第20章:Cargo 深入

第20章:Cargo 深入

20.1 Features 系统

定义 Features

# Cargo.toml
[features]
default = ["json"]              # 默认启用的 features
json = ["dep:serde", "dep:serde_json"]
xml = ["dep:quick-xml"]
full = ["json", "xml", "logging"]
logging = []

[dependencies]
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
quick-xml = { version = "0.31", optional = true }

条件编译

#[cfg(feature = "json")]
pub mod json_support {
    pub fn parse(s: &str) -> serde_json::Value {
        serde_json::from_str(s).unwrap()
    }
}

#[cfg(feature = "xml")]
pub mod xml_support {
    pub fn parse(s: &str) -> String {
        format!("XML: {}", s)
    }
}

pub fn auto_parse(s: &str) -> String {
    #[cfg(feature = "json")]
    { return format!("JSON: {:?}", json_support::parse(s)); }

    #[cfg(not(feature = "json"))]
    { return format!("原始: {}", s); }
}

使用 Features

# 使用默认 features
cargo build

# 启用特定 features
cargo build --features "json,xml"

# 禁用默认 features
cargo build --no-default-features

# 禁用默认 + 启用特定
cargo build --no-default-features --features "xml"

20.2 依赖管理

版本指定

[dependencies]
# 精确版本
serde = "1.0.200"

# 语义化版本范围
tokio = "1"               # ^1.0.0 (>=1.0.0, <2.0.0)
axum = "0.7"              # ^0.7.0 (>=0.7.0, <0.8.0)

# 更多版本格式
foo = ">=1.0, <2.0"       # 范围
bar = "=1.0.5"            # 精确匹配
baz = "~1.2.3"            # >=1.2.3, <1.3.0
qux = "*"                 # 任意版本(不推荐)

# Git 依赖
mylib = { git = "https://github.com/user/mylib.git", branch = "main" }
mylib2 = { git = "https://github.com/user/mylib.git", tag = "v1.0" }
mylib3 = { git = "https://github.com/user/mylib.git", rev = "abc123" }

# 本地路径
utils = { path = "../utils" }

依赖重命名

[dependencies]
# 重命名以避免冲突
my_serde = { package = "serde", version = "1.0" }

平台特定依赖

# 只在特定平台编译
[target.'cfg(windows)'.dependencies]
winapi = "0.3"

[target.'cfg(target_os = "linux")'.dependencies]
nix = "0.29"

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2"

查看依赖树

cargo tree
cargo tree -d            # 只显示重复的依赖
cargo tree --depth 1     # 限制深度
cargo tree -i serde      # 反向查找谁依赖 serde

20.3 Profile 配置

# Cargo.toml

# 开发配置(cargo build)
[profile.dev]
opt-level = 0            # 0-3, s, z
debug = true
debug-assertions = true
overflow-checks = true
lto = false
incremental = true
codegen-units = 256

# 发布配置(cargo build --release)
[profile.release]
opt-level = 3
debug = false
debug-assertions = false
overflow-checks = false
lto = true               # 链接时优化
codegen-units = 1        # 更好优化,更慢编译
strip = true             # 去除调试信息
panic = "abort"          # panic 时直接终止

# 测试配置
[profile.test]
opt-level = 1

# 基准测试配置
[profile.bench]
opt-level = 3
lto = true

优化级别说明

级别说明
0无优化(默认开发模式)
1基本优化
2更多优化
3最高优化(默认发布模式)
s优化大小
z最小大小

20.4 构建脚本(build.rs)

基本用法

// build.rs
fn main() {
    // 设置环境变量
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-env-changed=MY_VAR");

    // 条件编译
    if cfg!(target_os = "linux") {
        println!("cargo:rustc-cfg=linux");
    }

    // 链接原生库
    // println!("cargo:rustc-link-lib=static=mylib");
    // println!("cargo:rustc-link-search=native=/usr/local/lib");
}

使用 cc crate 编译 C 代码

# Cargo.toml
[build-dependencies]
cc = "1.0"
// build.rs
fn main() {
    cc::Build::new()
        .file("src/helper.c")
        .compile("helper");
}

20.5 Cargo 子命令

常用子命令安装

cargo install cargo-watch     # 文件变化自动重新编译
cargo install cargo-edit      # cargo add/rm/upgrade
cargo install cargo-expand    # 展开宏
cargo install cargo-audit     # 安全审计
cargo install cargo-outdated  # 检查过期依赖
cargo install cargo-deny      # 依赖策略检查
cargo install cargo-bloat     # 分析二进制大小
cargo install cargo-flamegraph # 性能火焰图

常用子命令

# 文件变化自动编译运行
cargo watch -x run
cargo watch -x test
cargo watch -x 'test -- --show-output'

# 安全审计
cargo audit

# 检查过期依赖
cargo outdated

# 展开宏
cargo expand

# 分析二进制大小
cargo bloat --release

# 性能分析
cargo flamegraph

20.6 发布到 crates.io

准备工作

# Cargo.toml
[package]
name = "my-awesome-crate"
version = "0.1.0"
edition = "2024"
authors = ["Your Name <email@example.com>"]
description = "A short description of what this crate does"
license = "MIT OR Apache-2.0"
repository = "https://github.com/user/my-awesome-crate"
homepage = "https://my-crate.com"
documentation = "https://docs.rs/my-awesome-crate"
readme = "README.md"
keywords = ["tool", "utility"]
categories = ["command-line-utilities"]
rust-version = "1.70"

发布流程

# 1. 登录
cargo login <your-api-token>

# 2. 检查包内容
cargo package --list

# 3. 试运行发布(不实际发布)
cargo publish --dry-run

# 4. 正式发布
cargo publish

# 5. 发布新版本
# 修改 Cargo.toml 中的 version
cargo publish

版本管理

# 使用 cargo-release 自动化
cargo install cargo-release

# 补丁版本 (0.1.0 → 0.1.1)
cargo release patch

# 次版本 (0.1.0 → 0.2.0)
cargo release minor

# 主版本 (0.1.0 → 1.0.0)
cargo release major

20.7 业务场景示例

生产级 Cargo.toml

[package]
name = "my-service"
version = "0.3.1"
edition = "2024"
rust-version = "1.70"

[dependencies]
tokio = { version = "1", features = ["full"] }
axum = "0.7"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
anyhow = "1"

[dev-dependencies]
tokio-test = "0.4"
reqwest = { version = "0.12", features = ["json"] }

[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true
panic = "abort"

[profile.dev]
opt-level = 1

20.8 本章小结

要点说明
Features条件编译功能模块
版本管理语义化版本,^ 为默认前缀
Profiledev/release/test/bench 配置
build.rs构建脚本,编译原生代码
发布cargo publish 发布到 crates.io

扩展阅读

  1. Cargo 手册 — 官方文档
  2. Cargo.toml 参考 — 完整配置参考