-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Features are always resolved at workspace level #66
Comments
Hey! I'm currently working through using cargo-auditable and/or cyclonedx to generate an SBOM, and I've run into this general class of issues. To address them, I'm planning to hook up the Cargo build simulations I wrote within guppy. These build simulations are, to my knowledge, correct for both the v1 and v2 resolvers, as validated by extensive randomized testing against Cargo itself. (They're also the foundation of cargo-hakari). The idea is that guppy's build simulations will produce the exact set of packages and features that a particular cargo build command would run, even if the build is expected to be run on a host platform that differs from the current platform. (So, for example, you can see the set of packages and features that would be built if you did a native build on x86_64-unknown-linux-gnu, even if you're on Windows or macOS.) I'm planning to maintain a fork for now. Would there be interest in upstreaming it? |
I'm also curious what your thoughts are about cargo-auditable vs cargo-cyclonedx. We're currently evaluating which approach to go with (data stored in the binary vs a file on the side) -- it seems like both have benefits and costs. |
Thank you for reaching out! Yes, this is interesting. I have also been looking into the krates crate, which also lets one write custom traversal functions over the crate graph and replicate resolver v2 fairly easily that way. I am cautious to introduce custom reimplementations of complex and loosely documented algorithms, but extensive randomized testing gives me enough confidence in its correctness. My concern is that Cargo is about to roll out the MSRV-aware resolver v3, which is going to ship in rust 1.85 in February 2025. This is the same release that will stabilize the 2024 edition and make MSRV-aware resolver the default. So whatever algorithm we use to refine TL;DR: I would be happy to switch to guppy if it also supports the upcoming resolver v3. And I guess we'd still have to maintain a raw |
Regarding cargo-auditable vs cargo-cyclonedx: I've worked on both tools. "both have benefits and costs" just about sums it up. |
Thanks for the response! Resolver v3 only affects the part of the dependency resolver that finds which versions to resolve to. Feature resolution is the same as v2, so no code changes are required. I'll try pushing an update to guppy to add the v3 resolver as an option, which works the same as the v2 resolver. I would definitely be careful about trying to reimplement the resolver yourself. While building guppy's Cargo resolution I found a number of edge cases. For example:
The resolver lives in Interestingly, in comparison testing I've found that guppy is many times faster than Cargo at delivering the same results. It's bad enough that guppy's CI runs the comparison tests in release mode — guppy itself is plenty fast in debug mode, but Cargo is too slow when you're running hundreds of simulations per run (even with opt-level 1). |
Curiously, Cargo itself is in the process of migrating to PubGrub to speed things up, and also make the dependency resolver a standalone crate: https://rust-lang.github.io/rust-project-goals/2024h2/pubgrub-in-cargo.html The tracking issue is here, and they have also demonstrated a significant performance improvement - see the comment from 3 days ago. If I add some dependency solver, I'd prefer it to be that one, because this will be identical to what Cargo itself uses. That would get us if not perfect correctness then at least perfect adherence to Cargo's quirks. Do you think it would be a good idea to just use that in place of guppy? |
Hmm I thought pubgrub was just for version resolution, not feature resolution (which isn't a constraint solving problem) |
I may be very wrong here! Let me ask the person working on PubGrub in Cargo. |
Indeed, the bits to be exposed by Cargo are not sufficient for the task. Then I'll be happy to add |
Resolver v3 is now supported as of guppy 0.17.11. See https://docs.rs/guppy/latest/guppy/graph/cargo/enum.CargoResolverVersion.html#variant.V3. If you decide to try integrating guppy, let me know! Happy to sync up in Zulip. I have to admit that guppy was the first big Rust crate I designed and I'd definitely do some things differently today. If there are particular warts that stand out or you have ideas for improving the API, please feel welcome to suggest them. |
Thank you! Is there any example code I could use as a starting point for integrating I'm particularly interested in how the resolver version is determined. |
This code can help you get started: https://github.com/guppy-rs/guppy/blob/6769bd5748b5a0cfe243db2a20b95a41ccc14878/cargo-guppy/src/lib.rs#L213-L296 Hakari (the workspace-hack manager) does a few things as well. See https://github.com/guppy-rs/guppy/blob/6769bd5748b5a0cfe243db2a20b95a41ccc14878/tools/hakari/src/hakari.rs#L988-L1007, and in general search for
The resolver version actually must be passed in -- it is not auto-determined. One of guppy's design principles is that it works purely in-memory with information passed into it (typically the output of Unfortunately,
Maybe there's a crate already which does this discovery. |
Oh, and the first example linked also shows how to set a different host platform. This feature allows hakari to work in a completely platform-independent manner, such that the same |
We use
cargo metadata
, so we are affected by this issue: rust-lang/cargo#7754The text was updated successfully, but these errors were encountered: