Cargo package doesn't work with Rust's workspace? - rust

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"
# error here. It can't found the foo_2 package.
[dependencies]
foo_2 = { 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)`

Packaging and publishing crates requires all dependencies of said crate to also be available in a registry. For publishing this is relatively obvious, since consumers also need to be able to fetch and build transitive dependencies. Creating tarballs also happens to have the same constraints at the moment, so it is not possible if they are not meant to be published.
Whenever you have a project with many crates in a single workspace and wish to publish them on crates.io, you would start with the crate without dependencies and work your way up to the other crates.
cargo publish -p foo_2
cargo publish -p foo_1
Or, using cargo-workspaces:
cargo workspaces publish
Is this an intended behavior?
One can still publish crates in a workspace, so long as this is done in the right order. For packaging, it is a limitation at the time of writing. The current behavior could be linked with packaging being primarily part of publishing, so this could probably be improved.
If so, then why should I bother with workspace at all?
Tangential to the matter here. Workspaces exist mainly to settle other concerns, such as having a single source of compiled dependencies with a shared dependency lock. This distinction is described in that same link.

Related

error: no matching package named `rocket_dyn_templates` found

I'm trying to build a small web server using Rust and the Rocket framework. For this I need the rocket_dyn_templates crate, so I did a cargo search rocket_dyn_templates, which gave as output
rocket_dyn_templates = "0.1.0-rc.2" # Dynamic templating engine integration for Rocket.
and added
rocket_dyn_templates = "0.1.0-rc2"
to the Cargo.toml file in my project.
However, when I try cargo run, cargo update or cargo package I always get the same output:
Updating crates.io index
error: no matching package named `rocket_dyn_templates` found
location searched: registry `crates-io`
required by package `calc v0.1.0 (/home/utilisateur/tmp/calc)`
I was expecting the crate to be found and downloaded, instead I keep getting the error message that no matching package was found. What am I doing wrong?
As cafce25 said, the issue was a missing . in the Cargo.toml file - it should be rc.2, not rc2.

How does cargo manage dependency versions?

I was reading this at the guessing game tutorial inside the rust book
Ensuring Reproducible Builds with the Cargo.lock File
Cargo has a mechanism that ensures you can rebuild the same artifact every time you or anyone else builds your code: Cargo will use only the versions of the dependencies you specified until you indicate otherwise. For example, say that next week version 0.8.4 of the rand crate comes out, and that version contains an important bug fix, but it also contains a regression that will break your code. To handle this, Rust creates the Cargo.lock file the first time you run cargo build, so we now have this in the guessing_game directory.
When you build a project for the first time, Cargo figures out all the versions of the dependencies that fit the criteria and then writes them to the Cargo.lock file. When you build your project in the future, Cargo will see that the Cargo.lock file exists and use the versions specified there rather than doing all the work of figuring out versions again. This lets you have a reproducible build automatically. In other words, your project will remain at 0.8.3 until you explicitly upgrade, thanks to the Cargo.lock file.
but didn't quite understand how cargo garantees that we have/need the correct version of a dependency. For instance, if we put in the [dependecies] rand="0.8.3" it will not exactly download the crate at this version, but the crate the match the needs of our program but it's compatible with this version(?)
Please clarify this logic!
When specifying a crate in Cargo.toml, you can give an exact version (e.g. =0.8.3) or more general indications (e.g. 0.8.*).
If you specify rand = "=0.8.3" in Cargo.toml, then cargo will take version 0.8.3 (note the extra = inside the version requirement). But if you specify rand = "*", then the first time you build your crate it will take the latest version and write this version to Cargo.lock. That way if you rebuild your crate later cargo will reuse the same version even if a new version has been published on crates.io in the meantime.
Note btw that specifying rand = "0.8.3" does not mean "exactly version 0.8.3", but instead means "any version >=0.8.3 and <0.9": link.

No matching package found

I am trying to integrate an API in a yew project and facing the following issue:
Dark#Dark:/var/www/html/yew-practice$ wasm-pack build --target web
Error: Error during execution of `cargo metadata`: Updating crates.io index
Updating git repository `https://github.com/yewstack/yew`
error: no matching package found
searched package name: `yewtil`
perhaps you meant: yew
location searched: https://github.com/yewstack/yew
Cargo.toml:
[package]
name = "yew-practice"
version = "0.1.0"
edition = "2018"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "^0.2"
serde="1"
yew = { git = "https://github.com/yewstack/yew" }
yewtil = { git = "https://github.com/yewstack/yew", features = ["fetch"] }
How do I solve the problem above?
The error tells you that no package yewtil was found in the Git repository. If you go to the repository and check its Cargo.toml file, you will indeed notice that it doesn't include a yewtil package.
I searched in the repository for yewtil, and found this pull request that refactored the project and merged yewtil into other packages: yewstack/yew#1842.
You have two options now:
Drop the dependency on yewtil, and use the documentation to figure out where the features have moved that you want to use.
Add a tag key to the dependency to pull in the latest release that included yewtil, or simply switch to the latest published version on crates.io.
If you want to get the latest features from yew, which appears to be the case given that you're pulling in the package from GitHub and not crates.io, go with option 1. You can use the documentation and the examples in the master branch to see how to use the package in its latest version.
Yew git repository is not a valid address, it must end with .git.
git = "https://github.com/yewstack/yew.git"

