GNU bug report logs - #70895
[PATCH] grafts: Only compute necessary graft derivations.

Previous Next

Package: guix-patches;

Reported by: David Elsing <david.elsing <at> posteo.net>

Date: Sun, 12 May 2024 13:44:02 UTC

Severity: normal

Tags: patch

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


Message #34 received at 70895 <at> debbugs.gnu.org (full text, mbox):

From: David Elsing <david.elsing <at> posteo.net>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 70895 <at> debbugs.gnu.org
Subject: Re: [bug#70895] [PATCH] grafts: Only compute necessary graft
 derivations.
Date: Tue, 21 Jan 2025 21:11:22 +0000
[Message part 1 (text/plain, inline)]
Hi Ludo',

Ludovic Courtès <ludo <at> gnu.org> writes:

> Oh, got it.  Yes, we could keep a <package> in the ‘replacement’ field
> instead of explicitly calling ‘package->derivation’.  It’s much simpler,
> that’s a good idea.

Oh nice, that's really neat! I didn't know about <parameterized>, that
achieves exactly what I was hoping for.

> I gave it a try, see patch attached.  Let me know what you think!

Is there a reason you use 'with-parameters' in 'graft-derivation/shallow'
and not in 'input-graft' and 'input-cross-graft'? I attached a patch
below where I do that and also set %current-system and
%current-target-system (although I'm not sure they are strictly
necessary because of the 'parameterize' in 'bag-grafts').
Then, the changes to the gexp-compiler of <parameterized> are not
required to allow for strings in the 'replacement' field in
tests/grafts.scm and the tests still pass.

Cheers,
David

[grafts.patch (text/x-patch, inline)]
diff --git a/guix/grafts.scm b/guix/grafts.scm
index 7636df9267..e93a5e60bb 100644
--- a/guix/grafts.scm
+++ b/guix/grafts.scm
@@ -275,20 +275,6 @@ (define (dependency-grafts items)
                                       #:system system)))))
           (reference-origins drv items)))
 
