From 36bbbbd150f75c2a6dab2473643c3723e606e41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Fri, 21 Feb 2014 23:03:19 +0100 Subject: derivations: Add support for recursive fixed-output derivations. * guix/derivations.scm (): Add 'recursive?' field. Adjust 'make-derivation-output' callers. (%read-derivation) : When HASH-ALGO starts with 'r:', set the 'recursive?' field and drop 'r:' from the hash algo name. (write-derivation)[write-output]: Write the algo as 'r:HASH-ALGO' when the RECURSIVE? field is set. (derivation-hash) : Prepend "r:" when RECURSIVE? is set. (fixed-output-path): New procedure. (derivation): Add #:recursive? parameter. Use 'fixed-output-path' to compute the output file name of a fixed output derivation. (build-expression->derivation): Add #:recursive? parameter. Pass it to 'derivation'. * tests/derivations.scm ("fixed-output derivation, recursive", "build-expression->derivation produces recursive fixed-output", "build-expression->derivation uses recursive fixed-output"): New tests. * doc/guix.texi (Derivations): Document #:recursive? for 'derivation'. Add #:recursive? for 'build-expression->derivation'. --- guix/derivations.scm | 71 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 18 deletions(-) (limited to 'guix/derivations.scm') diff --git a/guix/derivations.scm b/guix/derivations.scm index cc8e37c973..4f060a6aa2 100644 --- a/guix/derivations.scm +++ b/guix/derivations.scm @@ -47,6 +47,7 @@ derivation-output-path derivation-output-hash-algo derivation-output-hash + derivation-output-recursive? derivation-input? @@ -91,11 +92,12 @@ (file-name derivation-file-name)) ; the .drv file name (define-record-type - (make-derivation-output path hash-algo hash) + (make-derivation-output path hash-algo hash recursive?) derivation-output? (path derivation-output-path) ; store path (hash-algo derivation-output-hash-algo) ; symbol | #f - (hash derivation-output-hash)) ; bytevector | #f + (hash derivation-output-hash) ; bytevector | #f + (recursive? derivation-output-recursive?)) ; Boolean (define-record-type (make-derivation-input path sub-derivations) @@ -241,14 +243,19 @@ that second value is the empty list." (match output ((name path "" "") (alist-cons name - (make-derivation-output path #f #f) + (make-derivation-output path #f #f #f) result)) ((name path hash-algo hash) ;; fixed-output - (let ((algo (string->symbol hash-algo)) - (hash (base16-string->bytevector hash))) + (let* ((rec? (string-prefix? "r:" hash-algo)) + (algo (string->symbol + (if rec? + (string-drop hash-algo 2) + hash-algo))) + (hash (base16-string->bytevector hash))) (alist-cons name - (make-derivation-output path algo hash) + (make-derivation-output path algo + hash rec?) result))))) '() x)) @@ -368,9 +375,12 @@ that form." (define (write-output output port) (match output - ((name . ($ path hash-algo hash)) + ((name . ($ path hash-algo hash recursive?)) (write-tuple (list name path - (or (and=> hash-algo symbol->string) "") + (if hash-algo + (string-append (if recursive? "r:" "") + (symbol->string hash-algo)) + "") (or (and=> hash bytevector->base16-string) "")) write @@ -476,11 +486,14 @@ in SIZE bytes." "Return the hash of DRV, modulo its fixed-output inputs, as a bytevector." (match drv (($ ((_ . ($ path - (? symbol? hash-algo) (? bytevector? hash))))) + (? symbol? hash-algo) (? bytevector? hash) + (? boolean? recursive?))))) ;; A fixed-output derivation. (sha256 (string->utf8 - (string-append "fixed:out:" (symbol->string hash-algo) + (string-append "fixed:out:" + (if recursive? "r:" "") + (symbol->string hash-algo) ":" (bytevector->base16-string hash) ":" path)))) (($ outputs inputs sources @@ -527,17 +540,33 @@ the derivation called NAME with hash HASH." name (string-append name "-" output)))) +(define (fixed-output-path output hash-algo hash recursive? name) + "Return an output path for the fixed output OUTPUT defined by HASH of type +HASH-ALGO, of the derivation NAME. RECURSIVE? has the same meaning as for +'add-to-store'." + (if (and recursive? (eq? hash-algo 'sha256)) + (store-path "source" hash name) + (let ((tag (string-append "fixed:" output ":" + (if recursive? "r:" "") + (symbol->string hash-algo) ":" + (bytevector->base16-string hash) ":"))) + (store-path (string-append "output:" output) + (sha256 (string->utf8 tag)) + name)))) + (define* (derivation store name builder args #:key (system (%current-system)) (env-vars '()) (inputs '()) (outputs '("out")) - hash hash-algo hash-mode + hash hash-algo hash-mode recursive? references-graphs local-build?) "Build a derivation with the given arguments, and return the resulting object. When HASH, HASH-ALGO, and HASH-MODE are given, a fixed-output derivation is created---i.e., one whose result is known in -advance, such as a file download. +advance, such as a file download. If, in addition, RECURSIVE? is true, then +that fixed output may be an executable file or a directory and HASH must be +the hash of an archive containing this output. When REFERENCES-GRAPHS is true, it must be a list of file name/store path pairs. In that case, the reference graph of each store path is exported in @@ -555,12 +584,16 @@ derivations where the costs of data transfers would outweigh the benefits." (let* ((drv-hash (derivation-hash drv)) (outputs (map (match-lambda ((output-name . ($ - _ algo hash)) - (let ((path (output-path output-name - drv-hash name))) + _ algo hash rec?)) + (let ((path (if hash + (fixed-output-path output-name + algo hash + rec? name) + (output-path output-name + drv-hash name)))) (cons output-name (make-derivation-output path algo - hash))))) + hash rec?))))) outputs))) (make-derivation outputs inputs sources system builder args (map (match-lambda @@ -618,7 +651,8 @@ derivations where the costs of data transfers would outweigh the benefits." (let* ((outputs (map (lambda (name) ;; Return outputs with an empty path. (cons name - (make-derivation-output "" hash-algo hash))) + (make-derivation-output "" hash-algo + hash recursive?))) outputs)) (inputs (map (match-lambda (((? derivation? drv)) @@ -909,7 +943,7 @@ they can refer to each other." (system (%current-system)) (inputs '()) (outputs '("out")) - hash hash-algo + hash hash-algo recursive? (env-vars '()) (modules '()) guile-for-build @@ -1056,6 +1090,7 @@ LOCAL-BUILD?." env-vars) #:hash hash #:hash-algo hash-algo + #:recursive? recursive? #:outputs outputs #:references-graphs references-graphs #:local-build? local-build?))) -- cgit v1.2.3 From 2096ef47aad57a9988c8fdfaa46a70770a0e0b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Fri, 21 Feb 2014 23:48:56 +0100 Subject: derivations: Remove unused 'derivation' parameter. * guix/derivations.scm (derivation): Remove unused #:hash-mode parameter. * doc/guix.texi (Derivations): Adjust accordingly. --- guix/derivations.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'guix/derivations.scm') diff --git a/guix/derivations.scm b/guix/derivations.scm index 4f060a6aa2..82a0173232 100644 --- a/guix/derivations.scm +++ b/guix/derivations.scm @@ -558,11 +558,11 @@ HASH-ALGO, of the derivation NAME. RECURSIVE? has the same meaning as for #:key (system (%current-system)) (env-vars '()) (inputs '()) (outputs '("out")) - hash hash-algo hash-mode recursive? + hash hash-algo recursive? references-graphs local-build?) "Build a derivation with the given arguments, and return the resulting - object. When HASH, HASH-ALGO, and HASH-MODE are given, a + object. When HASH and HASH-ALGO are given, a fixed-output derivation is created---i.e., one whose result is known in advance, such as a file download. If, in addition, RECURSIVE? is true, then that fixed output may be an executable file or a directory and HASH must be -- cgit v1.2.3