[bug#77093,rust-team,04/18] build-system: cargo: Support installing Cargo workspace.

Message ID f9521627c5f774edcccd732ecc7f368375180b64.1742281797.git.hako@ultrarare.space
State New
Headers
Series New Rust packaging workflow based on lockfile importer. |

Commit Message

Hilton Chain March 18, 2025, 7:24 a.m. UTC
  *guix/build-system/cargo.scm (cargo-build,cargo-cross-build)
[#:cargo-install-paths]: New argument.
* guix/build/cargo-build-system.scm (install): Use it.
* doc/guix.texi (Build Systems)[cargo-build-system]: Document it.

Change-Id: I74ed1972a5716da05afeac8edb2b0e4b6834bf40
---
 doc/guix.texi                     |  5 ++++-
 guix/build-system/cargo.scm       |  4 ++++
 guix/build/cargo-build-system.scm | 17 +++++++++++++----
 3 files changed, 21 insertions(+), 5 deletions(-)
  

Comments

Efraim Flashner March 18, 2025, 11:49 a.m. UTC | #1
I don't love the name cargo-install-paths.  I had to build atuin to see
what it did.  The last few lines of the 'install phase:

   Compiling atuin-daemon v18.4.0 (/tmp/guix-build-atuin-18.4.0.drv-0/source/crates/atuin-daemon)
   Compiling atuin v18.4.0 (/tmp/guix-build-atuin-18.4.0.drv-0/source/crates/atuin)
    Finished `release` profile [optimized] target(s) in 22.73s
  Installing /gnu/store/yqfi454wkc1lv455m7n5i7l5lwn1la8v-atuin-18.4.0/bin/atuin
   Installed package `atuin v18.4.0 (/tmp/guix-build-atuin-18.4.0.drv-0/source/crates/atuin)` (executable `atuin`)
warning: be sure to add `/gnu/store/yqfi454wkc1lv455m7n5i7l5lwn1la8v-atuin-18.4.0/bin` to your PATH to be able to run the installed binaries

With #:cargo-install-paths removed I got an error that it was a virtual
manifest and to find the actual package.  Looking at the Cargo.toml I
don't see an obvious way to figure out which package(s) in the workspace
has an installable executable.

So obviously 'paths-to-installable-crates-in-the-worktree' is too long.
Looking at the code it's obvious how the name cargo-install-path came to
be.

On Tue, Mar 18, 2025 at 03:24:17PM +0800, Hilton Chain wrote:
> *guix/build-system/cargo.scm (cargo-build,cargo-cross-build)
> [#:cargo-install-paths]: New argument.
> * guix/build/cargo-build-system.scm (install): Use it.
> * doc/guix.texi (Build Systems)[cargo-build-system]: Document it.
> 
> Change-Id: I74ed1972a5716da05afeac8edb2b0e4b6834bf40
> ---
>  doc/guix.texi                     |  5 ++++-
>  guix/build-system/cargo.scm       |  4 ++++
>  guix/build/cargo-build-system.scm | 17 +++++++++++++----
>  3 files changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 322512fd36..c20e1d7f9c 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -9369,7 +9369,10 @@ Build Systems
>  names of library crates to package in @code{package} phase.  Specified
>  crates are packaged from left to right, in case there's dependency among
>  them.  For example, specifying @code{''("pcre2-sys" "pcre2")} will
> -package @code{"pcre2-sys"} first and then @code{"pcre2"}.
> +package @code{"pcre2-sys"} first and then @code{"pcre2"}.  Parameter
> +@code{#:cargo-install-paths} (default: @code{''()}) allows specifying
> +paths of binary crates to install in @code{install} phase,

paths of binary crates to install in the @code{install} phase,

> +@code{''("crates/atuin")}, for example.
>  @end defvar
>  
>  @defvar chicken-build-system
> diff --git a/guix/build-system/cargo.scm b/guix/build-system/cargo.scm
> index 4f6d46e70c..4486c706a1 100644
> --- a/guix/build-system/cargo.scm
> +++ b/guix/build-system/cargo.scm
> @@ -96,6 +96,7 @@ (define* (cargo-build name inputs
>                        (cargo-test-flags ''())
>                        (cargo-package-crates ''())
>                        (cargo-package-flags ''("--no-metadata" "--no-verify"))
> +                      (cargo-install-paths ''())
>                        (features ''())
>                        (skip-build? #f)
>                        (parallel-build? #t)
> @@ -125,6 +126,7 @@ (define* (cargo-build name inputs
>                         #:cargo-test-flags #$(sexp->gexp cargo-test-flags)
>                         #:cargo-package-crates #$(sexp->gexp cargo-package-crates)
>                         #:cargo-package-flags #$(sexp->gexp cargo-package-flags)
> +                       #:cargo-install-paths #$(sexp->gexp cargo-install-paths)
>                         #:cargo-target #$(cargo-triplet system)
>                         #:features #$(sexp->gexp features)
>                         #:skip-build? #$skip-build?
> @@ -158,6 +160,7 @@ (define* (cargo-cross-build name
>                              (cargo-test-flags ''())
>                              (cargo-package-crates ''())
>                              (cargo-package-flags ''("--no-metadata" "--no-verify"))
> +                            (cargo-install-paths ''())
>                              (cargo-target (cargo-triplet (or target system)))
>                              (features ''())
>                              (skip-build? #f)
> @@ -190,6 +193,7 @@ (define* (cargo-cross-build name
>                         #:cargo-test-flags #$(sexp->gexp cargo-test-flags)
>                         #:cargo-package-crates #$(sexp->gexp cargo-package-crates)
>                         #:cargo-package-flags #$(sexp->gexp cargo-package-flags)
> +                       #:cargo-install-paths #$(sexp->gexp cargo-install-paths)
>                         #:cargo-target #$(cargo-triplet (or target system))
>                         #:features #$(sexp->gexp features)
>                         #:skip-build? #$skip-build?
> diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm
> index 001e9c7adc..bcee10837e 100644
> --- a/guix/build/cargo-build-system.scm
> +++ b/guix/build/cargo-build-system.scm
> @@ -384,6 +384,7 @@ (define* (install #:key
>                    skip-build?
>                    install-source?
>                    features
> +                  (cargo-install-paths '())
>                    #:allow-other-keys)
>    "Install a given Cargo package."
>    (let* ((out      (assoc-ref outputs "out"))
> @@ -398,10 +399,18 @@ (define* (install #:key
>      ;; Only install crates which include binary targets,
>      ;; otherwise cargo will raise an error.
>      (or skip-build?
> -        (not (has-executable-target?))
> -        (invoke "cargo" "install" "--offline" "--no-track"
> -                "--path" "." "--root" out
> -                "--features" (string-join features)))
> +        ;; NOTE: Cargo workspace installation support:
> +        ;; #:skip-build? #f + #:cargo-install-paths.
> +        (and (null? cargo-install-paths)
> +             (not (has-executable-target?)))
> +        (for-each
> +         (lambda (path)
> +           (invoke "cargo" "install" "--offline" "--no-track"
> +                   "--path" path "--root" out
> +                   "--features" (string-join features)))
> +         (if (null? cargo-install-paths)
> +             '(".")
> +             cargo-install-paths)))
>  
>      (when install-source?
>        ;; Install crate tarballs and unpacked sources for later use.
> -- 
> 2.48.1
> 
> 
>
  

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index 322512fd36..c20e1d7f9c 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -9369,7 +9369,10 @@  Build Systems
 names of library crates to package in @code{package} phase.  Specified
 crates are packaged from left to right, in case there's dependency among
 them.  For example, specifying @code{''("pcre2-sys" "pcre2")} will
-package @code{"pcre2-sys"} first and then @code{"pcre2"}.
+package @code{"pcre2-sys"} first and then @code{"pcre2"}.  Parameter
+@code{#:cargo-install-paths} (default: @code{''()}) allows specifying
+paths of binary crates to install in @code{install} phase,
+@code{''("crates/atuin")}, for example.
 @end defvar
 
 @defvar chicken-build-system
diff --git a/guix/build-system/cargo.scm b/guix/build-system/cargo.scm
index 4f6d46e70c..4486c706a1 100644
--- a/guix/build-system/cargo.scm
+++ b/guix/build-system/cargo.scm
@@ -96,6 +96,7 @@  (define* (cargo-build name inputs
                       (cargo-test-flags ''())
                       (cargo-package-crates ''())
                       (cargo-package-flags ''("--no-metadata" "--no-verify"))
+                      (cargo-install-paths ''())
                       (features ''())
                       (skip-build? #f)
                       (parallel-build? #t)
@@ -125,6 +126,7 @@  (define* (cargo-build name inputs
                        #:cargo-test-flags #$(sexp->gexp cargo-test-flags)
                        #:cargo-package-crates #$(sexp->gexp cargo-package-crates)
                        #:cargo-package-flags #$(sexp->gexp cargo-package-flags)
+                       #:cargo-install-paths #$(sexp->gexp cargo-install-paths)
                        #:cargo-target #$(cargo-triplet system)
                        #:features #$(sexp->gexp features)
                        #:skip-build? #$skip-build?
@@ -158,6 +160,7 @@  (define* (cargo-cross-build name
                             (cargo-test-flags ''())
                             (cargo-package-crates ''())
                             (cargo-package-flags ''("--no-metadata" "--no-verify"))
+                            (cargo-install-paths ''())
                             (cargo-target (cargo-triplet (or target system)))
                             (features ''())
                             (skip-build? #f)
@@ -190,6 +193,7 @@  (define* (cargo-cross-build name
                        #:cargo-test-flags #$(sexp->gexp cargo-test-flags)
                        #:cargo-package-crates #$(sexp->gexp cargo-package-crates)
                        #:cargo-package-flags #$(sexp->gexp cargo-package-flags)
+                       #:cargo-install-paths #$(sexp->gexp cargo-install-paths)
                        #:cargo-target #$(cargo-triplet (or target system))
                        #:features #$(sexp->gexp features)
                        #:skip-build? #$skip-build?
diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm
index 001e9c7adc..bcee10837e 100644
--- a/guix/build/cargo-build-system.scm
+++ b/guix/build/cargo-build-system.scm
@@ -384,6 +384,7 @@  (define* (install #:key
                   skip-build?
                   install-source?
                   features
+                  (cargo-install-paths '())
                   #:allow-other-keys)
   "Install a given Cargo package."
   (let* ((out      (assoc-ref outputs "out"))
@@ -398,10 +399,18 @@  (define* (install #:key
     ;; Only install crates which include binary targets,
     ;; otherwise cargo will raise an error.
     (or skip-build?
-        (not (has-executable-target?))
-        (invoke "cargo" "install" "--offline" "--no-track"
-                "--path" "." "--root" out
-                "--features" (string-join features)))
+        ;; NOTE: Cargo workspace installation support:
+        ;; #:skip-build? #f + #:cargo-install-paths.
+        (and (null? cargo-install-paths)
+             (not (has-executable-target?)))
+        (for-each
+         (lambda (path)
+           (invoke "cargo" "install" "--offline" "--no-track"
+                   "--path" path "--root" out
+                   "--features" (string-join features)))
+         (if (null? cargo-install-paths)
+             '(".")
+             cargo-install-paths)))
 
     (when install-source?
       ;; Install crate tarballs and unpacked sources for later use.