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