derivations: Add 'module->source-file-name'.
[jackhill/guix/guix.git] / guix / derivations.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
35b5ca78 2;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
77d3cf08 3;;;
233e7676 4;;; This file is part of GNU Guix.
77d3cf08 5;;;
233e7676 6;;; GNU Guix is free software; you can redistribute it and/or modify it
77d3cf08
LC
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
233e7676 11;;; GNU Guix is distributed in the hope that it will be useful, but
77d3cf08
LC
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
233e7676 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
77d3cf08
LC
18
19(define-module (guix derivations)
20 #:use-module (srfi srfi-1)
21 #:use-module (srfi srfi-9)
07c86312 22 #:use-module (srfi srfi-9 gnu)
77d3cf08 23 #:use-module (srfi srfi-26)
f304c9c2
LC
24 #:use-module (srfi srfi-34)
25 #:use-module (srfi srfi-35)
77d3cf08
LC
26 #:use-module (rnrs io ports)
27 #:use-module (rnrs bytevectors)
28 #:use-module (ice-9 match)
29 #:use-module (ice-9 rdelim)
e387ab7c 30 #:use-module (ice-9 vlist)
69f90f5c 31 #:use-module (guix store)
26bbbb95 32 #:use-module (guix utils)
e87f0591 33 #:use-module (guix monads)
72626a71 34 #:use-module (guix hash)
ddc29a78 35 #:use-module (guix base32)
969df974 36 #:use-module (guix records)
ed3592a9 37 #:use-module (guix sets)
9a20830e
LC
38 #:export (<derivation>
39 derivation?
77d3cf08
LC
40 derivation-outputs
41 derivation-inputs
42 derivation-sources
43 derivation-system
7ce7361b 44 derivation-builder
77d3cf08
LC
45 derivation-builder-arguments
46 derivation-builder-environment-vars
6a446d56 47 derivation-file-name
9a20830e
LC
48 derivation-prerequisites
49 derivation-prerequisites-to-build
77d3cf08 50
9a20830e 51 <derivation-output>
77d3cf08
LC
52 derivation-output?
53 derivation-output-path
54 derivation-output-hash-algo
55 derivation-output-hash
36bbbbd1 56 derivation-output-recursive?
77d3cf08 57
9a20830e 58 <derivation-input>
77d3cf08
LC
59 derivation-input?
60 derivation-input-path
61 derivation-input-sub-derivations
dd36b51b 62 derivation-input-output-paths
3681db5d 63 valid-derivation-input?
77d3cf08 64
f304c9c2
LC
65 &derivation-error
66 derivation-error?
67 derivation-error-derivation
68 &derivation-missing-output-error
69 derivation-missing-output-error?
70 derivation-missing-output
71
e786293e 72 derivation-name
0b6af195 73 derivation-output-names
77d3cf08 74 fixed-output-derivation?
fc93e309
LC
75 offloadable-derivation?
76 substitutable-derivation?
e9651e39 77 substitution-oracle
341c6fdd
LC
78 derivation-hash
79
80 read-derivation
26bbbb95 81 write-derivation
59688fc4
LC
82 derivation->output-path
83 derivation->output-paths
de4c3f26 84 derivation-path->output-path
7244a5f7 85 derivation-path->output-paths
d9085c23 86 derivation
969df974 87
e387ab7c 88 map-derivation
d9085c23 89
01d8ac64 90 build-derivations
e87f0591 91 built-derivations
e87f0591 92
9d8100f4 93
6985335f 94 module->source-file-name
aa72d9af 95 build-expression->derivation)
e87f0591
LC
96
97 ;; Re-export it from here for backward compatibility.
01d8ac64 98 #:re-export (%guile-for-build))
77d3cf08 99
f304c9c2
LC
100;;;
101;;; Error conditions.
102;;;
103
104(define-condition-type &derivation-error &nix-error
105 derivation-error?
106 (derivation derivation-error-derivation))
107
108(define-condition-type &derivation-missing-output-error &derivation-error
109 derivation-missing-output-error?
110 (output derivation-missing-output))
111
77d3cf08
LC
112;;;
113;;; Nix derivations, as implemented in Nix's `derivations.cc'.
114;;;
115
116(define-record-type <derivation>
6a446d56
LC
117 (make-derivation outputs inputs sources system builder args env-vars
118 file-name)
77d3cf08
LC
119 derivation?
120 (outputs derivation-outputs) ; list of name/<derivation-output> pairs
121 (inputs derivation-inputs) ; list of <derivation-input>
122 (sources derivation-sources) ; list of store paths
123 (system derivation-system) ; string
124 (builder derivation-builder) ; store path
125 (args derivation-builder-arguments) ; list of strings
6a446d56
LC
126 (env-vars derivation-builder-environment-vars) ; list of name/value pairs
127 (file-name derivation-file-name)) ; the .drv file name
77d3cf08
LC
128
129(define-record-type <derivation-output>
36bbbbd1 130 (make-derivation-output path hash-algo hash recursive?)
77d3cf08
LC
131 derivation-output?
132 (path derivation-output-path) ; store path
133 (hash-algo derivation-output-hash-algo) ; symbol | #f
36bbbbd1
LC
134 (hash derivation-output-hash) ; bytevector | #f
135 (recursive? derivation-output-recursive?)) ; Boolean
77d3cf08
LC
136
137(define-record-type <derivation-input>
138 (make-derivation-input path sub-derivations)
139 derivation-input?
140 (path derivation-input-path) ; store path
141 (sub-derivations derivation-input-sub-derivations)) ; list of strings
142
07c86312
LC
143(set-record-type-printer! <derivation>
144 (lambda (drv port)
145 (format port "#<derivation ~a => ~a ~a>"
146 (derivation-file-name drv)
147 (string-join
148 (map (match-lambda
149 ((_ . output)
150 (derivation-output-path output)))
151 (derivation-outputs drv)))
152 (number->string (object-address drv) 16))))
153
e786293e
LC
154(define (derivation-name drv)
155 "Return the base name of DRV."
156 (let ((base (store-path-package-name (derivation-file-name drv))))
157 (string-drop-right base 4)))
158
0b6af195
LC
159(define (derivation-output-names drv)
160 "Return the names of the outputs of DRV."
161 (match (derivation-outputs drv)
162 (((names . _) ...)
163 names)))
164
77d3cf08
LC
165(define (fixed-output-derivation? drv)
166 "Return #t if DRV is a fixed-output derivation, such as the result of a
167download with a fixed hash (aka. `fetchurl')."
168 (match drv
169 (($ <derivation>
99e17dc9 170 (("out" . ($ <derivation-output> _ (? symbol?) (? bytevector?)))))
77d3cf08
LC
171 #t)
172 (_ #f)))
173
dd36b51b
LC
174(define (derivation-input-output-paths input)
175 "Return the list of output paths corresponding to INPUT, a
176<derivation-input>."
177 (match input
178 (($ <derivation-input> path sub-drvs)
179 (map (cut derivation-path->output-path path <>)
180 sub-drvs))))
181
3681db5d
LC
182(define (valid-derivation-input? store input)
183 "Return true if INPUT is valid--i.e., if all the outputs it requests are in
184the store."
185 (every (cut valid-path? store <>)
186 (derivation-input-output-paths input)))
187
188(define* (derivation-prerequisites drv #:optional (cut? (const #f)))
189 "Return the list of derivation-inputs required to build DRV, recursively.
190
191CUT? is a predicate that is passed a derivation-input and returns true to
192eliminate the given input and its dependencies from the search. An example of
193search a predicate is 'valid-derivation-input?'; when it is used as CUT?, the
194result is the set of prerequisites of DRV not already in valid."
ed3592a9
LC
195 (let loop ((drv drv)
196 (result '())
197 (input-set (set)))
3681db5d
LC
198 (let ((inputs (remove (lambda (input)
199 (or (set-contains? input-set input)
200 (cut? input)))
9a20830e 201 (derivation-inputs drv))))
ed3592a9
LC
202 (fold2 loop
203 (append inputs result)
204 (fold set-insert input-set inputs)
205 (map (lambda (i)
206 (call-with-input-file (derivation-input-path i)
207 read-derivation))
208 inputs)))))
9a20830e 209
fc93e309
LC
210(define (offloadable-derivation? drv)
211 "Return true if DRV can be offloaded, false otherwise."
212 (match (assoc "preferLocalBuild"
213 (derivation-builder-environment-vars drv))
214 (("preferLocalBuild" . "1") #f)
215 (_ #t)))
216
4a6aeb67
LC
217(define (substitutable-derivation? drv)
218 "Return #t if DRV can be substituted."
219 (match (assoc "allowSubstitutes"
220 (derivation-builder-environment-vars drv))
221 (("allowSubstitutes" . value)
222 (string=? value "1"))
223 (_ #t)))
fc93e309 224
e9651e39
LC
225(define (derivation-output-paths drv sub-drvs)
226 "Return the output paths of outputs SUB-DRVS of DRV."
227 (match drv
228 (($ <derivation> outputs)
229 (map (lambda (sub-drv)
230 (derivation-output-path (assoc-ref outputs sub-drv)))
231 sub-drvs))))
232
58c08df0
LC
233(define* (substitution-oracle store drv
234 #:key (mode (build-mode normal)))
e9651e39
LC
235 "Return a one-argument procedure that, when passed a store file name,
236returns #t if it's substitutable and #f otherwise. The returned procedure
1eabf4ec
LC
237knows about all substitutes for all the derivations listed in DRV, *except*
238those that are already valid (that is, it won't bother checking whether an
239item is substitutable if it's already on disk); it also knows about their
240prerequisites, unless they are themselves substitutable.
e9651e39
LC
241
242Creating a single oracle (thus making a single 'substitutable-paths' call) and
243reusing it is much more efficient than calling 'has-substitutes?' or similar
244repeatedly, because it avoids the costs associated with launching the
245substituter many times."
c7d1d88f
LC
246 (define valid?
247 (cut valid-path? store <>))
248
c3a450fb
LC
249 (define valid-input?
250 (cut valid-derivation-input? store <>))
251
252 (define (dependencies drv)
253 ;; Skip prerequisite sub-trees of DRV whose root is valid. This allows us
254 ;; to ask the substituter for just as much as needed, instead of asking it
255 ;; for the whole world, which can be significantly faster when substitute
256 ;; info is not already in cache.
257 (append-map derivation-input-output-paths
258 (derivation-prerequisites drv valid-input?)))
259
e9651e39 260 (let* ((paths (delete-duplicates
b59df243
LC
261 (concatenate
262 (fold (lambda (drv result)
263 (let ((self (match (derivation->output-paths drv)
264 (((names . paths) ...)
265 paths))))
58c08df0
LC
266 (cond ((eqv? mode (build-mode check))
267 (cons (dependencies drv) result))
268 ((every valid? self)
269 result)
270 (else
271 (cons* self (dependencies drv) result)))))
b59df243
LC
272 '()
273 drv))))
c06d140c
LC
274 (subst (list->set (substitutable-paths store paths))))
275 (cut set-contains? subst <>)))
e9651e39 276
784bb1f3 277(define* (derivation-prerequisites-to-build store drv
dd36b51b 278 #:key
58c08df0 279 (mode (build-mode normal))
dd36b51b 280 (outputs
0b6af195 281 (derivation-output-names drv))
e9651e39
LC
282 (substitutable?
283 (substitution-oracle store
58c08df0
LC
284 (list drv)
285 #:mode mode)))
dd36b51b
LC
286 "Return two values: the list of derivation-inputs required to build the
287OUTPUTS of DRV and not already available in STORE, recursively, and the list
e9651e39
LC
288of required store paths that can be substituted. SUBSTITUTABLE? must be a
289one-argument procedure similar to that returned by 'substitution-oracle'."
784bb1f3
LC
290 (define built?
291 (cut valid-path? store <>))
292
9a20830e 293 (define input-built?
dd36b51b
LC
294 (compose (cut any built? <>) derivation-input-output-paths))
295
296 (define input-substitutable?
297 ;; Return true if and only if all of SUB-DRVS are subsitutable. If at
298 ;; least one is missing, then everything must be rebuilt.
299 (compose (cut every substitutable? <>) derivation-input-output-paths))
784bb1f3 300
58c08df0
LC
301 (define (derivation-built? drv* sub-drvs)
302 ;; In 'check' mode, assume that DRV is not built.
303 (and (not (and (eqv? mode (build-mode check))
304 (eq? drv* drv)))
305 (every built? (derivation-output-paths drv* sub-drvs))))
dd36b51b
LC
306
307 (define (derivation-substitutable? drv sub-drvs)
d2d0514b
LC
308 (and (substitutable-derivation? drv)
309 (every substitutable? (derivation-output-paths drv sub-drvs))))
dd36b51b
LC
310
311 (let loop ((drv drv)
312 (sub-drvs outputs)
313 (build '())
314 (substitute '()))
315 (cond ((derivation-built? drv sub-drvs)
316 (values build substitute))
317 ((derivation-substitutable? drv sub-drvs)
318 (values build
319 (append (derivation-output-paths drv sub-drvs)
320 substitute)))
321 (else
d2d0514b
LC
322 (let ((build (if (substitutable-derivation? drv)
323 build
324 (cons (make-derivation-input
325 (derivation-file-name drv) sub-drvs)
326 build)))
327 (inputs (remove (lambda (i)
dd36b51b
LC
328 (or (member i build) ; XXX: quadratic
329 (input-built? i)
330 (input-substitutable? i)))
331 (derivation-inputs drv))))
332 (fold2 loop
333 (append inputs build)
334 (append (append-map (lambda (input)
335 (if (and (not (input-built? input))
336 (input-substitutable? input))
337 (derivation-input-output-paths
338 input)
339 '()))
340 (derivation-inputs drv))
341 substitute)
342 (map (lambda (i)
343 (call-with-input-file (derivation-input-path i)
344 read-derivation))
345 inputs)
346 (map derivation-input-sub-derivations inputs)))))))
9a20830e 347
d0840e4a
LC
348(define (%read-derivation drv-port)
349 ;; Actually read derivation from DRV-PORT.
77d3cf08
LC
350
351 (define comma (string->symbol ","))
352
353 (define (ununquote x)
354 (match x
355 (('unquote x) (ununquote x))
356 ((x ...) (map ununquote x))
357 (_ x)))
358
359 (define (outputs->alist x)
360 (fold-right (lambda (output result)
361 (match output
362 ((name path "" "")
363 (alist-cons name
36bbbbd1 364 (make-derivation-output path #f #f #f)
77d3cf08
LC
365 result))
366 ((name path hash-algo hash)
367 ;; fixed-output
36bbbbd1
LC
368 (let* ((rec? (string-prefix? "r:" hash-algo))
369 (algo (string->symbol
370 (if rec?
371 (string-drop hash-algo 2)
372 hash-algo)))
373 (hash (base16-string->bytevector hash)))
77d3cf08 374 (alist-cons name
36bbbbd1
LC
375 (make-derivation-output path algo
376 hash rec?)
77d3cf08
LC
377 result)))))
378 '()
379 x))
380
381 (define (make-input-drvs x)
382 (fold-right (lambda (input result)
383 (match input
384 ((path (sub-drvs ...))
385 (cons (make-derivation-input path sub-drvs)
386 result))))
387 '()
388 x))
389
df7bbd38
LC
390 ;; The contents of a derivation are typically ASCII, but choosing
391 ;; UTF-8 allows us to take the fast path for Guile's `scm_getc'.
392 (set-port-encoding! drv-port "UTF-8")
393
77d3cf08
LC
394 (let loop ((exp (read drv-port))
395 (result '()))
396 (match exp
397 ((? eof-object?)
398 (let ((result (reverse result)))
399 (match result
400 (('Derive ((outputs ...) (input-drvs ...)
401 (input-srcs ...)
402 (? string? system)
403 (? string? builder)
404 ((? string? args) ...)
405 ((var value) ...)))
406 (make-derivation (outputs->alist outputs)
407 (make-input-drvs input-drvs)
408 input-srcs
409 system builder args
6a446d56
LC
410 (fold-right alist-cons '() var value)
411 (port-filename drv-port)))
77d3cf08
LC
412 (_
413 (error "failed to parse derivation" drv-port result)))))
414 ((? (cut eq? <> comma))
415 (loop (read drv-port) result))
416 (_
417 (loop (read drv-port)
418 (cons (ununquote exp) result))))))
419
d0840e4a
LC
420(define read-derivation
421 (let ((cache (make-weak-value-hash-table 200)))
422 (lambda (drv-port)
423 "Read the derivation from DRV-PORT and return the corresponding
424<derivation> object."
425 ;; Memoize that operation because `%read-derivation' is quite expensive,
426 ;; and because the same argument is read more than 15 times on average
427 ;; during something like (package-derivation s gdb).
428 (let ((file (and=> (port-filename drv-port) basename)))
429 (or (and file (hash-ref cache file))
430 (let ((drv (%read-derivation drv-port)))
431 (hash-set! cache file drv)
432 drv))))))
433
d8085599
LC
434(define-inlinable (write-sequence lst write-item port)
435 ;; Write each element of LST with WRITE-ITEM to PORT, separating them with a
436 ;; comma.
437 (match lst
438 (()
439 #t)
440 ((prefix (... ...) last)
441 (for-each (lambda (item)
442 (write-item item port)
443 (display "," port))
444 prefix)
445 (write-item last port))))
446
447(define-inlinable (write-list lst write-item port)
448 ;; Write LST as a derivation list to PORT, using WRITE-ITEM to write each
449 ;; element.
450 (display "[" port)
451 (write-sequence lst write-item port)
452 (display "]" port))
453
454(define-inlinable (write-tuple lst write-item port)
455 ;; Same, but write LST as a tuple.
456 (display "(" port)
457 (write-sequence lst write-item port)
458 (display ")" port))
459
77d3cf08
LC
460(define (write-derivation drv port)
461 "Write the ATerm-like serialization of DRV to PORT. See Section 2.4 of
462Eelco Dolstra's PhD dissertation for an overview of a previous version of
463that form."
aaa848f3
LC
464
465 ;; Make sure we're using the faster implementation.
466 (define format simple-format)
467
d8085599
LC
468 (define (write-string-list lst)
469 (write-list lst write port))
77d3cf08 470
d66ac374
LC
471 (define (coalesce-duplicate-inputs inputs)
472 ;; Return a list of inputs, such that when INPUTS contains the same DRV
473 ;; twice, they are coalesced, with their sub-derivations merged. This is
474 ;; needed because Nix itself keeps only one of them.
475 (fold (lambda (input result)
476 (match input
477 (($ <derivation-input> path sub-drvs)
478 ;; XXX: quadratic
479 (match (find (match-lambda
480 (($ <derivation-input> p s)
481 (string=? p path)))
482 result)
483 (#f
484 (cons input result))
485 ((and dup ($ <derivation-input> _ sub-drvs2))
486 ;; Merge DUP with INPUT.
487 (let ((sub-drvs (delete-duplicates
488 (append sub-drvs sub-drvs2))))
489 (cons (make-derivation-input path sub-drvs)
490 (delq dup result))))))))
491 '()
492 inputs))
493
d8085599
LC
494 (define (write-output output port)
495 (match output
36bbbbd1 496 ((name . ($ <derivation-output> path hash-algo hash recursive?))
d8085599 497 (write-tuple (list name path
36bbbbd1
LC
498 (if hash-algo
499 (string-append (if recursive? "r:" "")
500 (symbol->string hash-algo))
501 "")
d8085599
LC
502 (or (and=> hash bytevector->base16-string)
503 ""))
504 write
505 port))))
506
507 (define (write-input input port)
508 (match input
509 (($ <derivation-input> path sub-drvs)
510 (display "(" port)
511 (write path port)
512 (display "," port)
513 (write-string-list (sort sub-drvs string<?))
514 (display ")" port))))
515
516 (define (write-env-var env-var port)
517 (match env-var
518 ((name . value)
519 (display "(" port)
520 (write name port)
521 (display "," port)
522 (write value port)
523 (display ")" port))))
524
561eaf71
LC
525 ;; Note: lists are sorted alphabetically, to conform with the behavior of
526 ;; C++ `std::map' in Nix itself.
527
77d3cf08
LC
528 (match drv
529 (($ <derivation> outputs inputs sources
530 system builder args env-vars)
531 (display "Derive(" port)
d8085599
LC
532 (write-list (sort outputs
533 (lambda (o1 o2)
534 (string<? (car o1) (car o2))))
535 write-output
536 port)
77d3cf08 537 (display "," port)
d8085599
LC
538 (write-list (sort (coalesce-duplicate-inputs inputs)
539 (lambda (i1 i2)
540 (string<? (derivation-input-path i1)
541 (derivation-input-path i2))))
542 write-input
543 port)
77d3cf08 544 (display "," port)
d8085599 545 (write-string-list (sort sources string<?))
77d3cf08 546 (format port ",~s,~s," system builder)
d8085599 547 (write-string-list args)
77d3cf08 548 (display "," port)
d8085599
LC
549 (write-list (sort env-vars
550 (lambda (e1 e2)
551 (string<? (car e1) (car e2))))
552 write-env-var
553 port)
77d3cf08
LC
554 (display ")" port))))
555
be4e38fb
LC
556(define derivation->string
557 (memoize
558 (lambda (drv)
559 "Return the external representation of DRV as a string."
560 (with-fluids ((%default-port-encoding "UTF-8"))
561 (call-with-output-string
562 (cut write-derivation drv <>))))))
563
59688fc4 564(define* (derivation->output-path drv #:optional (output "out"))
f304c9c2
LC
565 "Return the store path of its output OUTPUT. Raise a
566'&derivation-missing-output-error' condition if OUTPUT is not an output of
567DRV."
568 (let ((output* (assoc-ref (derivation-outputs drv) output)))
569 (if output*
570 (derivation-output-path output*)
571 (raise (condition (&derivation-missing-output-error
572 (derivation drv)
573 (output output)))))))
59688fc4
LC
574
575(define (derivation->output-paths drv)
576 "Return the list of name/path pairs of the outputs of DRV."
577 (map (match-lambda
578 ((name . output)
579 (cons name (derivation-output-path output))))
580 (derivation-outputs drv)))
581
aaa848f3
LC
582(define derivation-path->output-path
583 ;; This procedure is called frequently, so memoize it.
584 (memoize
585 (lambda* (path #:optional (output "out"))
6f58d582 586 "Read the derivation from PATH (`/gnu/store/xxx.drv'), and return the store
de4c3f26 587path of its output OUTPUT."
d0dc4907
LC
588 (derivation->output-path (call-with-input-file path read-derivation)
589 output))))
de4c3f26 590
7244a5f7 591(define (derivation-path->output-paths path)
6f58d582 592 "Read the derivation from PATH (`/gnu/store/xxx.drv'), and return the
7244a5f7 593list of name/path pairs of its outputs."
59688fc4 594 (derivation->output-paths (call-with-input-file path read-derivation)))
7244a5f7 595
de4c3f26
LC
596\f
597;;;
598;;; Derivation primitive.
599;;;
600
26bbbb95
LC
601(define (compressed-hash bv size) ; `compressHash'
602 "Given the hash stored in BV, return a compressed version thereof that fits
603in SIZE bytes."
604 (define new (make-bytevector size 0))
605 (define old-size (bytevector-length bv))
606 (let loop ((i 0))
607 (if (= i old-size)
608 new
609 (let* ((j (modulo i size))
610 (o (bytevector-u8-ref new j)))
611 (bytevector-u8-set! new j
612 (logxor o (bytevector-u8-ref bv i)))
613 (loop (+ 1 i))))))
77d3cf08 614
1391dcb0
LC
615(define derivation-path->base16-hash
616 (memoize
617 (lambda (file)
618 "Return a string containing the base16 representation of the hash of the
619derivation at FILE."
620 (call-with-input-file file
621 (compose bytevector->base16-string
622 derivation-hash
623 read-derivation)))))
624
de4c3f26
LC
625(define derivation-hash ; `hashDerivationModulo' in derivations.cc
626 (memoize
627 (lambda (drv)
628 "Return the hash of DRV, modulo its fixed-output inputs, as a bytevector."
629 (match drv
630 (($ <derivation> ((_ . ($ <derivation-output> path
36bbbbd1
LC
631 (? symbol? hash-algo) (? bytevector? hash)
632 (? boolean? recursive?)))))
de4c3f26 633 ;; A fixed-output derivation.
77d3cf08 634 (sha256
de4c3f26 635 (string->utf8
36bbbbd1
LC
636 (string-append "fixed:out:"
637 (if recursive? "r:" "")
638 (symbol->string hash-algo)
749c6567
LC
639 ":" (bytevector->base16-string hash)
640 ":" path))))
de4c3f26
LC
641 (($ <derivation> outputs inputs sources
642 system builder args env-vars)
643 ;; A regular derivation: replace the path of each input with that
644 ;; input's hash; return the hash of serialization of the resulting
561eaf71
LC
645 ;; derivation.
646 (let* ((inputs (map (match-lambda
647 (($ <derivation-input> path sub-drvs)
1391dcb0 648 (let ((hash (derivation-path->base16-hash path)))
561eaf71
LC
649 (make-derivation-input hash sub-drvs))))
650 inputs))
651 (drv (make-derivation outputs inputs sources
6a446d56
LC
652 system builder args env-vars
653 #f)))
b0fad8a2
LC
654
655 ;; XXX: At this point this remains faster than `port-sha256', because
656 ;; the SHA256 port's `write' method gets called for every single
657 ;; character.
de4c3f26 658 (sha256
be4e38fb 659 (string->utf8 (derivation->string drv)))))))))
77d3cf08 660
26bbbb95
LC
661(define (store-path type hash name) ; makeStorePath
662 "Return the store path for NAME/HASH/TYPE."
663 (let* ((s (string-append type ":sha256:"
664 (bytevector->base16-string hash) ":"
665 (%store-prefix) ":" name))
666 (h (sha256 (string->utf8 s)))
667 (c (compressed-hash h 20)))
668 (string-append (%store-prefix) "/"
669 (bytevector->nix-base32-string c) "-"
670 name)))
671
672(define (output-path output hash name) ; makeOutputPath
673 "Return an output path for OUTPUT (the name of the output as a string) of
674the derivation called NAME with hash HASH."
675 (store-path (string-append "output:" output) hash
676 (if (string=? output "out")
677 name
678 (string-append name "-" output))))
679
36bbbbd1
LC
680(define (fixed-output-path output hash-algo hash recursive? name)
681 "Return an output path for the fixed output OUTPUT defined by HASH of type
682HASH-ALGO, of the derivation NAME. RECURSIVE? has the same meaning as for
683'add-to-store'."
684 (if (and recursive? (eq? hash-algo 'sha256))
685 (store-path "source" hash name)
686 (let ((tag (string-append "fixed:" output ":"
687 (if recursive? "r:" "")
688 (symbol->string hash-algo) ":"
689 (bytevector->base16-string hash) ":")))
690 (store-path (string-append "output:" output)
691 (sha256 (string->utf8 tag))
692 name))))
693
a987d2c0
LC
694(define* (derivation store name builder args
695 #:key
696 (system (%current-system)) (env-vars '())
697 (inputs '()) (outputs '("out"))
2096ef47 698 hash hash-algo recursive?
35b5ca78
LC
699 references-graphs
700 allowed-references disallowed-references
4a6aeb67
LC
701 leaked-env-vars local-build?
702 (substitutable? #t))
59688fc4 703 "Build a derivation with the given arguments, and return the resulting
2096ef47 704<derivation> object. When HASH and HASH-ALGO are given, a
59688fc4 705fixed-output derivation is created---i.e., one whose result is known in
36bbbbd1
LC
706advance, such as a file download. If, in addition, RECURSIVE? is true, then
707that fixed output may be an executable file or a directory and HASH must be
708the hash of an archive containing this output.
5b0c9d16 709
858e9282 710When REFERENCES-GRAPHS is true, it must be a list of file name/store path
5b0c9d16 711pairs. In that case, the reference graph of each store path is exported in
1909431c
LC
712the build environment in the corresponding file, in a simple text format.
713
b53be755 714When ALLOWED-REFERENCES is true, it must be a list of store items or outputs
35b5ca78
LC
715that the derivation's outputs may refer to. Likewise, DISALLOWED-REFERENCES,
716if true, must be a list of things the outputs may not refer to.
b53be755 717
c0468155
LC
718When LEAKED-ENV-VARS is true, it must be a list of strings denoting
719environment variables that are allowed to \"leak\" from the daemon's
720environment to the build environment. This is only applicable to fixed-output
721derivations--i.e., when HASH is true. The main use is to allow variables such
722as \"http_proxy\" to be passed to derivations that download files.
723
1909431c
LC
724When LOCAL-BUILD? is true, declare that the derivation is not a good candidate
725for offloading and should rather be built locally. This is the case for small
4a6aeb67
LC
726derivations where the costs of data transfers would outweigh the benefits.
727
728When SUBSTITUTABLE? is false, declare that substitutes of the derivation's
729output should not be used."
26bbbb95
LC
730 (define (add-output-paths drv)
731 ;; Return DRV with an actual store path for each of its output and the
732 ;; corresponding environment variable.
733 (match drv
734 (($ <derivation> outputs inputs sources
735 system builder args env-vars)
736 (let* ((drv-hash (derivation-hash drv))
737 (outputs (map (match-lambda
d9085c23 738 ((output-name . ($ <derivation-output>
36bbbbd1
LC
739 _ algo hash rec?))
740 (let ((path (if hash
741 (fixed-output-path output-name
742 algo hash
743 rec? name)
744 (output-path output-name
745 drv-hash name))))
d9085c23
LC
746 (cons output-name
747 (make-derivation-output path algo
36bbbbd1 748 hash rec?)))))
d9085c23 749 outputs)))
26bbbb95
LC
750 (make-derivation outputs inputs sources system builder args
751 (map (match-lambda
752 ((name . value)
753 (cons name
754 (or (and=> (assoc-ref outputs name)
755 derivation-output-path)
756 value))))
6a446d56
LC
757 env-vars)
758 #f)))))
26bbbb95 759
5b0c9d16
LC
760 (define (user+system-env-vars)
761 ;; Some options are passed to the build daemon via the env. vars of
762 ;; derivations (urgh!). We hide that from our API, but here is the place
763 ;; where we kludgify those options.
b53be755
LC
764 (let ((env-vars `(,@(if local-build?
765 `(("preferLocalBuild" . "1"))
766 '())
4a6aeb67
LC
767 ,@(if (not substitutable?)
768 `(("allowSubstitutes" . "0"))
769 '())
b53be755
LC
770 ,@(if allowed-references
771 `(("allowedReferences"
772 . ,(string-join allowed-references)))
773 '())
35b5ca78
LC
774 ,@(if disallowed-references
775 `(("disallowedReferences"
776 . ,(string-join disallowed-references)))
777 '())
c0468155
LC
778 ,@(if leaked-env-vars
779 `(("impureEnvVars"
780 . ,(string-join leaked-env-vars)))
781 '())
b53be755 782 ,@env-vars)))
1909431c
LC
783 (match references-graphs
784 (((file . path) ...)
785 (let ((value (map (cut string-append <> " " <>)
786 file path)))
787 ;; XXX: This all breaks down if an element of FILE or PATH contains
788 ;; white space.
789 `(("exportReferencesGraph" . ,(string-join value " "))
790 ,@env-vars)))
791 (#f
792 env-vars))))
5b0c9d16
LC
793
794 (define (env-vars-with-empty-outputs env-vars)
26bbbb95 795 ;; Return a variant of ENV-VARS where each OUTPUTS is associated with an
561eaf71 796 ;; empty string, even outputs that do not appear in ENV-VARS.
26bbbb95
LC
797 (let ((e (map (match-lambda
798 ((name . val)
799 (if (member name outputs)
800 (cons name "")
801 (cons name val))))
802 env-vars)))
561eaf71
LC
803 (fold (lambda (output-name env-vars)
804 (if (assoc output-name env-vars)
805 env-vars
806 (append env-vars `((,output-name . "")))))
807 e
808 outputs)))
26bbbb95 809
6a446d56
LC
810 (define (set-file-name drv file)
811 ;; Set FILE as the 'file-name' field of DRV.
812 (match drv
813 (($ <derivation> outputs inputs sources system builder
814 args env-vars)
815 (make-derivation outputs inputs sources system builder
816 args env-vars file))))
817
26bbbb95
LC
818 (let* ((outputs (map (lambda (name)
819 ;; Return outputs with an empty path.
820 (cons name
36bbbbd1
LC
821 (make-derivation-output "" hash-algo
822 hash recursive?)))
26bbbb95
LC
823 outputs))
824 (inputs (map (match-lambda
59688fc4
LC
825 (((? derivation? drv))
826 (make-derivation-input (derivation-file-name drv)
827 '("out")))
828 (((? derivation? drv) sub-drvs ...)
829 (make-derivation-input (derivation-file-name drv)
830 sub-drvs))
200dc937 831 (((? direct-store-path? input))
de4c3f26 832 (make-derivation-input input '("out")))
200dc937 833 (((? direct-store-path? input) sub-drvs ...)
26bbbb95
LC
834 (make-derivation-input input sub-drvs))
835 ((input . _)
836 (let ((path (add-to-store store
837 (basename input)
a9ebd9ef 838 #t "sha256" input)))
26bbbb95 839 (make-derivation-input path '()))))
d26ad5e4 840 (delete-duplicates inputs)))
5b0c9d16 841 (env-vars (env-vars-with-empty-outputs (user+system-env-vars)))
26bbbb95
LC
842 (drv-masked (make-derivation outputs
843 (filter (compose derivation-path?
844 derivation-input-path)
845 inputs)
846 (filter-map (lambda (i)
847 (let ((p (derivation-input-path i)))
848 (and (not (derivation-path? p))
849 p)))
850 inputs)
6a446d56 851 system builder args env-vars #f))
26bbbb95 852 (drv (add-output-paths drv-masked)))
de4c3f26 853
6a446d56 854 (let ((file (add-text-to-store store (string-append name ".drv")
be4e38fb 855 (derivation->string drv)
6a446d56
LC
856 (map derivation-input-path
857 inputs))))
59688fc4
LC
858 (set-file-name drv file))))
859
e387ab7c
LC
860(define* (map-derivation store drv mapping
861 #:key (system (%current-system)))
862 "Given MAPPING, a list of pairs of derivations, return a derivation based on
863DRV where all the 'car's of MAPPING have been replaced by its 'cdr's,
864recursively."
865 (define (substitute str initial replacements)
866 (fold (lambda (path replacement result)
867 (string-replace-substring result path
868 replacement))
869 str
870 initial replacements))
871
872 (define (substitute-file file initial replacements)
873 (define contents
874 (with-fluids ((%default-port-encoding #f))
875 (call-with-input-file file get-string-all)))
876
877 (let ((updated (substitute contents initial replacements)))
878 (if (string=? updated contents)
879 file
880 ;; XXX: permissions aren't preserved.
881 (add-text-to-store store (store-path-package-name file)
882 updated))))
883
884 (define input->output-paths
885 (match-lambda
a716e36d 886 (((? derivation? drv))
e387ab7c 887 (list (derivation->output-path drv)))
a716e36d 888 (((? derivation? drv) sub-drvs ...)
e387ab7c 889 (map (cut derivation->output-path drv <>)
a716e36d
LC
890 sub-drvs))
891 ((file)
892 (list file))))
e387ab7c
LC
893
894 (let ((mapping (fold (lambda (pair result)
895 (match pair
a716e36d 896 (((? derivation? orig) . replacement)
e387ab7c 897 (vhash-cons (derivation-file-name orig)
a716e36d
LC
898 replacement result))
899 ((file . replacement)
900 (vhash-cons file replacement result))))
e387ab7c
LC
901 vlist-null
902 mapping)))
903 (define rewritten-input
904 ;; Rewrite the given input according to MAPPING, and return an input
905 ;; in the format used in 'derivation' calls.
906 (memoize
907 (lambda (input loop)
908 (match input
909 (($ <derivation-input> path (sub-drvs ...))
910 (match (vhash-assoc path mapping)
a716e36d 911 ((_ . (? derivation? replacement))
e387ab7c 912 (cons replacement sub-drvs))
a716e36d
LC
913 ((_ . replacement)
914 (list replacement))
e387ab7c
LC
915 (#f
916 (let* ((drv (loop (call-with-input-file path read-derivation))))
917 (cons drv sub-drvs)))))))))
918
919 (let loop ((drv drv))
920 (let* ((inputs (map (cut rewritten-input <> loop)
921 (derivation-inputs drv)))
922 (initial (append-map derivation-input-output-paths
923 (derivation-inputs drv)))
924 (replacements (append-map input->output-paths inputs))
925
926 ;; Sources typically refer to the output directories of the
927 ;; original inputs, INITIAL. Rewrite them by substituting
928 ;; REPLACEMENTS.
a716e36d
LC
929 (sources (map (lambda (source)
930 (match (vhash-assoc source mapping)
931 ((_ . replacement)
932 replacement)
933 (#f
934 (substitute-file source
935 initial replacements))))
e387ab7c
LC
936 (derivation-sources drv)))
937
938 ;; Now augment the lists of initials and replacements.
939 (initial (append (derivation-sources drv) initial))
940 (replacements (append sources replacements))
941 (name (store-path-package-name
942 (string-drop-right (derivation-file-name drv)
943 4))))
944 (derivation store name
945 (substitute (derivation-builder drv)
946 initial replacements)
947 (map (cut substitute <> initial replacements)
948 (derivation-builder-arguments drv))
949 #:system system
950 #:env-vars (map (match-lambda
951 ((var . value)
952 `(,var
953 . ,(substitute value initial
954 replacements))))
955 (derivation-builder-environment-vars drv))
956 #:inputs (append (map list sources) inputs)
0b6af195 957 #:outputs (derivation-output-names drv)
e387ab7c
LC
958 #:hash (match (derivation-outputs drv)
959 ((($ <derivation-output> _ algo hash))
960 hash)
961 (_ #f))
962 #:hash-algo (match (derivation-outputs drv)
963 ((($ <derivation-output> _ algo hash))
964 algo)
965 (_ #f)))))))
966
59688fc4
LC
967\f
968;;;
969;;; Store compatibility layer.
970;;;
971
a8d65643
LC
972(define* (build-derivations store derivations
973 #:optional (mode (build-mode normal)))
974 "Build DERIVATIONS, a list of <derivation> objects or .drv file names, using
975the specified MODE."
01d8ac64
LC
976 (build-things store (map (match-lambda
977 ((? string? file) file)
978 ((and drv ($ <derivation>))
979 (derivation-file-name drv)))
a8d65643
LC
980 derivations)
981 mode))
d9085c23
LC
982
983\f
984;;;
985;;; Guile-based builders.
986;;;
987
d9024884
LC
988(define (parent-directories file-name)
989 "Return the list of parent dirs of FILE-NAME, in the order in which an
990`mkdir -p' implementation would make them."
991 (let ((not-slash (char-set-complement (char-set #\/))))
992 (reverse
993 (fold (lambda (dir result)
994 (match result
995 (()
996 (list dir))
997 ((prev _ ...)
998 (cons (string-append prev "/" dir)
999 result))))
1000 '()
1001 (remove (cut string=? <> ".")
1002 (string-tokenize (dirname file-name) not-slash))))))
1003
aa72d9af 1004(define* (imported-files store files ;deprecated
b272c474
LC
1005 #:key (name "file-import")
1006 (system (%current-system))
1007 (guile (%guile-for-build)))
99634e3f
LC
1008 "Return a derivation that imports FILES into STORE. FILES must be a list
1009of (FINAL-PATH . FILE-NAME) pairs; each FILE-NAME is read from the file
1010system, imported, and appears under FINAL-PATH in the resulting store path."
99634e3f
LC
1011 (let* ((files (map (match-lambda
1012 ((final-path . file-name)
2acb2cb6 1013 (list final-path
a9ebd9ef 1014 (add-to-store store (basename final-path) #f
99634e3f
LC
1015 "sha256" file-name))))
1016 files))
1017 (builder
1018 `(begin
1019 (mkdir %output) (chdir %output)
1020 ,@(append-map (match-lambda
2acb2cb6 1021 ((final-path store-path)
d9024884 1022 (append (match (parent-directories final-path)
99634e3f
LC
1023 (() '())
1024 ((head ... tail)
1025 (append (map (lambda (d)
1026 `(false-if-exception
1027 (mkdir ,d)))
1028 head)
224f7ad6
LC
1029 `((or (file-exists? ,tail)
1030 (mkdir ,tail))))))
99634e3f
LC
1031 `((symlink ,store-path ,final-path)))))
1032 files))))
dd1a5a15
LC
1033 (build-expression->derivation store name builder
1034 #:system system
1035 #:inputs files
6ce206cb
LC
1036 #:guile-for-build guile
1037 #:local-build? #t)))
99634e3f 1038
8601d0dd
LC
1039(define search-path*
1040 ;; A memoizing version of 'search-path' so 'imported-modules' does not end
1041 ;; up looking for the same files over and over again.
1042 (memoize search-path))
1043
6985335f
LC
1044(define (module->source-file-name module)
1045 "Return the file name corresponding to MODULE, a Guile module name (a list
1046of symbols.)"
1047 (string-append (string-join (map symbol->string module) "/")
1048 ".scm"))
1049
aa72d9af 1050(define* (%imported-modules store modules ;deprecated
e87f0591
LC
1051 #:key (name "module-import")
1052 (system (%current-system))
1053 (guile (%guile-for-build))
1054 (module-path %load-path))
3eb98237 1055 "Return a derivation that contains the source files of MODULES, a list of
8dcb0c55 1056module names such as `(ice-9 q)'. All of MODULES must be in the MODULE-PATH
3eb98237
LC
1057search path."
1058 ;; TODO: Determine the closure of MODULES, build the `.go' files,
1059 ;; canonicalize the source files through read/write, etc.
1060 (let ((files (map (lambda (m)
6985335f 1061 (let ((f (module->source-file-name m)))
8601d0dd 1062 (cons f (search-path* module-path f))))
3eb98237 1063 modules)))
b272c474
LC
1064 (imported-files store files #:name name #:system system
1065 #:guile guile)))
3eb98237 1066
aa72d9af 1067(define* (%compiled-modules store modules ;deprecated
e87f0591
LC
1068 #:key (name "module-import-compiled")
1069 (system (%current-system))
1070 (guile (%guile-for-build))
1071 (module-path %load-path))
d9024884
LC
1072 "Return a derivation that builds a tree containing the `.go' files
1073corresponding to MODULES. All the MODULES are built in a context where
1074they can refer to each other."
e87f0591
LC
1075 (let* ((module-drv (%imported-modules store modules
1076 #:system system
1077 #:guile guile
1078 #:module-path module-path))
59688fc4 1079 (module-dir (derivation->output-path module-drv))
d9024884
LC
1080 (files (map (lambda (m)
1081 (let ((f (string-join (map symbol->string m)
1082 "/")))
1083 (cons (string-append f ".go")
1084 (string-append module-dir "/" f ".scm"))))
1085 modules)))
1086 (define builder
1087 `(begin
1088 (use-modules (system base compile))
1089 (let ((out (assoc-ref %outputs "out")))
1090 (mkdir out)
1091 (chdir out))
1092
1093 (set! %load-path
1094 (cons ,module-dir %load-path))
1095
1096 ,@(map (match-lambda
1097 ((output . input)
1098 (let ((make-parent-dirs (map (lambda (dir)
1099 `(unless (file-exists? ,dir)
1100 (mkdir ,dir)))
1101 (parent-directories output))))
1102 `(begin
1103 ,@make-parent-dirs
1104 (compile-file ,input
1105 #:output-file ,output
1106 #:opts %auto-compilation-options)))))
1107 files)))
1108
dd1a5a15
LC
1109 (build-expression->derivation store name builder
1110 #:inputs `(("modules" ,module-drv))
1111 #:system system
6ce206cb
LC
1112 #:guile-for-build guile
1113 #:local-build? #t)))
3eb98237 1114
aa72d9af 1115(define* (build-expression->derivation store name exp ;deprecated
dd1a5a15
LC
1116 #:key
1117 (system (%current-system))
1118 (inputs '())
1119 (outputs '("out"))
36bbbbd1 1120 hash hash-algo recursive?
4c1eddf7 1121 (env-vars '())
6dd7787c 1122 (modules '())
9c629a27 1123 guile-for-build
1909431c 1124 references-graphs
63a42824 1125 allowed-references
35b5ca78 1126 disallowed-references
4a6aeb67 1127 local-build? (substitutable? #t))
874e6874
LC
1128 "Return a derivation that executes Scheme expression EXP as a builder
1129for derivation NAME. INPUTS must be a list of (NAME DRV-PATH SUB-DRV)
1130tuples; when SUB-DRV is omitted, \"out\" is assumed. MODULES is a list
1131of names of Guile modules from the current search path to be copied in
1132the store, compiled, and made available in the load path during the
1133execution of EXP.
1134
1135EXP is evaluated in an environment where %OUTPUT is bound to the main
1136output path, %OUTPUTS is bound to a list of output/path pairs, and where
1137%BUILD-INPUTS is bound to an alist of string/output-path pairs made from
1138INPUTS. Optionally, ENV-VARS is a list of string pairs specifying the
1139name and value of environment variables visible to the builder. The
1140builder terminates by passing the result of EXP to `exit'; thus, when
1141EXP returns #f, the build is considered to have failed.
6dd7787c
LC
1142
1143EXP is built using GUILE-FOR-BUILD (a derivation). When GUILE-FOR-BUILD is
9c629a27
LC
1144omitted or is #f, the value of the `%guile-for-build' fluid is used instead.
1145
63a42824 1146See the `derivation' procedure for the meaning of REFERENCES-GRAPHS,
35b5ca78 1147ALLOWED-REFERENCES, DISALLOWED-REFERENCES, LOCAL-BUILD?, and SUBSTITUTABLE?."
b272c474
LC
1148 (define guile-drv
1149 (or guile-for-build (%guile-for-build)))
1150
d9085c23 1151 (define guile
59688fc4 1152 (string-append (derivation->output-path guile-drv)
d9085c23
LC
1153 "/bin/guile"))
1154
0d56a551
LC
1155 (define module-form?
1156 (match-lambda
a987d2c0
LC
1157 (((or 'define-module 'use-modules) _ ...) #t)
1158 (_ #f)))
0d56a551 1159
7bdd1f0e
LC
1160 (define source-path
1161 ;; When passed an input that is a source, return its path; otherwise
1162 ;; return #f.
1163 (match-lambda
59688fc4
LC
1164 ((_ (? derivation?) _ ...)
1165 #f)
7bdd1f0e
LC
1166 ((_ path _ ...)
1167 (and (not (derivation-path? path))
1168 path))))
1169
d9085c23 1170 (let* ((prologue `(begin
0d56a551
LC
1171 ,@(match exp
1172 ((_ ...)
1173 ;; Module forms must appear at the top-level so
1174 ;; that any macros they export can be expanded.
1175 (filter module-form? exp))
1176 (_ `(,exp)))
1177
d9085c23 1178 (define %output (getenv "out"))
9bc07f4d
LC
1179 (define %outputs
1180 (map (lambda (o)
1181 (cons o (getenv o)))
1182 ',outputs))
d9085c23
LC
1183 (define %build-inputs
1184 ',(map (match-lambda
2acb2cb6
LC
1185 ((name drv . rest)
1186 (let ((sub (match rest
1187 (() "out")
1188 ((x) x))))
1189 (cons name
59688fc4
LC
1190 (cond
1191 ((derivation? drv)
1192 (derivation->output-path drv sub))
1193 ((derivation-path? drv)
1194 (derivation-path->output-path drv
1195 sub))
1196 (else drv))))))
d44bc84b
LC
1197 inputs))
1198
d9024884
LC
1199 ,@(if (null? modules)
1200 '()
1201 ;; Remove our own settings.
1202 '((unsetenv "GUILE_LOAD_COMPILED_PATH")))
1203
d44bc84b
LC
1204 ;; Guile sets it, but remove it to avoid conflicts when
1205 ;; building Guile-using packages.
1206 (unsetenv "LD_LIBRARY_PATH")))
d9085c23
LC
1207 (builder (add-text-to-store store
1208 (string-append name "-guile-builder")
0bb1aa9e
LC
1209
1210 ;; Explicitly use UTF-8 for determinism,
1211 ;; and also because UTF-8 output is faster.
1212 (with-fluids ((%default-port-encoding
1213 "UTF-8"))
1214 (call-with-output-string
1215 (lambda (port)
1216 (write prologue port)
1217 (write
1218 `(exit
1219 ,(match exp
1220 ((_ ...)
1221 (remove module-form? exp))
1222 (_ `(,exp))))
1223 port))))
7bdd1f0e
LC
1224
1225 ;; The references don't really matter
1226 ;; since the builder is always used in
1227 ;; conjunction with the drv that needs
1228 ;; it. For clarity, we add references
1229 ;; to the subset of INPUTS that are
1230 ;; sources, avoiding references to other
1231 ;; .drv; otherwise, BUILDER's hash would
1232 ;; depend on those, even if they are
1233 ;; fixed-output.
1234 (filter-map source-path inputs)))
1235
d9024884 1236 (mod-drv (and (pair? modules)
e87f0591
LC
1237 (%imported-modules store modules
1238 #:guile guile-drv
1239 #:system system)))
3eb98237 1240 (mod-dir (and mod-drv
59688fc4 1241 (derivation->output-path mod-drv)))
d9024884 1242 (go-drv (and (pair? modules)
e87f0591
LC
1243 (%compiled-modules store modules
1244 #:guile guile-drv
1245 #:system system)))
d9024884 1246 (go-dir (and go-drv
59688fc4 1247 (derivation->output-path go-drv))))
a987d2c0 1248 (derivation store name guile
3eb98237
LC
1249 `("--no-auto-compile"
1250 ,@(if mod-dir `("-L" ,mod-dir) '())
1251 ,builder)
d9024884 1252
a987d2c0
LC
1253 #:system system
1254
1255 #:inputs `((,(or guile-for-build (%guile-for-build)))
1256 (,builder)
1257 ,@(map cdr inputs)
1258 ,@(if mod-drv `((,mod-drv) (,go-drv)) '()))
1259
d9024884
LC
1260 ;; When MODULES is non-empty, shamelessly clobber
1261 ;; $GUILE_LOAD_COMPILED_PATH.
a987d2c0
LC
1262 #:env-vars (if go-dir
1263 `(("GUILE_LOAD_COMPILED_PATH" . ,go-dir)
1264 ,@(alist-delete "GUILE_LOAD_COMPILED_PATH"
1265 env-vars))
1266 env-vars)
1267
9bc07f4d 1268 #:hash hash #:hash-algo hash-algo
36bbbbd1 1269 #:recursive? recursive?
9c629a27 1270 #:outputs outputs
1909431c 1271 #:references-graphs references-graphs
63a42824 1272 #:allowed-references allowed-references
35b5ca78 1273 #:disallowed-references disallowed-references
4a6aeb67
LC
1274 #:local-build? local-build?
1275 #:substitutable? substitutable?)))
e87f0591
LC
1276
1277\f
1278;;;
1279;;; Monadic interface.
1280;;;
1281
1282(define built-derivations
1283 (store-lift build-derivations))