Cargo Workspace Behavior Change between 1.50 and 1.51

Cargo Workspace Behavior Change

There is a change in the way cargo workspaces handle dependencies between 1.50 and 1.51.
Before 1.51, attempting to build a dependency with --package fails if it is not a workspace member.
After 1.51 this becomes possible.

Workspace Description

  • notws is a directory that contains one library package named dep_1.
  • ws is a directory that contains a workspace-only Cargo.toml file and a package that is a member of the workspace, ws_member_1.
  • ws_member_1 has dep_1 as a dependency using path.
โ”œโ”€โ”€ notws
โ”‚   โ””โ”€โ”€ dep_1
โ”‚       โ”œโ”€โ”€ Cargo.toml
โ”‚       โ””โ”€โ”€ src
โ”‚           โ””โ”€โ”€ lib.rs
โ””โ”€โ”€ ws
    โ”œโ”€โ”€ Cargo.lock
    โ”œโ”€โ”€ Cargo.toml
    โ””โ”€โ”€ ws_member_1
        โ”œโ”€โ”€ Cargo.toml
        โ””โ”€โ”€ src
            โ””โ”€โ”€ main.rs

Repro

If I try to build dep_1 from the workspace context with 1.50, it fails to find the package.
This seems reasonable given that dep_1 is a dependency, but not a workspace member.

rustup default 1.50.0
cargo build --manifest-path ./ws/Cargo.toml --package dep_1
# error: package ID specification `dep_1` matched no packages

This works with 1.51.0:

rustup default 1.51.0
cargo build --manifest-path ./ws/Cargo.toml --package dep_1

Question

Is this behavior change intended?
Can I rely on this behavior in my build?

Here is the repo: GitHub - webern/cargo-workspace-1.51: Demonstrates a change to workspace behavior in 1.51 that I have a question about.

Kind of a wild stab, but maybe it was this Add suggestion for bad package id. by ehuss ยท Pull Request #9095 ยท rust-lang/cargo ยท GitHub and thus @ehuss would know?

The Files

ws/Cargo.toml:

[workspace]
members = [
    "ws_member_1",
]

ws/ws_member_1/Cargo.toml:

[package]
name = "ws_member_1"
version = "0.1.0"
edition = "2018"

[dependencies]
dep_1 = { path = "../../notws/dep_1" }

notws/dep_1/Cargo.toml:

[package]
name = "dep_1"
version = "0.1.0"
edition = "2018"
1 Like

This changed as part of the new cli feature flag behavior. I don't think it was intentional for this specific case.

Can you say more about why you would want to do that?

It solves a very specific problem in a very complicated build. It would be a bit hard to describe. But an attempt at a TL;DR is that, we don't want to move a certain directory to be within the workspace, cargo complains if I try to include siblings as workspace members with "../../overthere", and we have separate build targets that should re-use the workspace's build context.

The very specific place where it would be convenient to rely on this behavior is here:

Edit: I should admit that what we are doing is beyond what anyone probably ever intended with cargo, I wrote this a while ago to describe it: How the Bottlerocket build system works | AWS Open Source Blog

Makes sense. Thanks for taking the time to write up all the details and the repro.

I don't currently have any plans to change the behavior. It will be somewhat limited in that you cannot specify feature flags for non-members, though.

Ok, thank you for your help!

I think it'd be best to file it as a Cargo bug, so people familiar with the details would see the question.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.