all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Efraim Flashner <efraim@flashner.co.il>
To: jgart <jgart@dismail.de>
Cc: guix-devel@gnu.org
Subject: Re: Rust <3 Guix
Date: Thu, 28 Dec 2023 09:54:22 +0200	[thread overview]
Message-ID: <ZY0prn1jTDEe02f2@3900XT> (raw)
In-Reply-To: <a4c85946a0aea313bf36f452cb42ea9e909bc709@dismail.de>


[-- Attachment #1.1: Type: text/plain, Size: 1723 bytes --]

On Mon, Dec 25, 2023 at 07:25:26AM +0000, jgart wrote:
> > Do you need both nss-certs and curl?
> 
> Hi Efraim, yes, I need both, oddly enough. If I remove one of them the build fails with the error message in the README that I provided.
> 
> > I saw in a later commit you said it's working.
> 
> I'm able to build main.rs with the guix installed tools but I'm not able to use guix-installed crate dependencies.
> 
> I ended up installing the crates with cargo by fetching them from crates.io with the following invocations:
> 
> cargo fetch
> cargo update
> cargo build
> 
> Not sure at the moment how to get cargo to defer to guix for managing the crates when doing development... WDYT

It's not pretty currently using guix's crates.  The first part, getting
the necessary crates, involves manually adding them (with their
dependencies!) to your environment. The second part involves adjusting
your config.toml to include the following:

[source.crates-io]
local-registry = '/gnu/store/3nfgfhxlciblr360jyrgxl275sf78a6f-profile/share/cargo/registry'

HOWEVER, instead of /gnu/store/...-profile you need to adjust the path
to the value of your GUIX_ENVIRONMENT, and there's no way that I've
figured out to use $GUIX_ENVIRONMENT in a toml file.

Actually, it looks like I have the cargo registry patches sitting
unapplied on my machine, so I'm not even sure if it'll work the way I
wrote above.  I'll see about getting them into a state I'm happy with
for the rust-team branch.

-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #1.2: 0001-build-cargo-build-system-Produce-registry-index-file.patch --]
[-- Type: text/plain, Size: 8648 bytes --]

From 84d2f06e9facec9a1646afd53adcbf2b95da4da0 Mon Sep 17 00:00:00 2001
Message-ID: <84d2f06e9facec9a1646afd53adcbf2b95da4da0.1702565894.git.efraim@flashner.co.il>
In-Reply-To: <cover.1702565894.git.efraim@flashner.co.il>
References: <cover.1702565894.git.efraim@flashner.co.il>
From: Efraim Flashner <efraim@flashner.co.il>
Date: Thu, 14 Dec 2023 16:49:58 +0200
Subject: [PATCH 1/2] build: cargo-build-system: Produce registry index files.

* guix/build/cargo-build-system.scm (rewrite-deps): New procedure.
(package): Obtain output from 'cargo manifest' of the current package
when the package will be installed.
(install): Don't install cargo crates and source.
(install-source): New phase.  Install cargo crates.  Generate cargo
registry index files and install them in a known location.
(%standard-phases): Add 'install-source phase after 'install.

Change-Id: I6ce6c5b33fe3eb7667f86964daef798320724a25
---
 guix/build/cargo-build-system.scm | 102 +++++++++++++++++++++++++-----
 1 file changed, 87 insertions(+), 15 deletions(-)

diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm
index ffb2ec898e..f1e35a5c65 100644
--- a/guix/build/cargo-build-system.scm
+++ b/guix/build/cargo-build-system.scm
@@ -73,6 +73,21 @@ (define (crate-src? path)
                                             " | cut -d/ -f2"
                                             " | grep -q '^Cargo.toml$'")))))
 
