|
From: | Jason Conroy |
Subject: | Re: rust-team branch merged |
Date: | Mon, 06 May 2024 10:00:26 -0400 |
Efraim Flashner <efraim@flashner.co.il> writes:
[[PGP Signed Part:Undecided]] On Wed, Apr 24, 2024 at 11:58:22AM -0400, Jason Conroy wrote:Efraim Flashner <efraim@flashner.co.il> writes:> On the other hand, by generating it during the build of each > package we > make sure to pull in all the crates which exist in the build, > so we > could add into a profile/manifest just the crates listed in a > Cargo.toml > and then each crate would pull in its own dependencies, and > then the> profile hook could combine them all together.Thanks. Just to make sure I understand: it sounds like you're saying that by creating the JSON index files up front, we'd be preserving some knowledge about a package's dependency graph that isn't easily recovered later by recursively walking through inputs and cargo-inputs for the package specs ina manifest/profile?If we create it upfront it may be easier to keep track of the cargo-dependencies, but I suppose it would mostly depend on theimplementation. I'm not sure that'd actually be the case, so don't worry about it too much. Whatever we end up with will be better than what we have now, and we can always make it better later if it needs tochange.
Hi Efraim, I spent some time on this and have a few thoughts below. In short, I made progress but also hit some roadblocks that give me second thoughts about the approach we discussed up-thread.
As you suggested, I kept the metadata generation code in cargo-build-system and used the cargo-registry profile hook to merge all of those package artifacts into index files. I also modified the hook to lift the full closure of source dependencies into the profile for any rust packages in the manifest, borrowing logic from `(guix build-system cargo)`.
However, testing revealed some issues with this approach:1) Formerly, for any cargo package with `#:skip-build? #t` the crate was treated as an opaque file: it was copied to a location where cargo could access it, but otherwise unprocessed. But to generate the index file we need to unpack the crate and call `cargo metadata`, which performs some sanity checks on the package structure. The implication is that if #:skip-build? is used for reasons other than performance - e.g., for a package that works fine as a dependency but somehow fails during a standalone build - then we might have trouble including such a package in Cargo's local registry. I don't know how big an issue this is in practice, but I think I encountered one package that fits this scenario: custom_derive-0.1.7. (We can discuss the details in a separate thread if you're interested.)
2) When building against a local-registry, it seems like Cargo expects to find crates that it wouldn't for a vendor tree. As mentioned above, my current patch pulls source crates into the profile using the same logic as cargo-build-system currently does: for each manifest package and its cargo-development-inputs, recursively walk through all of the cargo-inputs. But after building a profile this way, I encountered the following:
$ cargo build error: no matching package named `automod` found location searched: registry `crates-io` required by package `serde_json v1.0.111`... which satisfies dependency `serde_json = "^1.0"` of package `rand_chacha v0.3.1` ... which satisfies dependency `rand_chacha = "^0.3.0"` of package `rand v0.8.5` ... which satisfies dependency `rand = "^0.8.5"` of package `mytest v0.1.0 (/home/guix/mytest)`
Note that serde_json is actually a dev-dependency of rand_chacha, and automod is a dev-dependency of serde_json, but our algorithm above assumes that dev-dependencies of dependencies can be omitted. So in practice, it seems like building a local-registry that cargo will accept is even more expensive than building a vendor tree.
3) The build error above is interesting for another reason: cargo simply gives up rather than fetching the missing dependencies. In our earlier discussion, the motivation for using a local-registry over a vendor tree in a profile was to support a sort of hybrid workflow: the profile seeds the registry with some packages, but cargo can still download others on its own during `cargo build`. But in this test and several others, I haven't observed a case where cargo falls back to crates.io for missing packages. Efraim, could you share details on how you accomplished this in the past? I wonder if our discussion might have conflated cargo's registry cache ($CARGO_HOME/registry) with a true local-registry; I haven't found any good documentation on the former, but it has a different directory layout and index file format from the local-registry's, so it wouldn't surprise me if it had different semantics as well.
Cheers, Jason
[Prev in Thread] | Current Thread | [Next in Thread] |