How to use Cargo package with Rust's workspace?

I create a "workspace" with several folder within it following the tutorial I read here

It runs successfully with cargo run or cargo build

if all of the package were independent from each other, cargo package would run successfully. But as soon as one package depends on the other the cargo package will fail.

It displays: no matching package named "foo_2" found. location searched: registry "crates-io". Which is pretty weird, since I specifically add a local path on the dependencies.

Is this an intended behavior? if so, then why should I bother with workspace at all ?

The root Cargo.toml

[workspace]
members = [
    "foo_1",
    "foo_2",
]

foo_1/Cargo.toml

[package]
name = "foo_1"
version = "0.1.0"
edition = "2021"

[dependencies]
item_manager = { path = "../foo_2", version = "0.1.0" }

foo_2/Cargo.toml

[package]
name = "foo_2"
version = "0.1.0"
edition = "2021"

[dependencies]

Error message:

PS E:\Works\Experimentals\rust-workspace> cargo package --workspace
warning: manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
   Packaging foo_1 v0.1.0 (E:\Works\Experimentals\rust-workspace\foo_1)
   Verifying foo_1 v0.1.0 (E:\Works\Experimentals\rust-workspace\foo_1)
    Updating crates.io index
error: failed to verify package tarball

Caused by:
  no matching package named `foo_2` found
  location searched: registry `crates-io`
  required by package `foo_1 v0.1.0 (E:\Works\Experimentals\rust-workspace\target\package\foo_1-0.1.0)`

When packaged, cargo ignores path dependencies. This allows for interconnected workspace crates to have path + version dependencies on other workspace crates, and when used in the workspace they'll use the other workspace crates, but when published they'll use the other crates in the registry.

1 Like

But what if I wish not to publish it to crates.io ?
Also if it ignores the path dependencies, what can I do if it was a private project ?
How can I bring foo_2 package to foo_1 (since foo_1 depends on foo_2 package)
Does workspace only work with published project in crates.io ?

1 Like

The workspace doesn't actually matter here; you'd get the same problem if you had a bunch of packages with path dependencies that weren't in a workspace. The problem is that cargo package expects all dependencies of the package to be published, and thus findable without following local paths.

Possibly you could make it succeed by running cargo package --no-verify, to skip the step where cargo package tries to build your package ignoring path dependencies. However, you'd still encounter a problem when trying to use the created package, since the dependencies would be assumed to be found via crates.io.

Maybe git = dependencies would work for you? I haven't ever tried creating packages manually, but the documentation doesn't say that wouldn't work. I know crates.io rejects git dependencies but maybe cargo package would be happy with them. If that doesn't work, then you'd need to set up a custom package registry.

If you're wondering “Why is this complicated? Surely people don't have to fiddle with this all the time?”: The typical way to distribute Rust code that is not published to crates.io is to publish a Git repository and use git = dependencies, not to use cargo package package files. Package files are usually used with crates.io or other Cargo registries only.

2 Likes