grafts: Use dependency information from substitutes when possible.
[jackhill/guix/guix.git] / guix / packages.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
7adf9b84 2;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
2e9511df 3;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
a6d0b306 4;;; Copyright © 2015 Eric Bavier <bavier@member.fsf.org>
e3ce5d70 5;;;
233e7676 6;;; This file is part of GNU Guix.
e3ce5d70 7;;;
233e7676 8;;; GNU Guix is free software; you can redistribute it and/or modify it
e3ce5d70
LC
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
233e7676 13;;; GNU Guix is distributed in the hope that it will be useful, but
e3ce5d70
LC
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
233e7676 19;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
e3ce5d70
LC
20
21(define-module (guix packages)
22 #:use-module (guix utils)
c0cd1b3e 23 #:use-module (guix records)
e3ce5d70 24 #:use-module (guix store)
e87f0591 25 #:use-module (guix monads)
ff40e9b7 26 #:use-module (guix gexp)
ddc29a78 27 #:use-module (guix base32)
7adf9b84 28 #:use-module (guix grafts)
d510ab46 29 #:use-module (guix derivations)
e3ce5d70 30 #:use-module (guix build-system)
e89431bf 31 #:use-module (guix search-paths)
cf87cc89 32 #:use-module (guix gexp)
c22a1324 33 #:use-module (guix sets)
e3ce5d70 34 #:use-module (ice-9 match)
c37a74bd 35 #:use-module (ice-9 vlist)
062c6927 36 #:use-module (srfi srfi-1)
946b72c9 37 #:use-module (srfi srfi-9 gnu)
05962f29 38 #:use-module (srfi srfi-11)
a63062b5 39 #:use-module (srfi srfi-26)
d36622dc
LC
40 #:use-module (srfi srfi-34)
41 #:use-module (srfi srfi-35)
3b4d0103 42 #:use-module (web uri)
cd52703a 43 #:re-export (%current-system
e89431bf
LC
44 %current-target-system
45 search-path-specification) ;for convenience
ff352cfb 46 #:export (origin
90c68be8
LC
47 origin?
48 origin-uri
49 origin-method
50 origin-sha256
51 origin-file-name
3b4d0103 52 origin-actual-file-name
ac10e0e1
LC
53 origin-patches
54 origin-patch-flags
55 origin-patch-inputs
56 origin-patch-guile
f9cc8971
LC
57 origin-snippet
58 origin-modules
59 origin-imported-modules
e4c245f8 60 base32
e3ce5d70
LC
61
62 package
63 package?
64 package-name
65 package-version
2847050a 66 package-full-name
e3ce5d70
LC
67 package-source
68 package-build-system
69 package-arguments
70 package-inputs
71 package-native-inputs
062c6927 72 package-propagated-inputs
e3ce5d70 73 package-outputs
a18eda27 74 package-native-search-paths
e3ce5d70 75 package-search-paths
05962f29 76 package-replacement
d45122f5 77 package-synopsis
e3ce5d70 78 package-description
e3ce5d70 79 package-license
52bda18a 80 package-home-page
4e097f86 81 package-supported-systems
e3ce5d70 82 package-maintainers
062c6927 83 package-properties
35f3c5f5 84 package-location
d66c7096 85 package-field-location
e3ce5d70 86
f77bcbc3
EB
87 package-direct-sources
88 package-transitive-sources
7d193ec3 89 package-direct-inputs
a3d73f59 90 package-transitive-inputs
9c1edabd
LC
91 package-transitive-target-inputs
92 package-transitive-native-inputs
113aef68 93 package-transitive-propagated-inputs
aa8e0515 94 package-transitive-native-search-paths
7c3c0374 95 package-transitive-supported-systems
e3ce5d70
LC
96 package-source-derivation
97 package-derivation
d36622dc 98 package-cross-derivation
d510ab46 99 package-output
05962f29 100 package-grafts
d36622dc 101
a6d0b306
EB
102 transitive-input-references
103
4e097f86 104 %supported-systems
035b6ff7 105 %hurd-systems
abcbda48 106 %hydra-supported-systems
bbceb0ef 107 supported-package?
4e097f86 108
d36622dc 109 &package-error
07783858 110 package-error?
d36622dc
LC
111 package-error-package
112 &package-input-error
07783858 113 package-input-error?
9b222abe
LC
114 package-error-invalid-input
115 &package-cross-build-system-error
0d5a559f
LC
116 package-cross-build-system-error?
117
118 package->bag
d3d337d2 119 bag->derivation
cceab875 120 bag-direct-inputs
0d5a559f
LC
121 bag-transitive-inputs
122 bag-transitive-host-inputs
123 bag-transitive-build-inputs
e87f0591
LC
124 bag-transitive-target-inputs
125
126 default-guile
ff40e9b7 127 default-guile-derivation
e87f0591
LC
128 set-guile-for-build
129 package-file
130 package->derivation
131 package->cross-derivation
132 origin->derivation))
e3ce5d70
LC
133
134;;; Commentary:
135;;;
136;;; This module provides a high-level mechanism to define packages in a
137;;; Guix-based distribution.
138;;;
139;;; Code:
140
90c68be8
LC
141;; The source of a package, such as a tarball URL and fetcher---called
142;; "origin" to avoid name clash with `package-source', `source', etc.
143(define-record-type* <origin>
144 origin make-origin
145 origin?
146 (uri origin-uri) ; string
9b5b5c17 147 (method origin-method) ; procedure
90c68be8 148 (sha256 origin-sha256) ; bytevector
ac10e0e1 149 (file-name origin-file-name (default #f)) ; optional file name
6b1f9721
LC
150
151 ;; Patches are delayed so that the 'search-patch' calls are made lazily,
152 ;; which reduces I/O on startup and allows patch-not-found errors to be
153 ;; gracefully handled at run time.
154 (patches origin-patches ; list of file names
155 (default '()) (delayed))
156
f9cc8971 157 (snippet origin-snippet (default #f)) ; sexp or #f
ac10e0e1
LC
158 (patch-flags origin-patch-flags ; list of strings
159 (default '("-p1")))
1d9bc459
LC
160
161 ;; Patching requires Guile, GNU Patch, and a few more. These two fields are
162 ;; used to specify these dependencies when needed.
ac10e0e1
LC
163 (patch-inputs origin-patch-inputs ; input list or #f
164 (default #f))
f9cc8971
LC
165 (modules origin-modules ; list of module names
166 (default '()))
167 (imported-modules origin-imported-modules ; list of module names
168 (default '()))
1d9bc459 169 (patch-guile origin-patch-guile ; package or #f
ac10e0e1 170 (default #f)))
e3ce5d70 171
f1096964
LC
172(define (print-origin origin port)
173 "Write a concise representation of ORIGIN to PORT."
174 (match origin
175 (($ <origin> uri method sha256 file-name patches)
176 (simple-format port "#<origin ~s ~a ~s ~a>"
177 uri (bytevector->base32-string sha256)
6b1f9721 178 (force patches)
f1096964
LC
179 (number->string (object-address origin) 16)))))
180
181(set-record-type-printer! <origin> print-origin)
182
e4c245f8
LC
183(define-syntax base32
184 (lambda (s)
185 "Return the bytevector corresponding to the given Nix-base32
186representation."
187 (syntax-case s ()
188 ((_ str)
189 (string? (syntax->datum #'str))
aba326f7 190 ;; A literal string: do the conversion at expansion time.
e4c245f8
LC
191 (with-syntax ((bv (nix-base32-string->bytevector
192 (syntax->datum #'str))))
aba326f7
LC
193 #''bv))
194 ((_ str)
195 #'(nix-base32-string->bytevector str)))))
e4c245f8 196
3b4d0103
EB
197(define (origin-actual-file-name origin)
198 "Return the file name of ORIGIN, either its 'file-name' field or the file
199name of its URI."
200 (define (uri->file-name uri)
201 ;; Return the 'base name' of URI or URI itself, where URI is a string.
202 (let ((path (and=> (string->uri uri) uri-path)))
203 (if path
204 (basename path)
205 uri)))
206
207 (or (origin-file-name origin)
208 (match (origin-uri origin)
209 ((head . tail)
210 (uri->file-name head))
211 ((? string? uri)
212 (uri->file-name uri))
213 (else
214 ;; git, svn, cvs, etc. reference
215 #f))))
216
4e097f86
LC
217(define %supported-systems
218 ;; This is the list of system types that are supported. By default, we
219 ;; expect all packages to build successfully here.
fc34deea 220 '("x86_64-linux" "i686-linux" "armhf-linux" "mips64el-linux"))
4e097f86 221
035b6ff7
LC
222(define %hurd-systems
223 ;; The GNU/Hurd systems for which support is being developed.
224 '("i585-gnu" "i686-gnu"))
225
abcbda48
LC
226(define %hydra-supported-systems
227 ;; This is the list of system types for which build slaves are available.
52c20d8e 228 %supported-systems)
abcbda48
LC
229
230
a18eda27 231;; A package.
e3ce5d70
LC
232(define-record-type* <package>
233 package make-package
234 package?
235 (name package-name) ; string
236 (version package-version) ; string
90c68be8 237 (source package-source) ; <origin> instance
e3ce5d70 238 (build-system package-build-system) ; build system
64fddd74 239 (arguments package-arguments ; arguments for the build method
21c203a5 240 (default '()) (thunked))
062c6927 241
e3ce5d70 242 (inputs package-inputs ; input packages or derivations
dd6b9a37 243 (default '()) (thunked))
062c6927 244 (propagated-inputs package-propagated-inputs ; same, but propagated
9d97a1b3 245 (default '()) (thunked))
e3ce5d70 246 (native-inputs package-native-inputs ; native input packages/derivations
a7dc055b 247 (default '()) (thunked))
c9d01150
LC
248 (self-native-input? package-self-native-input? ; whether to use itself as
249 ; a native input when cross-
250 (default #f)) ; compiling
062c6927 251
e3ce5d70
LC
252 (outputs package-outputs ; list of strings
253 (default '("out")))
a18eda27
LC
254
255 ; lists of
256 ; <search-path-specification>,
257 ; for native and cross
258 ; inputs
259 (native-search-paths package-native-search-paths (default '()))
260 (search-paths package-search-paths (default '()))
05962f29
LC
261 (replacement package-replacement ; package | #f
262 (default #f) (thunked))
e3ce5d70 263
d45122f5
LC
264 (synopsis package-synopsis) ; one-line description
265 (description package-description) ; one or two paragraphs
1fb78cb2 266 (license package-license)
45753b65 267 (home-page package-home-page)
4e097f86
LC
268 (supported-systems package-supported-systems ; list of strings
269 (default %supported-systems))
35f3c5f5 270 (maintainers package-maintainers (default '()))
45753b65 271
062c6927
LC
272 (properties package-properties (default '())) ; alist for anything else
273
35f3c5f5
LC
274 (location package-location
275 (default (and=> (current-source-location)
0004c590
LC
276 source-properties->location))
277 (innate)))
e3ce5d70 278
946b72c9
LC
279(set-record-type-printer! <package>
280 (lambda (package port)
281 (let ((loc (package-location package))
282 (format simple-format))
74e667d1 283 (format port "#<package ~a@~a ~a~a>"
946b72c9
LC
284 (package-name package)
285 (package-version package)
2e1bafb0
LC
286 (if loc
287 (format #f "~a:~a "
288 (location-file loc)
289 (location-line loc))
290 "")
946b72c9
LC
291 (number->string (object-address
292 package)
293 16)))))
294
d66c7096 295(define (package-field-location package field)
f903dc05
LC
296 "Return the source code location of the definition of FIELD for PACKAGE, or
297#f if it could not be determined."
298 (define (goto port line column)
299 (unless (and (= (port-column port) (- column 1))
300 (= (port-line port) (- line 1)))
301 (unless (eof-object? (read-char port))
302 (goto port line column))))
d66c7096
LC
303
304 (match (package-location package)
305 (($ <location> file line column)
306 (catch 'system
307 (lambda ()
0b8749b7
LC
308 ;; In general we want to keep relative file names for modules.
309 (with-fluids ((%file-port-name-canonicalization 'relative))
310 (call-with-input-file (search-path %load-path file)
311 (lambda (port)
312 (goto port line column)
313 (match (read port)
314 (('package inits ...)
315 (let ((field (assoc field inits)))
316 (match field
317 ((_ value)
318 ;; Put the `or' here, and not in the first argument of
319 ;; `and=>', to work around a compiler bug in 2.0.5.
320 (or (and=> (source-properties value)
321 source-properties->location)
322 (and=> (source-properties field)
323 source-properties->location)))
324 (_
325 #f))))
326 (_
327 #f))))))
d66c7096 328 (lambda _
f903dc05 329 #f)))
d66c7096
LC
330 (_ #f)))
331
d36622dc
LC
332
333;; Error conditions.
334
335(define-condition-type &package-error &error
336 package-error?
337 (package package-error-package))
338
339(define-condition-type &package-input-error &package-error
340 package-input-error?
341 (input package-error-invalid-input))
342
9b222abe
LC
343(define-condition-type &package-cross-build-system-error &package-error
344 package-cross-build-system-error?)
345
d36622dc 346
2847050a
LC
347(define (package-full-name package)
348 "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
349 (string-append (package-name package) "-" (package-version package)))
350
ac10e0e1 351(define (%standard-patch-inputs)
5ae4169c
LC
352 (let* ((canonical (module-ref (resolve-interface '(gnu packages base))
353 'canonical-package))
354 (ref (lambda (module var)
355 (canonical
356 (module-ref (resolve-interface module) var)))))
ac10e0e1
LC
357 `(("tar" ,(ref '(gnu packages base) 'tar))
358 ("xz" ,(ref '(gnu packages compression) 'xz))
359 ("bzip2" ,(ref '(gnu packages compression) 'bzip2))
360 ("gzip" ,(ref '(gnu packages compression) 'gzip))
361 ("lzip" ,(ref '(gnu packages compression) 'lzip))
17287d7d 362 ("unzip" ,(ref '(gnu packages zip) 'unzip))
9cca706c 363 ("patch" ,(ref '(gnu packages base) 'patch))
5ae4169c 364 ("locales" ,(ref '(gnu packages base) 'glibc-utf8-locales)))))
ac10e0e1 365
1d9bc459 366(define (default-guile)
e87f0591
LC
367 "Return the default Guile package used to run the build code of
368derivations."
bdb36958 369 (let ((distro (resolve-interface '(gnu packages commencement))))
1d9bc459 370 (module-ref distro 'guile-final)))
ac10e0e1 371
ff40e9b7
LC
372(define* (default-guile-derivation #:optional (system (%current-system)))
373 "Return the derivation for SYSTEM of the default Guile package used to run
374the build code of derivation."
375 (package->derivation (default-guile) system
376 #:graft? #f))
377
cf87cc89 378(define* (patch-and-repack source patches
ac10e0e1 379 #:key
a158484d 380 inputs
f9cc8971 381 (snippet #f)
ac10e0e1 382 (flags '("-p1"))
f9cc8971
LC
383 (modules '())
384 (imported-modules '())
ac10e0e1
LC
385 (guile-for-build (%guile-for-build))
386 (system (%current-system)))
f9cc8971
LC
387 "Unpack SOURCE (a derivation or store path), apply all of PATCHES, and
388repack the tarball using the tools listed in INPUTS. When SNIPPET is true,
389it must be an s-expression that will run from within the directory where
390SOURCE was unpacked, after all of PATCHES have been applied. MODULES and
391IMPORTED-MODULES specify modules to use/import for use by SNIPPET."
392 (define source-file-name
393 ;; SOURCE is usually a derivation, but it could be a store file.
394 (if (derivation? source)
395 (derivation->output-path source)
396 source))
397
a158484d
LC
398 (define lookup-input
399 ;; The default value of the 'patch-inputs' field, and thus INPUTS is #f,
400 ;; so deal with that.
401 (let ((inputs (or inputs (%standard-patch-inputs))))
402 (lambda (name)
403 (match (assoc-ref inputs name)
404 ((package) package)
405 (#f #f)))))
cf87cc89 406
ac10e0e1 407 (define decompression-type
f9cc8971
LC
408 (cond ((string-suffix? "gz" source-file-name) "gzip")
409 ((string-suffix? "bz2" source-file-name) "bzip2")
410 ((string-suffix? "lz" source-file-name) "lzip")
17287d7d 411 ((string-suffix? "zip" source-file-name) "unzip")
f9cc8971 412 (else "xz")))
ac10e0e1
LC
413
414 (define original-file-name
f9cc8971
LC
415 ;; Remove the store prefix plus the slash, hash, and hyphen.
416 (let* ((sans (string-drop source-file-name
417 (+ (string-length (%store-prefix)) 1)))
418 (dash (string-index sans #\-)))
419 (string-drop sans (+ 1 dash))))
ac10e0e1 420
3ca00bb5
LC
421 (define (numeric-extension? file-name)
422 ;; Return true if FILE-NAME ends with digits.
857ecb3d
LC
423 (and=> (file-extension file-name)
424 (cut string-every char-set:hex-digit <>)))
3ca00bb5
LC
425
426 (define (tarxz-name file-name)
427 ;; Return a '.tar.xz' file name based on FILE-NAME.
428 (let ((base (if (numeric-extension? file-name)
429 original-file-name
430 (file-sans-extension file-name))))
431 (string-append base
432 (if (equal? (file-extension base) "tar")
433 ".xz"
434 ".tar.xz"))))
435
cf87cc89
LC
436 (define instantiate-patch
437 (match-lambda
438 ((? string? patch)
439 (interned-file patch #:recursive? #t))
440 ((? origin? patch)
441 (origin->derivation patch system))))
442
443 (mlet %store-monad ((tar -> (lookup-input "tar"))
444 (xz -> (lookup-input "xz"))
445 (patch -> (lookup-input "patch"))
446 (locales -> (lookup-input "locales"))
447 (decomp -> (lookup-input decompression-type))
448 (patches (sequence %store-monad
449 (map instantiate-patch patches))))
450 (define build
451 #~(begin
452 (use-modules (ice-9 ftw)
453 (srfi srfi-1)
454 (guix build utils))
455
140b4bc6
MW
456 ;; The --sort option was added to GNU tar in version 1.28, released
457 ;; 2014-07-28. During bootstrap we must cope with older versions.
458 (define tar-supports-sort?
459 (zero? (system* (string-append #+tar "/bin/tar")
460 "cf" "/dev/null" "--files-from=/dev/null"
461 "--sort=name")))
462
cf87cc89
LC
463 (define (apply-patch patch)
464 (format (current-error-port) "applying '~a'...~%" patch)
465
466 ;; Use '--force' so that patches that do not apply perfectly are
467 ;; rejected.
1590e8a1
LC
468 (zero? (system* (string-append #+patch "/bin/patch")
469 "--force" #+@flags "--input" patch)))
cf87cc89
LC
470
471 (define (first-file directory)
472 ;; Return the name of the first file in DIRECTORY.
473 (car (scandir directory
474 (lambda (name)
475 (not (member name '("." "..")))))))
476
477 ;; Encoding/decoding errors shouldn't be silent.
478 (fluid-set! %default-port-conversion-strategy 'error)
479
1590e8a1 480 (when #+locales
cf87cc89
LC
481 ;; First of all, install a UTF-8 locale so that UTF-8 file names
482 ;; are correctly interpreted. During bootstrap, LOCALES is #f.
85b81cf8
LC
483 (setenv "LOCPATH"
484 (string-append #+locales "/lib/locale/"
485 #+(and locales
486 (package-version locales))))
afd3d931 487 (setlocale LC_ALL "en_US.utf8"))
cf87cc89 488
1590e8a1
LC
489 (setenv "PATH" (string-append #+xz "/bin" ":"
490 #+decomp "/bin"))
cf87cc89
LC
491
492 ;; SOURCE may be either a directory or a tarball.
1590e8a1 493 (and (if (file-is-directory? #+source)
2fdcc607 494 (let* ((store (%store-directory))
cf87cc89 495 (len (+ 1 (string-length store)))
1590e8a1 496 (base (string-drop #+source len))
cf87cc89
LC
497 (dash (string-index base #\-))
498 (directory (string-drop base (+ 1 dash))))
499 (mkdir directory)
1590e8a1 500 (copy-recursively #+source directory)
cf87cc89 501 #t)
1590e8a1
LC
502 #+(if (string=? decompression-type "unzip")
503 #~(zero? (system* "unzip" #+source))
504 #~(zero? (system* (string-append #+tar "/bin/tar")
505 "xvf" #+source))))
cf87cc89
LC
506 (let ((directory (first-file ".")))
507 (format (current-error-port)
508 "source is under '~a'~%" directory)
509 (chdir directory)
510
1590e8a1
LC
511 (and (every apply-patch '#+patches)
512 #+@(if snippet
cf87cc89
LC
513 #~((let ((module (make-fresh-user-module)))
514 (module-use-interfaces! module
515 (map resolve-interface
1590e8a1 516 '#+modules))
cf87cc89 517 ((@ (system base compile) compile)
1590e8a1 518 '#+snippet
cf87cc89
LC
519 #:to 'value
520 #:opts %auto-compilation-options
521 #:env module)))
522 #~())
523
524 (begin (chdir "..") #t)
140b4bc6
MW
525
526 (unless tar-supports-sort?
527 (call-with-output-file ".file_list"
528 (lambda (port)
529 (for-each (lambda (name) (format port "~a~%" name))
530 (find-files directory
531 #:directories? #t
532 #:fail-on-error? #t)))))
533 (zero? (apply system* (string-append #+tar "/bin/tar")
534 "cvfa" #$output
535 ;; avoid non-determinism in the archive
536 "--mtime=@0"
537 "--owner=root:0"
538 "--group=root:0"
539 (if tar-supports-sort?
540 `("--sort=name"
541 ,directory)
542 '("--no-recursion"
543 "--files-from=.file_list")))))))))
cf87cc89
LC
544
545 (let ((name (tarxz-name original-file-name))
546 (modules (delete-duplicates (cons '(guix build utils) modules))))
547 (gexp->derivation name build
548 #:graft? #f
549 #:system system
550 #:modules modules
551 #:guile-for-build guile-for-build))))
ac10e0e1 552
113aef68 553(define (transitive-inputs inputs)
161094c8
LC
554 "Return the closure of INPUTS when considering the 'propagated-inputs'
555edges. Omit duplicate inputs, except for those already present in INPUTS
556itself.
557
558This is implemented as a breadth-first traversal such that INPUTS is
559preserved, and only duplicate propagated inputs are removed."
560 (define (seen? seen item outputs)
561 (match (vhash-assq item seen)
562 ((_ . o) (equal? o outputs))
563 (_ #f)))
564
565 (let loop ((inputs inputs)
566 (result '())
567 (propagated '())
568 (first? #t)
569 (seen vlist-null))
a3d73f59
LC
570 (match inputs
571 (()
161094c8
LC
572 (if (null? propagated)
573 (reverse result)
574 (loop (reverse (concatenate propagated)) result '() #f seen)))
575 (((and input (label (? package? package) outputs ...)) rest ...)
576 (if (and (not first?) (seen? seen package outputs))
577 (loop rest result propagated first? seen)
578 (loop rest
579 (cons input result)
580 (cons (package-propagated-inputs package) propagated)
581 first?
582 (vhash-consq package outputs seen))))
a3d73f59 583 ((input rest ...)
161094c8 584 (loop rest (cons input result) propagated first? seen)))))
a3d73f59 585
f77bcbc3
EB
586(define (package-direct-sources package)
587 "Return all source origins associated with PACKAGE; including origins in
588PACKAGE's inputs."
589 `(,@(or (and=> (package-source package) list) '())
590 ,@(filter-map (match-lambda
591 ((_ (? origin? orig) _ ...)
592 orig)
593 (_ #f))
594 (package-direct-inputs package))))
595
596(define (package-transitive-sources package)
597 "Return PACKAGE's direct sources, and their direct sources, recursively."
598 (delete-duplicates
599 (concatenate (filter-map (match-lambda
600 ((_ (? origin? orig) _ ...)
601 (list orig))
602 ((_ (? package? p) _ ...)
603 (package-direct-sources p))
604 (_ #f))
605 (bag-transitive-inputs
606 (package->bag package))))))
607
7d193ec3
EB
608(define (package-direct-inputs package)
609 "Return all the direct inputs of PACKAGE---i.e, its direct inputs along
610with their propagated inputs."
611 (append (package-native-inputs package)
612 (package-inputs package)
613 (package-propagated-inputs package)))
614
113aef68
LC
615(define (package-transitive-inputs package)
616 "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
617with their propagated inputs, recursively."
7d193ec3 618 (transitive-inputs (package-direct-inputs package)))
113aef68 619
9c1edabd
LC
620(define (package-transitive-target-inputs package)
621 "Return the transitive target inputs of PACKAGE---i.e., its direct inputs
622along with their propagated inputs, recursively. This only includes inputs
623for the target system, and not native inputs."
624 (transitive-inputs (append (package-inputs package)
625 (package-propagated-inputs package))))
626
627(define (package-transitive-native-inputs package)
628 "Return the transitive native inputs of PACKAGE---i.e., its direct inputs
629along with their propagated inputs, recursively. This only includes inputs
630for the host system (\"native inputs\"), and not target inputs."
631 (transitive-inputs (package-native-inputs package)))
632
113aef68
LC
633(define (package-transitive-propagated-inputs package)
634 "Return the propagated inputs of PACKAGE, and their propagated inputs,
635recursively."
636 (transitive-inputs (package-propagated-inputs package)))
637
aa8e0515
LC
638(define (package-transitive-native-search-paths package)
639 "Return the list of search paths for PACKAGE and its propagated inputs,
640recursively."
641 (append (package-native-search-paths package)
642 (append-map (match-lambda
643 ((label (? package? p) _ ...)
644 (package-native-search-paths p))
645 (_
646 '()))
647 (package-transitive-propagated-inputs package))))
648
a6d0b306
EB
649(define (transitive-input-references alist inputs)
650 "Return a list of (assoc-ref ALIST <label>) for each (<label> <package> . _)
651in INPUTS and their transitive propagated inputs."
652 (define label
653 (match-lambda
654 ((label . _)
655 label)))
656
657 (map (lambda (input)
658 `(assoc-ref ,alist ,(label input)))
659 (transitive-inputs inputs)))
660
a193b824
MW
661(define-syntax define-memoized/v
662 (lambda (form)
663 "Define a memoized single-valued unary procedure with docstring.
664The procedure argument is compared to cached keys using `eqv?'."
665 (syntax-case form ()
666 ((_ (proc arg) docstring body body* ...)
667 (string? (syntax->datum #'docstring))
668 #'(define proc
669 (let ((cache (make-hash-table)))
670 (define (proc arg)
671 docstring
672 (match (hashv-get-handle cache arg)
673 ((_ . value)
674 value)
675 (_
676 (let ((result (let () body body* ...)))
677 (hashv-set! cache arg result)
678 result))))
679 proc))))))
c37a74bd 680
a193b824 681(define-memoized/v (package-transitive-supported-systems package)
7c3c0374
LC
682 "Return the intersection of the systems supported by PACKAGE and those
683supported by its dependencies."
a193b824
MW
684 (fold (lambda (input systems)
685 (match input
686 ((label (? package? p) . _)
687 (lset-intersection
688 string=? systems (package-transitive-supported-systems p)))
689 (_
690 systems)))
691 (package-supported-systems package)
9bf3ced0 692 (bag-direct-inputs (package->bag package))))
7c3c0374 693
bbceb0ef
LC
694(define* (supported-package? package #:optional (system (%current-system)))
695 "Return true if PACKAGE is supported on SYSTEM--i.e., if PACKAGE and all its
696dependencies are known to build on SYSTEM."
697 (member system (package-transitive-supported-systems package)))
698
cceab875
LC
699(define (bag-direct-inputs bag)
700 "Same as 'package-direct-inputs', but applied to a bag."
701 (append (bag-build-inputs bag)
702 (bag-host-inputs bag)
703 (bag-target-inputs bag)))
704
0d5a559f
LC
705(define (bag-transitive-inputs bag)
706 "Same as 'package-transitive-inputs', but applied to a bag."
cceab875 707 (transitive-inputs (bag-direct-inputs bag)))
0d5a559f
LC
708
709(define (bag-transitive-build-inputs bag)
710 "Same as 'package-transitive-native-inputs', but applied to a bag."
711 (transitive-inputs (bag-build-inputs bag)))
712
713(define (bag-transitive-host-inputs bag)
714 "Same as 'package-transitive-target-inputs', but applied to a bag."
715 (transitive-inputs (bag-host-inputs bag)))
716
717(define (bag-transitive-target-inputs bag)
718 "Return the \"target inputs\" of BAG, recursively."
719 (transitive-inputs (bag-target-inputs bag)))
720
a2ebaddd
LC
721\f
722;;;
723;;; Package derivations.
724;;;
725
726(define %derivation-cache
727 ;; Package to derivation-path mapping.
e4588af9 728 (make-weak-key-hash-table 100))
a2ebaddd 729
e509d152
LC
730(define (cache package system thunk)
731 "Memoize the return values of THUNK as the derivation of PACKAGE on
732SYSTEM."
bce7526f
LC
733 ;; FIXME: This memoization should be associated with the open store, because
734 ;; otherwise it breaks when switching to a different store.
e509d152
LC
735 (let ((vals (call-with-values thunk list)))
736 ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
737 ;; same value for all structs (as of Guile 2.0.6), and because pointer
738 ;; equality is sufficient in practice.
8dcec914
LC
739 (hashq-set! %derivation-cache package
740 `((,system ,@vals)
741 ,@(or (hashq-ref %derivation-cache package)
742 '())))
e509d152
LC
743 (apply values vals)))
744
745(define-syntax-rule (cached package system body ...)
746 "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
747Return the cached result when available."
8dcec914
LC
748 (let ((thunk (lambda () body ...))
749 (key system))
e509d152
LC
750 (match (hashq-ref %derivation-cache package)
751 ((alist (... ...))
8dcec914 752 (match (assoc-ref alist key)
e509d152
LC
753 ((vals (... ...))
754 (apply values vals))
755 (#f
8dcec914 756 (cache package key thunk))))
e509d152 757 (#f
8dcec914 758 (cache package key thunk)))))
a2ebaddd 759
a63062b5
LC
760(define* (expand-input store package input system #:optional cross-system)
761 "Expand INPUT, an input tuple, such that it contains only references to
762derivation paths or store paths. PACKAGE is only used to provide contextual
763information in exceptions."
592ef6c8
LC
764 (define (intern file)
765 ;; Add FILE to the store. Set the `recursive?' bit to #t, so that
766 ;; file permissions are preserved.
a9ebd9ef 767 (add-to-store store (basename file) #t "sha256" file))
592ef6c8 768
a63062b5
LC
769 (define derivation
770 (if cross-system
05962f29
LC
771 (cut package-cross-derivation store <> cross-system system
772 #:graft? #f)
773 (cut package-derivation store <> system #:graft? #f)))
a63062b5
LC
774
775 (match input
776 (((? string? name) (? package? package))
777 (list name (derivation package)))
778 (((? string? name) (? package? package)
779 (? string? sub-drv))
780 (list name (derivation package)
781 sub-drv))
782 (((? string? name)
783 (and (? string?) (? derivation-path?) drv))
784 (list name drv))
785 (((? string? name)
786 (and (? string?) (? file-exists? file)))
787 ;; Add FILE to the store. When FILE is in the sub-directory of a
788 ;; store path, it needs to be added anyway, so it can be used as a
789 ;; source.
790 (list name (intern file)))
791 (((? string? name) (? origin? source))
792 (list name (package-source-derivation store source system)))
793 (x
794 (raise (condition (&package-input-error
795 (package package)
796 (input x)))))))
592ef6c8 797
0d5a559f
LC
798(define* (package->bag package #:optional
799 (system (%current-system))
05962f29
LC
800 (target (%current-target-system))
801 #:key (graft? (%graft?)))
0d5a559f
LC
802 "Compile PACKAGE into a bag for SYSTEM, possibly cross-compiled to TARGET,
803and return it."
804 ;; Bind %CURRENT-SYSTEM and %CURRENT-TARGET-SYSTEM so that thunked field
805 ;; values can refer to it.
806 (parameterize ((%current-system system)
807 (%current-target-system target))
05962f29
LC
808 (match (if graft?
809 (or (package-replacement package) package)
810 package)
0d5a559f
LC
811 (($ <package> name version source build-system
812 args inputs propagated-inputs native-inputs self-native-input?
813 outputs)
05962f29 814 (or (make-bag build-system (string-append name "-" version)
d3d337d2 815 #:system system
0d5a559f
LC
816 #:target target
817 #:source source
818 #:inputs (append (inputs)
819 (propagated-inputs))
820 #:outputs outputs
821 #:native-inputs `(,@(if (and target self-native-input?)
822 `(("self" ,package))
823 '())
824 ,@(native-inputs))
825 #:arguments (args))
826 (raise (if target
827 (condition
828 (&package-cross-build-system-error
829 (package package)))
830 (condition
831 (&package-error
832 (package package))))))))))
833
05962f29 834(define (input-graft store system)
c22a1324
LC
835 "Return a procedure that, given a package with a graft, returns a graft, and
836#f otherwise."
05962f29 837 (match-lambda
c22a1324
LC
838 ((? package? package)
839 (let ((replacement (package-replacement package)))
840 (and replacement
841 (let ((orig (package-derivation store package system
842 #:graft? #f))
843 (new (package-derivation store replacement system)))
844 (graft
845 (origin orig)
846 (replacement new))))))
847 (x
848 #f)))
05962f29
LC
849
850(define (input-cross-graft store target system)
851 "Same as 'input-graft', but for cross-compilation inputs."
852 (match-lambda
c22a1324 853 ((? package? package)
05962f29
LC
854 (let ((replacement (package-replacement package)))
855 (and replacement
856 (let ((orig (package-cross-derivation store package target system
857 #:graft? #f))
858 (new (package-cross-derivation store replacement
859 target system)))
860 (graft
861 (origin orig)
c22a1324 862 (replacement new))))))
05962f29
LC
863 (_
864 #f)))
865
c22a1324
LC
866(define* (fold-bag-dependencies proc seed bag
867 #:key (native? #t))
868 "Fold PROC over the packages BAG depends on. Each package is visited only
869once, in depth-first order. If NATIVE? is true, restrict to native
870dependencies; otherwise, restrict to target dependencies."
871 (define nodes
872 (match (if native?
873 (append (bag-build-inputs bag)
874 (bag-target-inputs bag)
875 (if (bag-target bag)
876 '()
877 (bag-host-inputs bag)))
878 (bag-host-inputs bag))
879 (((labels things _ ...) ...)
880 things)))
881
882 (let loop ((nodes nodes)
883 (result seed)
884 (visited (setq)))
885 (match nodes
886 (()
887 result)
888 (((? package? head) . tail)
889 (if (set-contains? visited head)
890 (loop tail result visited)
891 (let ((inputs (bag-direct-inputs (package->bag head))))
892 (loop (match inputs
893 (((labels things _ ...) ...)
894 (append things tail)))
895 (proc head result)
896 (set-insert head visited)))))
897 ((head . tail)
898 (loop tail result visited)))))
899
05962f29 900(define* (bag-grafts store bag)
c22a1324
LC
901 "Return the list of grafts potentially applicable to BAG. Potentially
902applicable grafts are collected by looking at direct or indirect dependencies
903of BAG that have a 'replacement'. Whether a graft is actually applicable
904depends on whether the outputs of BAG depend on the items the grafts refer
905to (see 'graft-derivation'.)"
906 (define system (bag-system bag))
907 (define target (bag-target bag))
908
909 (define native-grafts
910 (let ((->graft (input-graft store system)))
911 (fold-bag-dependencies (lambda (package grafts)
912 (match (->graft package)
913 (#f grafts)
914 (graft (cons graft grafts))))
915 '()
916 bag)))
917
918 (define target-grafts
919 (if target
920 (let ((->graft (input-cross-graft store target system)))
921 (fold-bag-dependencies (lambda (package grafts)
922 (match (->graft package)
923 (#f grafts)
924 (graft (cons graft grafts))))
925 '()
926 bag
927 #:native? #f))
928 '()))
929
930 (append native-grafts target-grafts))
05962f29
LC
931
932(define* (package-grafts store package
933 #:optional (system (%current-system))
934 #:key target)
935 "Return the list of grafts applicable to PACKAGE as built for SYSTEM and
936TARGET."
937 (let* ((package (or (package-replacement package) package))
938 (bag (package->bag package system target)))
939 (bag-grafts store bag)))
940
d3d337d2
LC
941(define* (bag->derivation store bag
942 #:optional context)
943 "Return the derivation to build BAG for SYSTEM. Optionally, CONTEXT can be
944a package object describing the context in which the call occurs, for improved
945error reporting."
946 (if (bag-target bag)
947 (bag->cross-derivation store bag)
948 (let* ((system (bag-system bag))
949 (inputs (bag-transitive-inputs bag))
950 (input-drvs (map (cut expand-input store context <> system)
951 inputs))
952 (paths (delete-duplicates
953 (append-map (match-lambda
954 ((_ (? package? p) _ ...)
955 (package-native-search-paths
956 p))
957 (_ '()))
958 inputs))))
959
960 (apply (bag-build bag)
961 store (bag-name bag) input-drvs
962 #:search-paths paths
963 #:outputs (bag-outputs bag) #:system system
964 (bag-arguments bag)))))
965
966(define* (bag->cross-derivation store bag
967 #:optional context)
968 "Return the derivation to build BAG, which is actually a cross build.
969Optionally, CONTEXT can be a package object denoting the context of the call.
970This is an internal procedure."
971 (let* ((system (bag-system bag))
972 (target (bag-target bag))
973 (host (bag-transitive-host-inputs bag))
974 (host-drvs (map (cut expand-input store context <> system target)
975 host))
976 (target* (bag-transitive-target-inputs bag))
977 (target-drvs (map (cut expand-input store context <> system)
978 target*))
979 (build (bag-transitive-build-inputs bag))
980 (build-drvs (map (cut expand-input store context <> system)
981 build))
982 (all (append build target* host))
983 (paths (delete-duplicates
984 (append-map (match-lambda
985 ((_ (? package? p) _ ...)
986 (package-search-paths p))
987 (_ '()))
988 all)))
989 (npaths (delete-duplicates
990 (append-map (match-lambda
991 ((_ (? package? p) _ ...)
992 (package-native-search-paths
993 p))
994 (_ '()))
995 all))))
996
997 (apply (bag-build bag)
998 store (bag-name bag)
999 #:native-drvs build-drvs
1000 #:target-drvs (append host-drvs target-drvs)
1001 #:search-paths paths
1002 #:native-search-paths npaths
1003 #:outputs (bag-outputs bag)
1004 #:system system #:target target
1005 (bag-arguments bag))))
1006
a63062b5 1007(define* (package-derivation store package
05962f29
LC
1008 #:optional (system (%current-system))
1009 #:key (graft? (%graft?)))
59688fc4
LC
1010 "Return the <derivation> object of PACKAGE for SYSTEM."
1011
e509d152
LC
1012 ;; Compute the derivation and cache the result. Caching is important
1013 ;; because some derivations, such as the implicit inputs of the GNU build
1014 ;; system, will be queried many, many times in a row.
05962f29
LC
1015 (cached package (cons system graft?)
1016 (let* ((bag (package->bag package system #f #:graft? graft?))
1017 (drv (bag->derivation store bag package)))
1018 (if graft?
1019 (match (bag-grafts store bag)
1020 (()
1021 drv)
1022 (grafts
1023 (let ((guile (package-derivation store (default-guile)
1024 system #:graft? #f)))
c22a1324
LC
1025 ;; TODO: As an optimization, we can simply graft the tip
1026 ;; of the derivation graph since 'graft-derivation'
1027 ;; recurses anyway.
b0fef4d6 1028 (graft-derivation store drv grafts
05962f29
LC
1029 #:system system
1030 #:guile guile))))
1031 drv))))
e3ce5d70 1032
9c1edabd 1033(define* (package-cross-derivation store package target
05962f29
LC
1034 #:optional (system (%current-system))
1035 #:key (graft? (%graft?)))
9c1edabd
LC
1036 "Cross-build PACKAGE for TARGET (a GNU triplet) from host SYSTEM (a Guix
1037system identifying string)."
05962f29
LC
1038 (cached package (list system target graft?)
1039 (let* ((bag (package->bag package system target #:graft? graft?))
1040 (drv (bag->derivation store bag package)))
1041 (if graft?
1042 (match (bag-grafts store bag)
1043 (()
1044 drv)
1045 (grafts
b0fef4d6 1046 (graft-derivation store drv grafts
05962f29
LC
1047 #:system system
1048 #:guile
1049 (package-derivation store (default-guile)
1050 system #:graft? #f))))
1051 drv))))
d510ab46 1052
de8bcdae
LC
1053(define* (package-output store package
1054 #:optional (output "out") (system (%current-system)))
d510ab46
LC
1055 "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
1056symbolic output name, such as \"out\". Note that this procedure calls
1057`package-derivation', which is costly."
59688fc4
LC
1058 (let ((drv (package-derivation store package system)))
1059 (derivation->output-path drv output)))
e87f0591
LC
1060
1061\f
1062;;;
1063;;; Monadic interface.
1064;;;
1065
1066(define (set-guile-for-build guile)
1067 "This monadic procedure changes the Guile currently used to run the build
1068code of derivations to GUILE, a package object."
1069 (lambda (store)
1070 (let ((guile (package-derivation store guile)))
4e190c28 1071 (values (%guile-for-build guile) store))))
e87f0591
LC
1072
1073(define* (package-file package
1074 #:optional file
1075 #:key
1076 system (output "out") target)
1077 "Return as a monadic value the absolute file name of FILE within the
1078OUTPUT directory of PACKAGE. When FILE is omitted, return the name of the
1079OUTPUT directory of PACKAGE. When TARGET is true, use it as a
1080cross-compilation target triplet."
1081 (lambda (store)
1082 (define compute-derivation
1083 (if target
1084 (cut package-cross-derivation <> <> target <>)
1085 package-derivation))
1086
1087 (let* ((system (or system (%current-system)))
1088 (drv (compute-derivation store package system))
1089 (out (derivation->output-path drv output)))
4e190c28
LC
1090 (values (if file
1091 (string-append out "/" file)
1092 out)
1093 store))))
e87f0591
LC
1094
1095(define package->derivation
1096 (store-lift package-derivation))
1097
1098(define package->cross-derivation
1099 (store-lift package-cross-derivation))
1100
ff40e9b7
LC
1101(define-gexp-compiler (package-compiler (package package?) system target)
1102 ;; Compile PACKAGE to a derivation for SYSTEM, optionally cross-compiled for
1103 ;; TARGET. This is used when referring to a package from within a gexp.
1104 (if target
1105 (package->cross-derivation package target system)
1106 (package->derivation package system)))
1107
f220a838
LC
1108(define* (origin->derivation source
1109 #:optional (system (%current-system)))
1110 "When SOURCE is an <origin> object, return its derivation for SYSTEM. When
1111SOURCE is a file name, return either the interned file name (if SOURCE is
1112outside of the store) or SOURCE itself (if SOURCE is already a store item.)"
1113 (match source
6b1f9721 1114 (($ <origin> uri method sha256 name (= force ()) #f)
f220a838
LC
1115 ;; No patches, no snippet: this is a fixed-output derivation.
1116 (method uri 'sha256 sha256 name #:system system))
6b1f9721 1117 (($ <origin> uri method sha256 name (= force (patches ...)) snippet
f220a838
LC
1118 (flags ...) inputs (modules ...) (imported-modules ...)
1119 guile-for-build)
1120 ;; Patches and/or a snippet.
1121 (mlet %store-monad ((source (method uri 'sha256 sha256 name
1122 #:system system))
1123 (guile (package->derivation (or guile-for-build
1124 (default-guile))
1125 system
1126 #:graft? #f)))
cf87cc89
LC
1127 (patch-and-repack source patches
1128 #:inputs inputs
1129 #:snippet snippet
1130 #:flags flags
1131 #:system system
1132 #:modules modules
1133 #:imported-modules modules
1134 #:guile-for-build guile)))
f220a838
LC
1135 ((and (? string?) (? direct-store-path?) file)
1136 (with-monad %store-monad
1137 (return file)))
1138 ((? string? file)
1139 (interned-file file (basename file)
1140 #:recursive? #t))))
1141
ff40e9b7
LC
1142(define-gexp-compiler (origin-compiler (origin origin?) system target)
1143 ;; Compile ORIGIN to a derivation for SYSTEM. This is used when referring
1144 ;; to an origin from within a gexp.
1145 (origin->derivation origin system))
1146
f220a838
LC
1147(define package-source-derivation
1148 (store-lower origin->derivation))