rustrust-cargo

How can I build a rust/cargo workspace from scattered (non-hierarchical) directories?


I have a series of projects that have accumulated over the years, and as I refactor the API of the core library it is becoming a hassle to check&update all the apps that depend on that library. Not only did I have to write a shell script to iterate through them all, it chewed up a lot of disk space and compute time recompiling the same stuff in all the directories.

I thought I could maybe use a workspace, but immediately was disappointed:

error: workspace member `/home/user/art/2019/equation-minis/equation-stitcher/Cargo.toml` is not hierarchically below the workspace root `/home/user/src/embroidery/Cargo.toml`

I tried faking it out with a symlink like ln -s ../../art . but that failed because the art project uses

[dependencies]
"filler" = { path = "../../../src/embroidery/filler" }

and cargo complains:

error: failed to load manifest for workspace member `/home/user/src/embroidery/art/2022/united-methodist`

Caused by:
  failed to load manifest for dependency `filler`

Caused by:
  failed to read `/home/user/src/embroidery/src/embroidery/filler/Cargo.toml`

Is there a more flexible way to treat a bunch of rust crates as a workspace (consistent Cargo.lock, sharing built artifacts) ?


Solution

  • The Cargo book tells you:

    When inside a subdirectory within the workspace, Cargo will automatically search the parent directories for a Cargo.toml file with a [workspace] definition to determine which workspace to use. The package.workspace manifest key can be used in member crates to point at a workspace’s root to override this automatic search. The manual setting can be useful if the member is not inside a subdirectory of the workspace root.

    So just add this to the Cargo.toml of your out of directory crate:

    [package]
    workspace = "<path to the directory containing the workspace Cargo.toml>"