如何处理多个嵌套的工作空间根?

问题描述 投票:0回答:4

如何使用 Cargo 拥有多个嵌套工作区?

我有以下项目结构:

myworkspace
├── project_a
│   └── Cargo.toml
├── project_b
│   └── Cargo.toml
│   └── project_b_dependency
|       └── Cargo.toml
└── Cargo.toml

其中

project_b_dependency
是一个大库,它是一个 git 子模块,它本身有一个工作区。

运行

cargo build
时出现错误,因为工作区中存在工作区。

$ cargo build
error: multiple workspace roots found in the same workspace:
  /myworkspace
  /myworkspace/project_b/project_b_dependency

有简单的解决方法吗?我想将

project_b_dependency
作为子模块保留在源代码管理中。

这不是重构工作区结构导致 extern crate 导入不起作用的重复,因为我想知道如何处理嵌套工作区。

rust rust-cargo
4个回答
6
投票

工作空间不能嵌套;正如文档所述:

板条箱可以指定 package.workspace 或指定

[workspace]
。 也就是说,一个 crate 不能同时是工作空间中的 root crate(包含 [workspace]
)并且也是另一个工作区
的成员箱(包含
package.workspace
)。

Cargo

workspace RFC 也指定了这一点:

如果满足这两个属性,则工作空间有效:

  • 一个工作区只有一个 root crate(在 [workspace]
     中带有 
    Cargo.toml
  • workspace.members
     中定义的所有工作区 crate 都通过 
    package.workspace
     指向工作区根。

5
投票
嵌套工作空间似乎很难管理,所以 一种可能性是更改项目的布局:

. ├── myworkspace │   ├── Cargo.lock │   ├── Cargo.toml │   ├── project_a │   │   ├── Cargo.toml │   │   └── src │   │   └── lib.rs │   ├── project_b │   │   ├── Cargo.toml │   │   └── src │   │   └── lib.rs │   └── src │   └── main.rs └── project_b_dependency ├── Cargo.toml └── src └── lib.rs

myworkspace/Cargo.toml

[workspace] members= ["project_a", "project_b"]

myworkspace/project_b/Cargo.toml



[dependencies] project_b_dependency = {path = "../../project_b_dependency"}

我尝试在您的布局中使用

workspace.exclude

 属性,但没有成功。


1
投票
我找到了保留 git 子模块的方法。

    将子模块项目的工作区成员添加到父 Cargo.toml
  1. 删除子模块项目的 Cargo.toml
  2. 使用 submodule_name/crate 路径定义依赖项。

0
投票
我已经找到了一种方法来做到这一点,但它需要您引入的子模块合作以遵循类似的模式。

我的问题是,我有一个 lib

bigger_lib

,它在存储库中作为工作区,然后是一个 
common_lib
,它是 
my_app
bigger_lib
 的依赖项(不是具体问题所问的内容,但我正在努力解决的问题)。这些代表了我们许多小型工作区存储库的当前状态,全部都在 git 上。

这样的布局

workspace root ├── Cargo.toml (workspace) ├── my_app (exectuable package) | └── Cargo.toml ├── common_lib (lib, via submodule) | └── Cargo.toml └── bigger_lib_repo (workspace, via submodule) ├── Cargo.toml (workspace) ├── common_lib (lib, via submodule) | └── Cargo.toml └── bigger_lib (lib, via submodule)
内容看起来像这样

# ./Cargo.toml [workspace] members = ["app"] # Important to avoid the multiple workspaces error exclude = ["bigger_lib_repo"] # Unsure if this is necessary resolver = "2" [patch.crates-io] # The common dep gets overridden for everybody here common_lib = { path = "./common_lib" }
# ./my_app/Cargo.toml
[package]
name = "my_app"
version = "0.1.0"
edition = "2021"

[dependencies]
# Note this isn't specced using a path
common_lib = { version = "0.1.0" }
bigger_lib = { version = "0.1.0", path = "../bigger_lib_repo/bigger_lib" }
# ./bigger_lib_repo/Cargo.toml
[workspace]

members = [ "bigger_lib" ]

resolver = "2"

[patch.crates-io]
# Same as the root workspace
common_lib = { path = "./common_lib" }
# ./bigger_lib_repo/bigger_lib/Cargo.toml
[package]
name = "bigger_lib"
version = "0.1.0"
edition = "2021"

[dependencies]
# Note this isn't specced using a path
common_lib = { version = "0.1.0" }
所有其他 

Cargo.toml

 文件与您的预期并没有特别不同。

有了这个模式我就可以

    毫无问题地构建工作区根目录
  • 毫无问题地构建嵌套工作区根目录
  • 使用嵌套库中公开导出的包成员(即:
  • bigger_lib::common_lib::MyStruct
© www.soinside.com 2019 - 2024. All rights reserved.