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   <efr...@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
From 84d2f06e9facec9a1646afd53adcbf2b95da4da0 Mon Sep 17 00:00:00 2001
Message-ID: 
<84d2f06e9facec9a1646afd53adcbf2b95da4da0.1702565894.git.efr...@flashner.co.il>
In-Reply-To: <cover.1702565894.git.efr...@flashner.co.il>
References: <cover.1702565894.git.efr...@flashner.co.il>
From: Efraim Flashner <efr...@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   <efr...@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

From 1dca2772f81df7d9a66f7a97668c3f9acca141a8 Mon Sep 17 00:00:00 2001
Message-ID: 
<1dca2772f81df7d9a66f7a97668c3f9acca141a8.1702565894.git.efr...@flashner.co.il>
In-Reply-To: <cover.1702565894.git.efr...@flashner.co.il>
References: <cover.1702565894.git.efr...@flashner.co.il>
From: Efraim Flashner <efr...@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 <dan...@scratchpost.org>
 ;;; Copyright © 2014 David Thompson <da...@gnu.org>
 ;;; Copyright © 2022 Arun Isaac <arunis...@systemreboot.net>
+;;; Copyright © 2023 Efraim Flashner <efr...@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   <efr...@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: signature.asc
Description: PGP signature

Reply via email to