+(define (rewrite-deps cargo-deps)
+  (map (lambda (dependency)
+         `(@ ("name" . ,(assoc-ref dependency "name"))
+             ("req" . ,(assoc-ref dependency "req"))
+             ("features" . ,(assoc-ref dependency "features"))
+             ("optional" . ,(assoc-ref dependency "optional"))
+             ("default_features" . ,(assoc-ref dependency
+                                               "uses_default_features"))
+             ("target" . ,(assoc-ref dependency "target"))
+             ("kind" . ,(match (assoc-ref dependency "kind")
+                               (null? "normal")
+                               (kind kind)))
+             ("registry" . ,(assoc-ref dependency "registry"))))
+       cargo-deps))
+
 (define* (unpack-rust-crates #:key inputs vendor-dir #:allow-other-keys)
   (define (inputs->rust-inputs inputs)
     "Filter using the label part from INPUTS."
@@ -271,7 +286,8 @@ (define* (package #:key
                   install-source?
                   (cargo-package-flags '("--no-metadata" "--no-verify"))
                   #:allow-other-keys)
-  "Run 'cargo-package' for a given Cargo package."
+  "Run 'cargo-package' for a given Cargo package.  Also generate metadata so we can
+create a package index for the crates."
   (if install-source?
     (if skip-build?
       (begin
@@ -322,19 +338,24 @@ (define* (package #:key
                 (delete-file-recursively dir)))
             (find-files "." "\\.crate$")))))
     (format #t "Not installing cargo sources, skipping `cargo package`.~%"))
-  #t)
+
+  (when install-source?
+    ;; First generate the metadata so we can create the index file.
+    ;; https://doc.rust-lang.org/cargo/commands/cargo-metadata.html#json-format
+    (with-output-to-file "cargo-metadata.json"
+      (lambda _
+        (invoke "cargo" "metadata"
+                "--manifest-path" "Cargo.toml"
+                "--format-version" "1"
+                "--no-deps")))))
 
 (define* (install #:key
-                  inputs
                   outputs
                   skip-build?
-                  install-source?
                   features
                   #:allow-other-keys)
   "Install a given Cargo package."
-  (let* ((out      (assoc-ref outputs "out"))
-         (registry (string-append out "/share/cargo/registry"))
-         (sources  (string-append out "/share/cargo/src")))
+  (let ((out (assoc-ref outputs "out")))
     (mkdir-p out)
 
     ;; Make cargo reuse all the artifacts we just built instead
@@ -346,21 +367,71 @@ (define* (install #:key
     (or skip-build?
         (not (has-executable-target?))
         (invoke "cargo" "install" "--no-track" "--path" "." "--root" out
-                "--features" (string-join features)))
+                "--features" (string-join features)))))
+
+(define* (install-sources #:key
+                          name
+                          outputs
+                          install-source?
+                          #:allow-other-keys)
+  "Install a given Cargo package."
+  (let* ((out      (assoc-ref outputs "out"))
+         (registry (string-append out "/share/cargo/registry/"))
+         (name+ver (if (string-prefix? "rust-" name)
+                       (string-drop name 5)
+                       name))
+         ;; Strip the version if it exists.
+         (pkgname  (if (char-set-every
+                         (lambda (item)
+                           (char-set-contains?
+                             (list->char-set (list #\- #\.) char-set:digit) item))
+                         (string->char-set
+                           (string-drop name+ver (string-index-right name+ver #\-))))
+                     (string-take name+ver (string-index-right name+ver #\-))
+                     name+ver)))
 
     (when install-source?
       ;; Install crate tarballs and unpacked sources for later use.
-      ;; TODO: Is there a better format/directory for these files?
-      (mkdir-p sources)
       (for-each (lambda (crate)
                   (install-file crate registry))
                 (find-files "target/package" "\\.crate$"))
 
-      (for-each (lambda (crate)
-                  (invoke "tar" "xzf" crate "-C" sources))
-                (find-files registry "\\.crate$")))
+      (let ((path (match (string-length pkgname)
+                         (1 "1")
+                         (2 "2")
+                         (3 (string-append "3/" (string-take pkgname 1)))
+                         (else (string-append (substring pkgname 0 2) "/"
+                                              (substring pkgname 2 4)))))
+            (cargo-metadata (match (call-with-input-file
+                                     "cargo-metadata.json" read-json)
+                                   (('@ . alist) alist)))
+            (sha256sum (read-delimited
+                         " "
+                         (open-pipe* OPEN_READ
+                                     "sha256sum" "--"
+                                     (first (find-files registry pkgname))))))
 
-    #t))
+        ;; Now it's time to generate the actual index file:
+        ;; https://doc.rust-lang.org/cargo/reference/registry-index.html#json-schema
+        (call-with-output-file pkgname
+          (lambda (out)
+            (write-json
+              `(@ ("name" . ,(assoc-ref
+                               (first (assoc-ref cargo-metadata "packages"))
+                               "name"))
+                  ("vers" . ,(assoc-ref
+                               (first (assoc-ref cargo-metadata "packages"))
+                               "version"))
+                  ("deps" . ,(rewrite-deps (assoc-ref
+                               (first (assoc-ref cargo-metadata "packages"))
+                               "dependencies")))
+                  ("cksum" . ,sha256sum)
+                  ("features" . ,(assoc-ref
+                                   (first (assoc-ref cargo-metadata "packages"))
+                                   "features"))
+                  ("yanked" . #f))
+              out)))
+        (install-file pkgname (string-append registry "/index/" path))))))
 
 (define %standard-phases
   (modify-phases gnu:%standard-phases
@@ -372,7 +443,8 @@ (define %standard-phases
     (add-after 'build 'package package)
     (add-after 'unpack 'check-for-pregenerated-files check-for-pregenerated-files)
     (add-after 'check-for-pregenerated-files 'unpack-rust-crates unpack-rust-crates)
-    (add-after 'patch-generated-file-shebangs 'patch-cargo-checksums patch-cargo-checksums)))
+    (add-after 'patch-generated-file-shebangs 'patch-cargo-checksums patch-cargo-checksums)
+    (add-after 'install 'install-sources install-sources)))
 
 (define* (cargo-build #:key inputs (phases %standard-phases)
                       #:allow-other-keys #:rest args)
-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted


[-- Attachment #1.3: 0002-guix-profiles-Add-cargo-registry-profile-hook.patch --]
[-- Type: text/plain, Size: 2913 bytes --]

From 1dca2772f81df7d9a66f7a97668c3f9acca141a8 Mon Sep 17 00:00:00 2001
Message-ID: <1dca2772f81df7d9a66f7a97668c3f9acca141a8.1702565894.git.efraim@flashner.co.il>
In-Reply-To: <cover.1702565894.git.efraim@flashner.co.il>
References: <cover.1702565894.git.efraim@flashner.co.il>
From: Efraim Flashner <efraim@flashner.co.il>
Date: Thu, 14 Dec 2023 16:54:11 +0200
Subject: [PATCH 2/2] guix: profiles: Add cargo-registry profile hook.

* guix/profiles.scm (cargo-registry): New profile-hook.
(%default-profile-hooks): Add cargo-registry.

Change-Id: I8642e116e7ff7df2ae2dde77c98d5cfeed85f99d
---
 guix/profiles.scm | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/guix/profiles.scm b/guix/profiles.scm
index ce2f8337bf..129448b2b1 100644
--- a/guix/profiles.scm
+++ b/guix/profiles.scm
@@ -13,6 +13,7 @@
 ;;; Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
 ;;; Copyright © 2014 David Thompson <davet@gnu.org>
 ;;; Copyright © 2022 Arun Isaac <arunisaac@systemreboot.net>
+;;; Copyright © 2023 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1193,6 +1194,29 @@ (define* (ca-certificate-bundle manifest #:optional system)
                     `((type . profile-hook)
                       (hook . ca-certificate-bundle))))
 
+(define* (cargo-registry manifest #:optional system)
+  (define build
+    (with-imported-modules '((guix build utils))
+      #~(begin
+          (use-modules (guix build utils))
+          (let ((registry (string-append #$output "/share/cargo/registry")))
+            (mkdir-p registry)
+            ;; https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration
+            (with-output-to-file (string-append registry "/config.json")
+              (lambda _
+                (format #t "{~@
+                        \"dl\": \"~a/{crate}-{version}.crate\",~@
+                        }~%"
+                        registry)))))))
+
+  (gexp->derivation "cargo-registry" build
+                    #:system system
+                    #:local-build? #t
+                    #:substitutable? #f
+                    #:properties
+                    `((type . profile-hook)
+                      (hook . cargo-registry))))
+
 (define* (emacs-subdirs manifest #:optional system)
   (define build
     (with-imported-modules (source-module-closure
@@ -1932,6 +1956,7 @@ (define %default-profile-hooks
         fonts-dir-file
         ghc-package-cache-file
         ca-certificate-bundle
+        cargo-registry
         emacs-subdirs
         gdk-pixbuf-loaders-cache-file
         glib-schemas
-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

      reply	other threads:[~2023-12-28  7:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-24 20:35 Rust <3 Guix jgart
2023-12-25  6:35 ` Efraim Flashner
2023-12-25  7:25   ` jgart
2023-12-28  7:54     ` Efraim Flashner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZY0prn1jTDEe02f2@3900XT \
    --to=efraim@flashner.co.il \
    --cc=guix-devel@gnu.org \
    --cc=jgart@dismail.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.