43_cargo工作空间

1. 工作空间(workspaces)概述

  • cargo工作空间:帮助管理多个相互关联且需要协同开发的crate
  • cargo工作空间是一套共享同一个Cargo.lock和输出文件夹的包

类似于monorepo,但有不同的地方。

2. 创建工作空间

有多种方式创建工作空间,我们下面先创建一个二进制crate,再创建2个库crate。

rust 复制代码
- 二进制crate包含main函数,依赖于其他2个库crate,
- 其中1个库crate提供add_one函数,另一个库crate提供add_two函数。

下面是具体的步骤:

先创建一个add目录,在该目录下创建一个Cargo.toml文件,该文件用于配置整个包工作空间。

如下内容:

ini 复制代码
[workspace]

members = [
    "adder"
]

上面的代码中,包含wokspace节点,在该节点下的members字段表示工作空间的成员。现在我们使用cargo new adder在工作空间下创建出adder crate。

现在就创建出了一个工作空间,并且该空间内包含一个crate。在工作空间里使用cargo build命令将会对整个工作空间进行编译,编译后在target产生编译产物。即使我们切换到具体的crate目录执行cargo build,编译产物也依然会生成在工作空间下的target目录。通过共享一个target目录,不同的项目就可以避免不必要的重复编译过程。

3. 工作空间内的二进制crate依赖库crate

现在我们在工作空间下的Cargo.toml文件添加add_one项目,该项目是个库crate,所以使用cargo new add_one --lib创建出来。

我们修改add_one项目的src/lib.rs代码,修改为如下内容

Rust 复制代码
pub fn add_one(x: i32) -> i32 {
    x + 1
}

接下来我们让adder项目依赖add_one这个项目,在adder项目中修改Cargo.toml文件,追加以下内容即可

ini 复制代码
add_one = { path = "../add_one" }

最后修改adder项目的src/main.rs源代码,如下

Rust 复制代码
use add_one;

fn main() {
    let num = 10;
    println!(
        "Hello, world! {} plus one is {}!",
        num,
        add_one::add_one(num)
    )
}

这时候我们要运行adder这个项目,需要在工作空间内使用-p参数指定项目名即可,如下命令

bash 复制代码
cargo run -p adder

4. 在工作空间中依赖外部的crate

工作空间只有一个Cargo.lock文件,在工作空间的顶层目录。

  • 这个文件的配置内容保证里工作空间内所有的crate使用的依赖的版本都相同。

下面我们做一个测试

我们先在add_one项目的Cargo.toml添加以下定义

ini 复制代码
rand = "0.3.14"

我们在adder项目的Cargo.toml添加以下定义

ini 复制代码
rand = "0.3.15"

但是我们在工作空间执行cargo build之后,通过分析Cargo.lock文件

  • 发现两个crate使用的是同一个版本,并覆盖了Cargo.toml中定义的版本
  • 这样工作空间内所有的crate相互兼容

我们再通过cargo new add_two --lib创建add-two项目,并在工作空间里引入,如果这时候我们直接在add_two项目里使用rand crate是不行的,编译会报错,需要在其Cargo.toml先声明才可以。

5. 为工作空间添加测试

当我们在工作空间运行cargo test时,cargo会一次性运行工作空间里的所有crate的测试代码,包括文档注释的测试。如果只需要测试某个crate,使用-p参数指定具体crate即可,

如下示例命令:

bash 复制代码
cargo test -p add_one

对于发布,没有提供一次性发布工作空间所有crate的功能,如果需要发布,我们必须手动切换到具体的crate目录,再执行cargo publish。

相关推荐
星栈9 小时前
视频即代码,Remotion 能做什么、不能做什么
前端·音视频开发
广州华水科技9 小时前
单北斗GNSS位移监测系统的应用与技术解析
前端
用户479492835691510 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
风骏时光牛马12 小时前
生成一个AI多模态标题,仅输出一条标题,无额外文字、问句、备选、配图、文案等任何附加内容,不需要其他的任务服务 只要标题。
前端
wangruofeng13 小时前
从 GIF 到 AVIF:网页图片格式演进与 2026 年选型指南
前端·架构
wflynn13 小时前
GitHub 今日推荐|Stela:在 PC 上直接启动 macOS 的翻译层
rust·开源·github
清晨Coding14 小时前
为什么用 React Developer Tools 查看组件树这么乱?
前端·react.js
鶴哥只手遮天14 小时前
《Electron 45.2.3 内核解剖》第 4 章 补丁体系:380 个补丁改了什么
前端·electron
aifannihao14 小时前
Rust 1.100 的 DropGuard:用 Python 实测失败回滚与吞异常
python·rust·异常处理·标准库·contextlib
FungLeo16 小时前
成为全栈·Vue 管理后台篇·分类树与标签管理:层级数据如何落到管理界面
前端·javascript·vue.js·分类树·naive ui·标签管理·前端数据结构