derivations: build-expression->derivation: Builder only refers to sources.

* guix/derivations.scm (build-expression->derivation)[source-path]: New
  procedure.
  [builder]: Pass only sources as references.  This fixes a bug whereby
  changing a fixed-output drv referred to by a builder would cause the
  builder's hash to change, thereby leading to a full rebuild.
* tests/derivations.scm ("build-expression->derivation with a
  fixed-output input"): New test.
This commit is contained in:
Ludovic Courtès 2012-11-09 00:07:10 +01:00
parent 813986ac09
commit 7bdd1f0e3c
2 changed files with 54 additions and 1 deletions

View File

@ -595,6 +595,14 @@ omitted or is #f, the value of the `%guile-for-build' fluid is used instead."
(((or 'define-module 'use-modules) _ ...) #t) (((or 'define-module 'use-modules) _ ...) #t)
(_ #f))) (_ #f)))
(define source-path
;; When passed an input that is a source, return its path; otherwise
;; return #f.
(match-lambda
((_ path _ ...)
(and (not (derivation-path? path))
path))))
(let* ((prologue `(begin (let* ((prologue `(begin
,@(match exp ,@(match exp
((_ ...) ((_ ...)
@ -639,7 +647,18 @@ omitted or is #f, the value of the `%guile-for-build' fluid is used instead."
((_ ...) ((_ ...)
(remove module-form? exp)) (remove module-form? exp))
(_ `(,exp)))))) (_ `(,exp))))))
(map second inputs)))
;; The references don't really matter
;; since the builder is always used in
;; conjunction with the drv that needs
;; it. For clarity, we add references
;; to the subset of INPUTS that are
;; sources, avoiding references to other
;; .drv; otherwise, BUILDER's hash would
;; depend on those, even if they are
;; fixed-output.
(filter-map source-path inputs)))
(mod-drv (and (pair? modules) (mod-drv (and (pair? modules)
(imported-modules store modules (imported-modules store modules
#:guile guile-drv #:guile guile-drv

View File

@ -459,6 +459,40 @@
(string=? (derivation-path->output-path input1) (string=? (derivation-path->output-path input1)
(derivation-path->output-path input2))))) (derivation-path->output-path input2)))))
(test-assert "build-expression->derivation with a fixed-output input"
(let* ((builder1 '(call-with-output-file %output
(lambda (p)
(write "hello" p))))
(builder2 '(call-with-output-file (pk 'difference-here! %output)
(lambda (p)
(write "hello" p))))
(hash (sha256 (string->utf8 "hello")))
(input1 (build-expression->derivation %store "fixed"
(%current-system)
builder1 '()
#:hash hash
#:hash-algo 'sha256))
(input2 (build-expression->derivation %store "fixed"
(%current-system)
builder2 '()
#:hash hash
#:hash-algo 'sha256))
(builder3 '(let ((input (assoc-ref %build-inputs "input")))
(call-with-output-file %output
(lambda (out)
(format #f "My input is ~a.~%" input)))))
(final1 (build-expression->derivation %store "final"
(%current-system)
builder3
`(("input" ,input1))))
(final2 (build-expression->derivation %store "final"
(%current-system)
builder3
`(("input" ,input2)))))
(and (string=? (derivation-path->output-path final1)
(derivation-path->output-path final2))
(build-derivations %store (list final1 final2)))))
(test-end) (test-end)