Subject: [bug#35318] [PATCH] Update cargo-build-system to expand package inputs

From: Ivan Petkov <[email-masked]>
Date: Sat, 8 Jun 2019 16:33:50 -0700

Hi Chris,

> On Jun 8, 2019, at 11:44 AM, Chris Marusich <[email-masked]> wrote:
> 
> Sorry for taking so long to review this.  In short, I think these
> changes are good, and if nobody has more feedback in the next few days,
> I will merge it and we can see how it works in practice!

Thanks for the feedback, and thanks for the wonderful pros and cons summary!

> Cons:
> 
>    - Because the "dependencies" and "dev-dependencies" are specified as
>      package arguments instead of any kind of "input", they won't show
>      up in some of the graphs produced by "guix package".  However, in
>      theory "guix graph" could be taught to display nodes for crate
>      "dependencies" and "dev-dependencies", too.

Totally correct, we can iterate on this in the future.

>    - Everyone who defines a Guix package for a crate must make sure the
>      origin's file name ends in ".cargo", since the cargo-build-system
>      now assumes that any input ending in ".cargo" is a crate that
>      should be extracted into the build's crate-dir.  This is a little
>      brittle, and I wish we had a better way to check this, but I can't
>      think of a better way at the moment.  Since you've updated the
>      importer to always add this, it probably won't be much of an issue
>      in practice, since that's the default way new crates will be added
>      to Guix.  Going forward, maybe we can avoid this by just checking
>      the inputs to see which ones are gzipped tarballs containing
>      Cargo.toml files.

We discussed an alternative solution to this offline, namely we can ask
tar to check if a Cargo.toml file exists at the top level without fully unpacking
the archive. If it exists, we can assume the tarball is a crate source and only
then unpack it in the vendor directory.

This will make things less brittle as the `.crate` convention won’t be necessary
(a potential downside would be that if there happens to be some arbitrary input
which happens to be a tarball which happens to have a Cargo.toml, it will get
included in the vendor directory without us knowing about it. I think the chances
of this happening in practice are virtually zero, so we can iterate on this if it ever
becomes a problem).

I’m going to try to update the patch series to include this change over the next
few days (along with Ludo’s naming-related feedback). If I don’t get a chance to
finish this, we can always merge it in later!

> Limitations imposed by Rust/Cargo itself:
> 
>    - I'm not a Rust or Cargo expert, but my current understanding is
>      that it isn't feasible to save the artifacts produced when
>      building a crate for re-use when building another crate.  In the
>      world of C, it is common to produce a library, and then link
>      against that library when building other software later.  In Guix,
>      when building a C library, we install the built artifacts (e.g.,
>      .so files) into the output, so that those artifacts can be used as
>      the input for another package's build.  It seems that, by Cargo's
>      design, it isn't currently feasible to do the same sort of thing
>      with Cargo: that is, it isn't feasible to build artifacts, install
>      them somewhere for later use, and then later re-use them in
>      another Cargo build.  I'd be glad to learn that I'm mistaken, but
>      currently that is my understanding.

Your understanding here is correct.

>    - Related to this, I doubt that a Rust programmer will be able to
>      invoke a command like "guix environment my-crate" (even if we
>      teach it to understand crate "dependencies" and
>      "dev-dependencies") to make all the dependencies required to build
>      my-crate available.  If a Rust programmer wants to hack on
>      my-crate, they'll probably still just use "cargo" to do it without
>      using Guix at all.  Is there any way to avoid this and make it
>      possible to get the dependencies used by Guix in the build, so
>      that a Rust programmer can hack around using precisely those
>      dependencies?  If this were C or Python, you could do that using
>      "guix environment," but I'm not sure how this could work with Rust
>      crates.

Correct again, a programmer will not be able to run `guix environment my-crate`,
however, I don’t think anyone will do this in practice, since you can’t “point” cargo
at that source closure/outputs anyway.

For hacking on Rust crates, I’d imagine a Rust programmer would simply stick with
cargo and the crates.io <http://crates.io/> ecosystem proper. I don’t ever see guix as being a replacement
for crates.io <http://crates.io/> (it would be impossible to keep up with the package changes, even if we
automate things, crates aren’t guaranteed to even build, etc.).

I’d imagine that crates should only be imported into guix if they’re necessary for supporting
an actual application or service written in Rust, but not used for day-to-day development.

—Ivan