summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2013-08-26 22:12:46 +0200
committerLudovic Courtès <ludo@gnu.org>2013-08-26 22:20:53 +0200
commit5b0c9d1635df1608a498db8718af575d2f0e1663 (patch)
treec4e38d7d3b566507b8d966971b780705506fabb8
parenta987d2c02525efd1bf37b4bb5b5df405a06bd15c (diff)
derivations: Add #:dependency-graphs `derivation' parameter.
* guix/derivations.scm (derivation): Add `dependency-graphs' keyword parameter; honor it. * tests/derivations.scm (bootstrap-binary): New procedure. (%bash): Use it. (%mkdir): New variable. (directory-contents): Add `slurp' optional parameter. ("derivation with #:dependency-graphs"): New test. * doc/guix.texi (Derivations): Update accordingly.
-rw-r--r--doc/guix.texi7
-rw-r--r--guix/derivations.scm28
-rw-r--r--tests/derivations.scm68
3 files changed, 91 insertions, 12 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index c82d5f7480d..86912ecabf8 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -1113,13 +1113,18 @@ derivations as Scheme objects, along with procedures to create and
1113otherwise manipulate derivations. The lowest-level primitive to create 1113otherwise manipulate derivations. The lowest-level primitive to create
1114a derivation is the @code{derivation} procedure: 1114a derivation is the @code{derivation} procedure:
1115 1115
1116@deffn {Scheme Procedure} derivation @var{store} @var{name} @var{builder} @var{args} [#:outputs '("out")] [#:hash #f] [#:hash-algo #f] [#:hash-mode #f] [#:inputs '()] [#:env-vars '()] [#:system (%current-system)] 1116@deffn {Scheme Procedure} derivation @var{store} @var{name} @var{builder} @var{args} [#:outputs '("out")] [#:hash #f] [#:hash-algo #f] [#:hash-mode #f] [#:inputs '()] [#:env-vars '()] [#:system (%current-system)] [#:dependency-graphs #f]
1117Build a derivation with the given arguments. Return the resulting store 1117Build a derivation with the given arguments. Return the resulting store
1118path and @code{<derivation>} object. 1118path and @code{<derivation>} object.
1119 1119
1120When @var{hash}, @var{hash-algo}, and @var{hash-mode} are given, a 1120When @var{hash}, @var{hash-algo}, and @var{hash-mode} are given, a
1121@dfn{fixed-output derivation} is created---i.e., one whose result is 1121@dfn{fixed-output derivation} is created---i.e., one whose result is
1122known in advance, such as a file download. 1122known in advance, such as a file download.
1123
1124When @var{dependency-graphs} is true, it must be a list of file
1125name/store path pairs. In that case, the reference graph of each store
1126path is exported in the build environment in the corresponding file, in
1127a simple text format.
1123@end deffn 1128@end deffn
1124 1129
1125@noindent 1130@noindent
diff --git a/guix/derivations.scm b/guix/derivations.scm
index 3d7a30aaa8b..fea99843705 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -501,11 +501,16 @@ the derivation called NAME with hash HASH."
501 #:key 501 #:key
502 (system (%current-system)) (env-vars '()) 502 (system (%current-system)) (env-vars '())
503 (inputs '()) (outputs '("out")) 503 (inputs '()) (outputs '("out"))
504 hash hash-algo hash-mode) 504 hash hash-algo hash-mode
505 dependency-graphs)
505 "Build a derivation with the given arguments. Return the resulting 506 "Build a derivation with the given arguments. Return the resulting
506store path and <derivation> object. When HASH, HASH-ALGO, and HASH-MODE 507store path and <derivation> object. When HASH, HASH-ALGO, and HASH-MODE
507are given, a fixed-output derivation is created---i.e., one whose result is 508are given, a fixed-output derivation is created---i.e., one whose result is
508known in advance, such as a file download." 509known in advance, such as a file download.
510
511When DEPENDENCY-GRAPHS is true, it must be a list of file name/store path
512pairs. In that case, the reference graph of each store path is exported in
513the build environment in the corresponding file, in a simple text format."
509 (define direct-store-path? 514 (define direct-store-path?
510 (let ((len (+ 1 (string-length (%store-prefix))))) 515 (let ((len (+ 1 (string-length (%store-prefix)))))
511 (lambda (p) 516 (lambda (p)
@@ -540,7 +545,22 @@ known in advance, such as a file download."
540 value)))) 545 value))))
541 env-vars)))))) 546 env-vars))))))
542 547
543 (define (env-vars-with-empty-outputs) 548 (define (user+system-env-vars)
549 ;; Some options are passed to the build daemon via the env. vars of
550 ;; derivations (urgh!). We hide that from our API, but here is the place
551 ;; where we kludgify those options.
552 (match dependency-graphs
553 (((file . path) ...)
554 (let ((value (map (cut string-append <> " " <>)
555 file path)))
556 ;; XXX: This all breaks down if an element of FILE or PATH contains
557 ;; white space.
558 `(("exportReferencesGraph" . ,(string-join value " "))
559 ,@env-vars)))
560 (#f
561 env-vars)))
562
563 (define (env-vars-with-empty-outputs env-vars)
544 ;; Return a variant of ENV-VARS where each OUTPUTS is associated with an 564 ;; Return a variant of ENV-VARS where each OUTPUTS is associated with an
545 ;; empty string, even outputs that do not appear in ENV-VARS. 565 ;; empty string, even outputs that do not appear in ENV-VARS.
546 (let ((e (map (match-lambda 566 (let ((e (map (match-lambda
@@ -572,7 +592,7 @@ known in advance, such as a file download."
572 #t "sha256" input))) 592 #t "sha256" input)))
573 (make-derivation-input path '())))) 593 (make-derivation-input path '()))))
574 (delete-duplicates inputs))) 594 (delete-duplicates inputs)))
575 (env-vars (env-vars-with-empty-outputs)) 595 (env-vars (env-vars-with-empty-outputs (user+system-env-vars)))
576 (drv-masked (make-derivation outputs 596 (drv-masked (make-derivation outputs
577 (filter (compose derivation-path? 597 (filter (compose derivation-path?
578 derivation-input-path) 598 derivation-input-path)
diff --git a/tests/derivations.scm b/tests/derivations.scm
index 9833e151126..9b3d92a7bf7 100644
--- a/tests/derivations.scm
+++ b/tests/derivations.scm
@@ -50,19 +50,23 @@
50 (let ((drv (package-derivation %store %bootstrap-guile))) 50 (let ((drv (package-derivation %store %bootstrap-guile)))
51 (%guile-for-build drv))) 51 (%guile-for-build drv)))
52 52
53(define %bash 53(define (bootstrap-binary name)
54 (let ((bash (search-bootstrap-binary "bash" (%current-system)))) 54 (let ((bin (search-bootstrap-binary name (%current-system))))
55 (and %store 55 (and %store
56 (add-to-store %store "bash" #t "sha256" bash)))) 56 (add-to-store %store name #t "sha256" bin))))
57
58(define %bash
59 (bootstrap-binary "bash"))
60(define %mkdir
61 (bootstrap-binary "mkdir"))
57 62
58(define (directory-contents dir) 63(define* (directory-contents dir #:optional (slurp get-bytevector-all))
59 "Return an alist representing the contents of DIR." 64 "Return an alist representing the contents of DIR."
60 (define prefix-len (string-length dir)) 65 (define prefix-len (string-length dir))
61 (sort (file-system-fold (const #t) ; enter? 66 (sort (file-system-fold (const #t) ; enter?
62 (lambda (path stat result) ; leaf 67 (lambda (path stat result) ; leaf
63 (alist-cons (string-drop path prefix-len) 68 (alist-cons (string-drop path prefix-len)
64 (call-with-input-file path 69 (call-with-input-file path slurp)
65 get-bytevector-all)
66 result)) 70 result))
67 (lambda (path stat result) result) ; down 71 (lambda (path stat result) result) ; down
68 (lambda (path stat result) result) ; up 72 (lambda (path stat result) result) ; up
@@ -84,7 +88,7 @@
84 (and (equal? b1 b2) 88 (and (equal? b1 b2)
85 (equal? d1 d2)))) 89 (equal? d1 d2))))
86 90
87(test-skip (if %store 0 11)) 91(test-skip (if %store 0 12))
88 92
89(test-assert "add-to-store, flat" 93(test-assert "add-to-store, flat"
90 (let* ((file (search-path %load-path "language/tree-il/spec.scm")) 94 (let* ((file (search-path %load-path "language/tree-il/spec.scm"))
@@ -292,6 +296,56 @@
292 (and (valid-path? %store p) 296 (and (valid-path? %store p)
293 (equal? '(one two) (call-with-input-file p read))))))) 297 (equal? '(one two) (call-with-input-file p read)))))))
294 298
299(test-assert "derivation with #:dependency-graphs"
300 (let* ((input1 (add-text-to-store %store "foo" "hello"
301 (list %bash)))
302 (input2 (add-text-to-store %store "bar"
303 (number->string (random 7777))
304 (list input1)))
305 (builder (add-text-to-store %store "build-graph"
306 (format #f "
307~a $out
308 (while read l ; do echo $l ; done) < bash > $out/bash
309 (while read l ; do echo $l ; done) < input1 > $out/input1
310 (while read l ; do echo $l ; done) < input2 > $out/input2"
311 %mkdir)
312 (list %mkdir)))
313 (drv (derivation %store "closure-graphs"
314 %bash `(,builder)
315 #:dependency-graphs
316 `(("bash" . ,%bash)
317 ("input1" . ,input1)
318 ("input2" . ,input2))
319 #:inputs `((,%bash) (,builder))))
320 (out (derivation-path->output-path drv)))
321 (define (deps path . deps)
322 (let ((count (length deps)))
323 (string-append path "\n\n" (number->string count) "\n"
324 (string-join (sort deps string<?) "\n")
325 (if (zero? count) "" "\n"))))
326
327 (and (build-derivations %store (list drv))
328 (equal? (directory-contents out get-string-all)
329 `(("/bash" . ,(string-append %bash "\n\n0\n"))
330 ("/input1" . ,(if (string>? input1 %bash)
331 (string-append (deps %bash)
332 (deps input1 %bash))
333 (string-append (deps input1 %bash)
334 (deps %bash))))
335 ("/input2" . ,(string-concatenate
336 (map cdr
337 (sort
338 (map (lambda (p d)
339 (cons p (apply deps p d)))
340 (list %bash input1 input2)
341 (list '() (list %bash) (list input1)))
342 (lambda (x y)
343 (match x
344 ((p1 . _)
345 (match y
346 ((p2 . _)
347 (string<? p1 p2)))))))))))))))
348
295 349
296(define %coreutils 350(define %coreutils
297 (false-if-exception 351 (false-if-exception