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