10

How can you have multiple nested workspace with Cargo?

I have the following project structure:

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

Where project_b_dependency is a big library which is a git submodule which has a workspace by itself.

I get an error when I run cargo build because there is a workspace within a workspace.

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

Is there a simple work-around? I want to keep project_b_dependency in source control as a submodule.

This is not a duplicate of Refactoring to workspace structure causes extern crate imports to not work because I want to know how I can deal with nested workspaces.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Olivier
  • 773
  • 9
  • 14
  • Possible duplicate of [Refactoring to workspace structure causes extern crate imports to not work](https://stackoverflow.com/questions/49712872/refactoring-to-workspace-structure-causes-extern-crate-imports-to-not-work) – AbhiNickz Apr 16 '18 at 05:44
  • What do you want the behavior to be? Should `cargo build --all` put all the build artifacts of the workspace members of `project_b_dependency` into the `myworkspace` target directory? – Shepmaster Apr 16 '18 at 15:31
  • Yes, that's the behavior I desired. Thankfully, everyone was able to answer my question. – Olivier Apr 17 '18 at 02:56

3 Answers3

5

It seems that nested workspaces are quite difficult to manage, so one possibility is to change the layout of you project:

.
├── 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

in myworkspace/Cargo.toml:

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

In myworkspace/project_b/Cargo.toml

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

I've tried to use workspace.exclude property with your layout but without success.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
attdona
  • 17,196
  • 7
  • 49
  • 60
  • Does that mean that the workspace `project_b_dependency` can only be imported all at once? Or can I import only one of its crates? – Boiethios Mar 03 '21 at 08:45
5

Workspaces can't be nested; as the docs state:

A crate may either specify package.workspace or specify [workspace]. That is, a crate cannot both be a root crate in a workspace (contain [workspace]) and also be a member crate of another workspace (contain package.workspace).

The Cargo workspace RFC also specified this:

A workspace is valid if these two properties hold:

  • A workspace has only one root crate (that with [workspace] in Cargo.toml).
  • All workspace crates defined in workspace.members point back to the workspace root with package.workspace.
ljedrz
  • 20,316
  • 4
  • 69
  • 97
  • 1
    Since this post, it's currently possible as [the docs](https://doc.rust-lang.org/cargo/reference/manifest.html#the-workspace-section) now state. Also : `An empty [workspace] table can be used with a [package] to conveniently create a workspace with the package and all of its path dependencies.` – Raphaël Duchaîne Oct 29 '20 at 10:25
  • I don't see that phrase in the docs. It explains two examples a workspace with a package in the root, and a workspace that has a virtual root with (possibly) multiple children... but it doesn't mention further nesting. i.e. those children being workspaces with children of their own. The existence of this issue in the open state seems to confirm that? https://github.com/rust-lang/cargo/issues/5042 – Andrew Mackenzie Oct 14 '22 at 20:08
1

I find a method to keep git submodule.

  1. Add submodule project's workspace members to parent Cargo.toml
  2. Remove submodule project's Cargo.toml
  3. Use submodule_name/crate path to define dependency.
jolestar
  • 1,285
  • 15
  • 21