How do I resolve a cyclic dependency in Cargo?

I have the crates oauth2 (v4.1.0) and sqlx[json] (v0.5.5):
[dependencies]
oauth2 = "4.1.0"
sqlx = { version = "0.5.5", features = ["json"] }
When attempting to build, I am getting the following error:
error: cyclic package dependency: package `ahash v0.7.4` depends on itself. Cycle:
package `ahash v0.7.4`
... which is depended on by `hashbrown v0.11.2`
... which is depended on by `indexmap v1.7.0`
... which is depended on by `serde_json v1.0.64`
... which is depended on by `wasm-bindgen v0.2.74`
... which is depended on by `js-sys v0.3.51`
... which is depended on by `getrandom v0.2.3`
... which is depended on by `ahash v0.7.4`
This only happens when I activate the json feature flag on sqlx. How do I troubleshoot this kind of problem? Are there any workarounds to make these libs/features work together? What are the alternatives?
After trying a few things back and forth, the only solution I found, was to update the lockfile to the latest version, using:
cargo update
After that, cargo clean && cargo build worked like a charm! Seems like some older patch versions seem to have conflicts, but the changes in the Cargo.lock were too big to track down, which crate combination it was. I hope that helps anybody else!
EDIT: After more communication and searching, I got referred to an issue directly at the ahash github project: https://github.com/tkaitchuck/aHash/issues/95.
According to that, the actual official "workaround" was / is, to pin the indexmap crate to:
indexmap = "=1.6.2"
However when looking into my Cargo.lock file, it seems to work with now:
indexmap = "1.7"

How do I fix mismatching dependencies in my Cargo file to work around native library collisions?

I'm setting up a Rust server with Rocket and I'm trying to use it with a JWT library. They use different versions of the *ring* crate and I get an error during cargo build:
error: multiple packages link to native library `ring-asm`, but a native library can be linked only once
package `ring v0.12.1`
... which is depended on by `jsonwebtoken v4.0.1`
... which is depended on by `auther v0.1.0 (file:///home/drpytho/x/downloadble/auther)`
links to native library `ring-asm`
package `ring v0.11.0`
... which is depended on by `cookie v0.9.2`
... which is depended on by `rocket v0.3.6`
... which is depended on by `rocket_codegen v0.3.6`
... which is depended on by `auther v0.1.0 (file:///home/drpytho/x/downloadble/auther)`
also links to native library `ring-asm`
My Cargo.toml
[package]
name = "auther"
version = "0.1.0"
authors = ["Name <Email#mail.se>"]
[dependencies]
rocket = "0.3.6"
rocket_codegen = "0.3.6"
jsonwebtoken = "4"
serde_derive = "1"
serde = "1"
I read that you are supposed to fix the mismatching dependencies in your Cargo file, but I can't figure out how to do it.
You have to fix this by not transitively depending on different versions of crates that link to a native library.
There's no newer version of rocket available that depends on version 0.10 of cookie, which depends on ring 0.12, so you'll need to downgrade jsonwebtoken to 2.0.3.
You can work this out by checking the crates.io pages for the crates in question (like with jsonwebtoken), going back through older versions, and looking to see what dependencies it needs.

Resources