本页目录
Workspace 与项目管理
当项目包含多个 interdependent crate(如核心库+API server+CLI)时,workspace 让它们共享同一个 Cargo.lock 和 target 目录——编译缓存复用、依赖版本统一。patch 允许在开发时临时替换某个依赖的源码,build.rs 在编译前执行代码生成。
Workspace: 多 crate 同一仓库
当项目包含多个 interdependent crate(如 core lib + API server + CLI),把它们放在一个 workspace 中有三方面的好处:
[workspace]
members = ["crates/core", "crates/api", "crates/cli"]
resolver = "2"
- 共享编译产物: 所有成员共用一个
target/目录——依赖只需要编译一次,磁盘和编译时间大幅降低 - 一致版本:
Cargo.lock在 workspace 层面共享——所有成员看到同一版本的依赖 - 内部互相引用:
api可以用path = "../../crates/core"直接引用core(不需发布到 crates.io)
[workspace.dependencies]: 共享版本声明
1.64+ 支持在根 Cargo.toml 中声明版本,成员用 key 引用:
[workspace.dependencies]
serde = "1"
tokio = { version = "1", features = ["full"] }
# 各成员: [dependencies] → serde = { workspace = true }
这解决了多 crate 项目中"依赖版本散落各处、升级时忘改某个"的经典问题。改一处版本,全部成员更新。
[patch]: 临时替换依赖
当上游 crate 有 bug、你需要用 fork 直到 upstream 修复时:
[patch.crates-io]
serde = { git = "https://github.com/myfork/serde", branch = "fix" }
注意:[patch] 中的版本必须在 workspace 全局兼容——如果两个成员一个依赖 serde 1.0 另一个依赖 serde 1.3,fork 必须同时满足两者的 API。这就是为什么 fork 最好只改内部逻辑,不改公开 API。
build.rs 进阶
// build.rs — 编译主代码之前执行
build.rs 常用于:编译 C/C++ 依赖(通过 cc crate)、检测系统库是否存在、生成代码(protobuf, OpenAPI)、设置 feature flags。
参考
- Cargo Book: workspaces, build scripts
- cc crate: docs.rs/cc
Keywords: workspace, members, patch, build.rs, shared dependencies, multi-crate, Cargo.lock