Rust Cargo workspace
Cargo workspace 如何组织多 crate 单仓库:共享依赖解析、成员路径与发布边界。
#concept
#growing
#dev
#rust
[!info] related notes
Rust Cargo workspace
这个概念为什么出现
中大型项目常拆:
app二进制core领域库clientSDK
workspace 让它们同仓构建、统一 lock、共享依赖版本策略。
[!abstract] 一句话理解 Workspace 是多个 package 的 Cargo 顶层组织;一次
cargo test --workspace可构建成员集合并共享Cargo.lock(对虚拟清单等规则以 Cargo 书为准)。
最小可运行示例
场景:电商 mono-repo 拆 core + api
目录示意(创建命令):
# 业务意图:一仓两 package。
# 教学点:workspace 成员;路径依赖。
mkdir -p shop && cd shop
cargo new --lib pricing-core --vcs none
cargo new --bin api --vcs none
示例使用 Rust/Cargo 1.85+ 与 edition 2024,根虚拟清单显式选择 resolver 3;旧项目可按兼容需求保留 resolver 2,不必机械迁移。
根 Cargo.toml 示例:
[workspace]
members = ["pricing-core", "api"]
resolver = "3"
api/Cargo.toml 片段:
[dependencies]
pricing-core = { path = "../pricing-core" }
依赖条目追加到 api 清单已有的 [dependencies],不要重复建同名表。将 pricing-core/src/lib.rs 替换为:
pub fn quote(net: u32) -> u64 { u64::from(net) + u64::from(net) / 10 }
将 api/src/main.rs 替换为:
fn main() { println!("quote={}", pricing_core::quote(1000)); }
然后(在 shop 根目录):
cargo test --workspace
cargo run -p api
run 应输出 quote=1100;test 是否真正执行测试要看测试数量,构建成功但 0 tests 不能当作逻辑已验证。包名 pricing-core 在 Rust 导入时写为 pricing_core,避免使用与标准库 core 相同的包名。
结合场景再看三个关注点
- 路径依赖 连接成员
-p选择包- 发布时每个 package 独立
核心概念与准确模型
- 虚拟 manifest:根只有 workspace
default-members[workspace.dependencies]只是集中声明,成员须用dependency.workspace = true显式继承,并不会自动添加依赖- 统一 lint 也需成员通过
[lints] workspace = true选择继承;依赖 feature 可能在构建图中合并,workspace 不隔离各包 feature - 成员共享根 Cargo.lock 与 target 目录;虚拟根默认选择全部成员(可设 default-members),带根 package 的 workspace 默认选择规则不同,跨成员验收用 —workspace
设计动机
- 代码复用与边界清晰
- 原子提交跨 crate 改动
- 一致工具链体验
边界与误区
- 循环路径依赖
- workspace 过大构建变慢 → 合理拆分 CI
- 把不该公开的 crate 发布到 crates.io
[!warning] 常见误区:用 workspace 代替模块 小项目单 crate 模块更简单。
工程实践
- 领域边界拆 crate
- 公共依赖 workspace 继承
- CI:fmt/clippy/test workspace
- 版本与发布流水线按 package
本节总结
- 多 crate 同仓
- 路径依赖 + 统一构建
- 边界服务架构
自测题
- 何时不该建 workspace?
cargo run -p name作用?
参考答案
- 单二进制/小库足够时。
- 指定运行 workspace 中某个 package。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Cargo Book — Workspaces | 官方 | workspace |
| Cargo Book — Specifying Dependencies | 官方 | path 依赖 |