-  ;; If the 'replacement' field of the <graft> record is a procedure,
-  ;; this means that it is a value in the store monad and the actual
-  ;; derivation needs to be computed here.
-  (define (finalize-graft item)
-    (let ((replacement (graft-replacement item)))
-      (if (procedure? replacement)
-          (graft
-            (inherit item)
-            (replacement
-             (run-with-store store replacement
-                             #:guile-for-build guile
-                             #:system system)))
-          item)))
-
   (with-cache (list (derivation-file-name drv) outputs grafts)
     (match (non-self-references store drv outputs)
       (()                                         ;no dependencies
@@ -305,8 +291,7 @@ (define (finalize-graft item)
               ;; Use APPLICABLE, the subset of GRAFTS that is really
               ;; applicable to DRV, to avoid creating several identical
               ;; grafted variants of DRV.
-              (let* ((new    (graft-derivation/shallow* store drv
-                                                        (map finalize-graft applicable)
+              (let* ((new    (graft-derivation/shallow* store drv applicable
                                                         #:outputs outputs
                                                         #:guile guile
                                                         #:system system))
diff --git a/guix/packages.scm b/guix/packages.scm
index d266805ba8..c9e441ffeb 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -1817,16 +1817,19 @@ (define (input-graft system)
        (let ((replacement (package-replacement package)))
          (if replacement
              (mcached eq? (=> %package-graft-cache)
-                      (mlet %store-monad ((orig (package->derivation package system
-                                                                     #:graft? #f))
-                                          (new -> (package->derivation replacement system
-                                                                       #:graft? #t)))
-                        ;; Keep NEW as a monadic value so that its computation
-                        ;; is delayed until necessary.
+                      (mlet %store-monad
+                          ((orig (package->derivation package system
+                                                      #:graft? #f))
+                           ;; Do not compute the derivation of REPLACEMENT
+                           ;; yet, as it might not be needed.
+                           (replacement -> (with-parameters
+                                               ((%graft? #t)
+                                                (%current-system system))
+                                             replacement)))
                         (return (graft
                                   (origin orig)
                                   (origin-output output)
-                                  (replacement new)
+                                  (replacement replacement)
                                   (replacement-output output))))
                       package output system)
              (return #f))))
@@ -1840,18 +1843,21 @@ (define (input-cross-graft target system)
       (((? package? package) output)
        (let ((replacement (package-replacement package)))
          (if replacement
-             (mlet %store-monad ((orig (package->cross-derivation package
-                                                                  target system
-                                                                  #:graft? #f))
-                                 (new -> (package->cross-derivation replacement
-                                                                    target system
-                                                                    #:graft? #t)))
-               ;; Keep NEW as a monadic value so that its computation
-               ;; is delayed until necessary.
+             (mlet %store-monad
+                 ((orig (package->cross-derivation package
+                                                   target system
+                                                   #:graft? #f))
+                  ;; Do not compuate the derivation of REPLACEMENT
+                  ;; yet, as it might not be needed.
+                  (replacement -> (with-parameters
+                                      ((%graft? #t)
+                                       (%current-system system)
+                                       (%current-target-system target))
+                                    replacement)))
                (return (graft
                          (origin orig)
                          (origin-output output)
-                         (replacement new)
+                         (replacement replacement)
                          (replacement-output output))))
              (return #f))))
       (_
diff --git a/tests/packages.scm b/tests/packages.scm
index a4a0e2c3e8..2863fb5991 100644
--- a/tests/packages.scm
+++ b/tests/packages.scm
@@ -1095,9 +1095,7 @@ (define right-system?
       ((graft)
        (and (eq? (graft-origin graft)
                  (package-derivation %store dep))
-            (eq? (run-with-store %store
-                   (graft-replacement graft))
-                 (package-derivation %store new)))))))
+            (eq? (graft-replacement graft) new))))))
 
 ;; XXX: This test would require building the cross toolchain just to see if it
 ;; needs grafting, which is obviously too expensive, and thus disabled.
@@ -1134,9 +1132,7 @@ (define right-system?
       ((graft)
        (and (eq? (graft-origin graft)
                  (package-derivation %store dep))
-            (eq? (run-with-store %store
-                   (graft-replacement graft))
-                 (package-derivation %store new)))))))
+            (eq? (graft-replacement graft) new))))))
 
 (test-assert "package-grafts, same replacement twice"
   (let* ((new  (dummy-package "dep"
@@ -1161,9 +1157,7 @@ (define right-system?
                  (package-derivation %store
                                      (package (inherit dep)
                                               (replacement #f))))
-            (eq? (run-with-store %store
-                   (graft-replacement graft))
-                 (package-derivation %store new)))))))
+            (eq? (graft-replacement graft) new))))))
 
 (test-assert "package-grafts, dependency on several outputs"
   ;; Make sure we get one graft per output; see <https://bugs.gnu.org/41796>.
@@ -1183,9 +1177,9 @@ (define right-system?
       ((graft1 graft2)
        (and (eq? (graft-origin graft1) (graft-origin graft2)
                  (package-derivation %store p0))
-            (eq? (run-with-store %store (graft-replacement graft1))
-                 (run-with-store %store (graft-replacement graft2))
-                 (package-derivation %store p0*))
+            (eq? (graft-replacement graft1)
+                 (graft-replacement graft2)
+                 p0*)
             (string=? "lib"
                       (graft-origin-output graft1)
                       (graft-replacement-output graft1))
@@ -1262,14 +1256,10 @@ (define right-system?
       ((graft1 graft2)
        (and (eq? (graft-origin graft1)
                  (package-derivation %store p1 #:graft? #f))
-            (eq? (run-with-store %store
-                   (graft-replacement graft1))
-                 (package-derivation %store p1r))
+            (eq? (graft-replacement graft1) p1r)
             (eq? (graft-origin graft2)
                  (package-derivation %store p2 #:graft? #f))
-            (eq? (run-with-store %store
-                   (graft-replacement graft2))
-                 (package-derivation %store p2r #:graft? #t)))))))
+            (eq? (graft-replacement graft2) p2r))))))
 
 ;;; XXX: Nowadays 'graft-derivation' needs to build derivations beforehand to
 ;;; find out about their run-time dependencies, so this test is no longer

This bug report was last modified 107 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.