rust 如何处理多个嵌套的工作区根?

hyrbngr7  于 2023-10-20  发布在  其他
关注(0)|答案(4)|浏览(187)

如何使用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作为子模块保存在源代码控制中。
这不是Refactoring to workspace structure causes extern crate imports to not work的重复,因为我想知道如何处理嵌套的x1e。

jslywgbw

jslywgbw1#

工作区不能嵌套;正如docs所说:
一个crate可以指定package.workspace或者指定[workspace]。也就是说,一个crate不能同时是一个工作区的根crate(包含[workspace])和另一个工作区的成员crate(包含package.workspace)。
Cargo workspace RFC还指定了以下内容:
如果以下两个属性成立,则工作区有效:

*一个工作区只有一个根crate(Cargo.toml中有[workspace]的那个)

  • workspace.members中定义的所有工作区crate都指向带有package.workspace的工作区根。
pgvzfuti

pgvzfuti2#

看起来嵌套的布局很难管理,所以一种可能性是更改项目的布局:

.
├── 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属性与您的布局,但没有成功。

tzdcorbm

tzdcorbm3#

我找到了一个保持git子模块的方法。
1.将子模块项目的工作区成员添加到父Cargo.toml
1.移除子模块项目的Cargo.toml
1.使用submodule_name/crate path定义依赖关系。

slhcrj9b

slhcrj9b4#

我已经找到了一种方法来完成这个任务,但它需要您引入的子模块的合作,以遵循类似的模式。
我这里的问题是,我有一个lib bigger_lib,它在repo中作为一个工作区,然后是一个common_lib,它是my_appbigger_lib的依赖项(不是具体的问题是问什么,但我试图解决什么)。这些都是我们目前许多小工作空间仓库的代表,都在git上。
像这样的布局

workspace root
├── Cargo.toml (workspace)
├── my_app (executable)
|   └── 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, not a 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

相关问题