summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2020-06-11 18:24:59 +0200
committerLudovic Courtès <ludo@gnu.org>2020-06-11 19:05:05 +0200
commit03a70e4c190420e87c0b535285caf8f77260d4ff (patch)
treedbf3f3952af4990b959e048b1ae2766c1fc83ffa
parentcbd9581acc41cd49eb81c2432452cad4de805cbd (diff)
packages: 'package-grafts' returns grafts for all the relevant outputs.
Fixes <https://bugs.gnu.org/41796>. Reported by Jakub Kądziołka <kuba@kadziolka.net>. * guix/packages.scm (input-graft): Add 'output' parameter and honor it. Add OUTPUT to the cache key. (input-cross-graft): Likewise. (fold-bag-dependencies): Operate on inputs instead of nodes. Turn VISITED into a vhash instead of a set. Pass PROC HEAD and OUTPUT instead of just HEAD. (bag-grafts): Adjust accordingly. * tests/packages.scm ("package-grafts, dependency on several outputs"): New test.
-rw-r--r--guix/packages.scm81
-rw-r--r--tests/packages.scm24
2 files changed, 62 insertions, 43 deletions
diff --git a/guix/packages.scm b/guix/packages.scm
index 0ccd31a7a91..1e0ec41b764 100644
--- a/guix/packages.scm
+++ b/guix/packages.scm
@@ -1194,39 +1194,39 @@ and return it."
1194 (make-weak-key-hash-table 200)) 1194 (make-weak-key-hash-table 200))
1195 1195
1196(define (input-graft store system) 1196(define (input-graft store system)
1197 "Return a procedure that, given a package with a graft, returns a graft, and 1197 "Return a procedure that, given a package with a replacement and an output name,
1198#f otherwise." 1198returns a graft, and #f otherwise."
1199 (match-lambda 1199 (match-lambda*
1200 ((? package? package) 1200 (((? package? package) output)
1201 (let ((replacement (package-replacement package))) 1201 (let ((replacement (package-replacement package)))
1202 (and replacement 1202 (and replacement
1203 (cached (=> %graft-cache) package system 1203 (cached (=> %graft-cache) package (cons output system)
1204 (let ((orig (package-derivation store package system 1204 (let ((orig (package-derivation store package system
1205 #:graft? #f)) 1205 #:graft? #f))
1206 (new (package-derivation store replacement system 1206 (new (package-derivation store replacement system
1207 #:graft? #t))) 1207 #:graft? #t)))
1208 (graft 1208 (graft
1209 (origin orig) 1209 (origin orig)
1210 (replacement new))))))) 1210 (origin-output output)
1211 (x 1211 (replacement new)
1212 #f))) 1212 (replacement-output output)))))))))
1213 1213
1214(define (input-cross-graft store target system) 1214(define (input-cross-graft store target system)
1215 "Same as 'input-graft', but for cross-compilation inputs." 1215 "Same as 'input-graft', but for cross-compilation inputs."
1216 (match-lambda 1216 (match-lambda*
1217 ((? package? package) 1217 (((? package? package) output)
1218 (let ((replacement (package-replacement package))) 1218 (let ((replacement (package-replacement package)))
1219 (and replacement 1219 (and replacement
1220 (let ((orig (package-cross-derivation store package target system 1220 (let ((orig (package-cross-derivation store package target system
1221 #:graft? #f)) 1221 #:graft? #f))
1222 (new (package-cross-derivation store replacement 1222 (new (package-cross-derivation store replacement
1223 target system 1223 target system
1224 #:graft? #t))) 1224 #:graft? #t)))
1225 (graft 1225 (graft
1226 (origin orig) 1226 (origin orig)
1227 (replacement new)))))) 1227 (origin-output output)
1228 (_ 1228 (replacement new)
1229 #f))) 1229 (replacement-output output))))))))
1230 1230
1231(define* (fold-bag-dependencies proc seed bag 1231(define* (fold-bag-dependencies proc seed bag
1232 #:key (native? #t)) 1232 #:key (native? #t))
@@ -1243,26 +1243,21 @@ dependencies; otherwise, restrict to target dependencies."
1243 (bag-host-inputs bag)))) 1243 (bag-host-inputs bag))))
1244 bag-host-inputs)) 1244 bag-host-inputs))
1245 1245
1246 (define nodes 1246 (let loop ((inputs (bag-direct-inputs* bag))
1247 (match (bag-direct-inputs* bag)
1248 (((labels things _ ...) ...)
1249 things)))
1250
1251 (let loop ((nodes nodes)
1252 (result seed) 1247 (result seed)
1253 (visited (setq))) 1248 (visited vlist-null))
1254 (match nodes 1249 (match inputs
1255 (() 1250 (()
1256 result) 1251 result)
1257 (((? package? head) . tail) 1252 (((label (? package? head) . rest) . tail)
1258 (if (set-contains? visited head) 1253 (let ((output (match rest (() "out") ((output) output)))
1259 (loop tail result visited) 1254 (outputs (vhash-foldq* cons '() head visited)))
1260 (let ((inputs (bag-direct-inputs* (package->bag head)))) 1255 (if (member output outputs)
1261 (loop (match inputs 1256 (loop tail result visited)
1262 (((labels things _ ...) ...) 1257 (let ((inputs (bag-direct-inputs* (package->bag head))))
1263 (append things tail))) 1258 (loop (append inputs tail)
1264 (proc head result) 1259 (proc head output result)
1265 (set-insert head visited))))) 1260 (vhash-consq head output visited))))))
1266 ((head . tail) 1261 ((head . tail)
1267 (loop tail result visited))))) 1262 (loop tail result visited)))))
1268 1263
@@ -1279,8 +1274,8 @@ to (see 'graft-derivation'.)"
1279 (let ((->graft (input-graft store system))) 1274 (let ((->graft (input-graft store system)))
1280 (parameterize ((%current-system system) 1275 (parameterize ((%current-system system)
1281 (%current-target-system #f)) 1276 (%current-target-system #f))
1282 (fold-bag-dependencies (lambda (package grafts) 1277 (fold-bag-dependencies (lambda (package output grafts)
1283 (match (->graft package) 1278 (match (->graft package output)
1284 (#f grafts) 1279 (#f grafts)
1285 (graft (cons graft grafts)))) 1280 (graft (cons graft grafts))))
1286 '() 1281 '()
@@ -1291,8 +1286,8 @@ to (see 'graft-derivation'.)"
1291 (let ((->graft (input-cross-graft store target system))) 1286 (let ((->graft (input-cross-graft store target system)))
1292 (parameterize ((%current-system system) 1287 (parameterize ((%current-system system)
1293 (%current-target-system target)) 1288 (%current-target-system target))
1294 (fold-bag-dependencies (lambda (package grafts) 1289 (fold-bag-dependencies (lambda (package output grafts)
1295 (match (->graft package) 1290 (match (->graft package output)
1296 (#f grafts) 1291 (#f grafts)
1297 (graft (cons graft grafts)))) 1292 (graft (cons graft grafts))))
1298 '() 1293 '()
diff --git a/tests/packages.scm b/tests/packages.scm
index 72e87dbfb7d..c7b6f669b5e 100644
--- a/tests/packages.scm
+++ b/tests/packages.scm
@@ -900,6 +900,30 @@
900 (replacement #f)))) 900 (replacement #f))))
901 (replacement (package-derivation %store new))))))) 901 (replacement (package-derivation %store new)))))))
902 902
903(test-assert "package-grafts, dependency on several outputs"
904 ;; Make sure we get one graft per output; see <https://bugs.gnu.org/41796>.
905 (letrec* ((p0 (dummy-package "p0"
906 (version "1.0")
907 (replacement p0*)
908 (arguments '(#:implicit-inputs? #f))
909 (outputs '("out" "lib"))))
910 (p0* (package (inherit p0) (version "1.1")))
911 (p1 (dummy-package "p1"
912 (arguments '(#:implicit-inputs? #f))
913 (inputs `(("p0" ,p0)
914 ("p0:lib" ,p0 "lib"))))))
915 (lset= equal? (pk (package-grafts %store p1))
916 (list (graft
917 (origin (package-derivation %store p0))
918 (origin-output "out")
919 (replacement (package-derivation %store p0*))
920 (replacement-output "out"))
921 (graft
922 (origin (package-derivation %store p0))
923 (origin-output "lib")
924 (replacement (package-derivation %store p0*))
925 (replacement-output "lib"))))))
926
903(test-assert "replacement also grafted" 927(test-assert "replacement also grafted"
904 ;; We build a DAG as below, where dotted arrows represent replacements and 928 ;; We build a DAG as below, where dotted arrows represent replacements and
905 ;; solid arrows represent dependencies: 929 ;; solid arrows represent dependencies: