如何使用 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 导入不起作用的重复,因为我想知道如何处理嵌套工作区。
工作空间不能嵌套;正如文档所述:
Cargo板条箱可以指定 package.workspace 或指定
。 也就是说,一个 crate 不能同时是工作空间中的 root crate(包含[workspace]
[workspace]
)并且也是另一个工作区的成员箱(包含package.workspace
)。
workspace RFC 也指定了这一点:
如果满足这两个属性,则工作空间有效:
- 一个工作区只有一个 root crate(在
在[workspace]
中带有Cargo.toml
)。workspace.members
中定义的所有工作区 crate 都通过package.workspace
指向工作区根。
.
├── 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
属性,但没有成功。
我的问题是,我有一个 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
)