profiles: Store search paths in manifests.
[jackhill/guix/guix.git] / guix / packages.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
e87f0591 2;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
a193b824 3;;; Copyright © 2014 Mark H Weaver <mhw@netris.org>
e3ce5d70 4;;;
233e7676 5;;; This file is part of GNU Guix.
e3ce5d70 6;;;
233e7676 7;;; GNU Guix is free software; you can redistribute it and/or modify it
e3ce5d70
LC
8;;; under the terms of the GNU General Public License as published by
9;;; the Free Software Foundation; either version 3 of the License, or (at
10;;; your option) any later version.
11;;;
233e7676 12;;; GNU Guix is distributed in the hope that it will be useful, but
e3ce5d70
LC
13;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;;; GNU General Public License for more details.
16;;;
17;;; You should have received a copy of the GNU General Public License
233e7676 18;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
e3ce5d70
LC
19
20(define-module (guix packages)
21 #:use-module (guix utils)
c0cd1b3e 22 #:use-module (guix records)
e3ce5d70 23 #:use-module (guix store)
e87f0591 24 #:use-module (guix monads)
ff40e9b7 25 #:use-module (guix gexp)
ddc29a78 26 #:use-module (guix base32)
d510ab46 27 #:use-module (guix derivations)
e3ce5d70 28 #:use-module (guix build-system)
cf87cc89 29 #:use-module (guix gexp)
e3ce5d70 30 #:use-module (ice-9 match)
c37a74bd 31 #:use-module (ice-9 vlist)
062c6927 32 #:use-module (srfi srfi-1)
946b72c9 33 #:use-module (srfi srfi-9 gnu)
05962f29 34 #:use-module (srfi srfi-11)
a63062b5 35 #:use-module (srfi srfi-26)
d36622dc
LC
36 #:use-module (srfi srfi-34)
37 #:use-module (srfi srfi-35)
cd52703a
LC
38 #:re-export (%current-system
39 %current-target-system)
ff352cfb 40 #:export (origin
90c68be8
LC
41 origin?
42 origin-uri
43 origin-method
44 origin-sha256
45 origin-file-name
ac10e0e1
LC
46 origin-patches
47 origin-patch-flags
48 origin-patch-inputs
49 origin-patch-guile
f9cc8971
LC
50 origin-snippet
51 origin-modules
52 origin-imported-modules
e4c245f8 53 base32
e3ce5d70 54
a18eda27
LC
55 <search-path-specification>
56 search-path-specification
57 search-path-specification?
58 search-path-specification->sexp
dedb17ad 59 sexp->search-path-specification
a18eda27 60
e3ce5d70
LC
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
d66c7096 84 package-field-location
e3ce5d70 85
7d193ec3 86 package-direct-inputs
a3d73f59 87 package-transitive-inputs
9c1edabd
LC
88 package-transitive-target-inputs
89 package-transitive-native-inputs
113aef68 90 package-transitive-propagated-inputs
7c3c0374 91 package-transitive-supported-systems
e3ce5d70
LC
92 package-source-derivation
93 package-derivation
d36622dc 94 package-cross-derivation
d510ab46 95 package-output
05962f29 96 package-grafts
d36622dc 97
4e097f86 98 %supported-systems
abcbda48 99 %hydra-supported-systems
bbceb0ef 100 supported-package?
4e097f86 101
d36622dc 102 &package-error
07783858 103 package-error?
d36622dc
LC
104 package-error-package
105 &package-input-error
07783858 106 package-input-error?
9b222abe
LC
107 package-error-invalid-input
108 &package-cross-build-system-error
0d5a559f
LC
109 package-cross-build-system-error?
110
111 package->bag
d3d337d2 112 bag->derivation
cceab875 113 bag-direct-inputs
0d5a559f
LC
114 bag-transitive-inputs
115 bag-transitive-host-inputs
116 bag-transitive-build-inputs
e87f0591
LC
117 bag-transitive-target-inputs
118
119 default-guile
ff40e9b7 120 default-guile-derivation
e87f0591
LC
121 set-guile-for-build
122 package-file
123 package->derivation
124 package->cross-derivation
125 origin->derivation))
e3ce5d70
LC
126
127;;; Commentary:
128;;;
129;;; This module provides a high-level mechanism to define packages in a
130;;; Guix-based distribution.
131;;;
132;;; Code:
133
90c68be8
LC
134;; The source of a package, such as a tarball URL and fetcher---called
135;; "origin" to avoid name clash with `package-source', `source', etc.
136(define-record-type* <origin>
137 origin make-origin
138 origin?
139 (uri origin-uri) ; string
9b5b5c17 140 (method origin-method) ; procedure
90c68be8 141 (sha256 origin-sha256) ; bytevector
ac10e0e1 142 (file-name origin-file-name (default #f)) ; optional file name
6b1f9721
LC
143
144 ;; Patches are delayed so that the 'search-patch' calls are made lazily,
145 ;; which reduces I/O on startup and allows patch-not-found errors to be
146 ;; gracefully handled at run time.
147 (patches origin-patches ; list of file names
148 (default '()) (delayed))
149
f9cc8971 150 (snippet origin-snippet (default #f)) ; sexp or #f
ac10e0e1
LC
151 (patch-flags origin-patch-flags ; list of strings
152 (default '("-p1")))
1d9bc459
LC
153
154 ;; Patching requires Guile, GNU Patch, and a few more. These two fields are
155 ;; used to specify these dependencies when needed.
ac10e0e1
LC
156 (patch-inputs origin-patch-inputs ; input list or #f
157 (default #f))
f9cc8971
LC
158 (modules origin-modules ; list of module names
159 (default '()))
160 (imported-modules origin-imported-modules ; list of module names
161 (default '()))
1d9bc459 162 (patch-guile origin-patch-guile ; package or #f
ac10e0e1 163 (default #f)))
e3ce5d70 164
f1096964
LC
165(define (print-origin origin port)
166 "Write a concise representation of ORIGIN to PORT."
167 (match origin
168 (($ <origin> uri method sha256 file-name patches)
169 (simple-format port "#<origin ~s ~a ~s ~a>"
170 uri (bytevector->base32-string sha256)
6b1f9721 171 (force patches)
f1096964
LC
172 (number->string (object-address origin) 16)))))
173
174(set-record-type-printer! <origin> print-origin)
175
e4c245f8
LC
176(define-syntax base32
177 (lambda (s)
178 "Return the bytevector corresponding to the given Nix-base32
179representation."
180 (syntax-case s ()
181 ((_ str)
182 (string? (syntax->datum #'str))
aba326f7 183 ;; A literal string: do the conversion at expansion time.
e4c245f8
LC
184 (with-syntax ((bv (nix-base32-string->bytevector
185 (syntax->datum #'str))))
aba326f7
LC
186 #''bv))
187 ((_ str)
188 #'(nix-base32-string->bytevector str)))))
e4c245f8 189
a18eda27
LC
190;; The specification of a search path.
191(define-record-type* <search-path-specification>
192 search-path-specification make-search-path-specification
193 search-path-specification?
7b21fe53
LC
194 (variable search-path-specification-variable) ;string
195 (files search-path-specification-files) ;list of strings
196 (separator search-path-specification-separator ;string
197 (default ":"))
198 (file-type search-path-specification-file-type ;symbol
199 (default 'directory))
200 (file-pattern search-path-specification-file-pattern ;#f | string
201 (default #f)))
a18eda27
LC
202
203(define (search-path-specification->sexp spec)
204 "Return an sexp representing SPEC, a <search-path-specification>. The sexp
205corresponds to the arguments expected by `set-path-environment-variable'."
dedb17ad
LC
206 ;; Note that this sexp format is used both by build systems and in
207 ;; (guix profiles), so think twice before you change it.
a18eda27 208 (match spec
7b21fe53
LC
209 (($ <search-path-specification> variable files separator type pattern)
210 `(,variable ,files ,separator ,type ,pattern))))
d36622dc 211
dedb17ad
LC
212(define (sexp->search-path-specification sexp)
213 "Convert SEXP, which is as returned by 'search-path-specification->sexp', to
214a <search-path-specification> object."
215 (match sexp
216 ((variable files separator type pattern)
217 (search-path-specification
218 (variable variable)
219 (files files)
220 (separator separator)
221 (file-type type)
222 (file-pattern pattern)))))
223
4e097f86
LC
224(define %supported-systems
225 ;; This is the list of system types that are supported. By default, we
226 ;; expect all packages to build successfully here.
fc34deea 227 '("x86_64-linux" "i686-linux" "armhf-linux" "mips64el-linux"))
4e097f86 228
abcbda48
LC
229(define %hydra-supported-systems
230 ;; This is the list of system types for which build slaves are available.
231 (delete "armhf-linux" %supported-systems))
232
233
a18eda27 234;; A package.
e3ce5d70
LC
235(define-record-type* <package>
236 package make-package
237 package?
238 (name package-name) ; string
239 (version package-version) ; string
90c68be8 240 (source package-source) ; <origin> instance
e3ce5d70 241 (build-system package-build-system) ; build system
64fddd74 242 (arguments package-arguments ; arguments for the build method
21c203a5 243 (default '()) (thunked))
062c6927 244
e3ce5d70 245 (inputs package-inputs ; input packages or derivations
dd6b9a37 246 (default '()) (thunked))
062c6927 247 (propagated-inputs package-propagated-inputs ; same, but propagated
9d97a1b3 248 (default '()) (thunked))
e3ce5d70 249 (native-inputs package-native-inputs ; native input packages/derivations
a7dc055b 250 (default '()) (thunked))
c9d01150
LC
251 (self-native-input? package-self-native-input? ; whether to use itself as
252 ; a native input when cross-
253 (default #f)) ; compiling
062c6927 254
e3ce5d70
LC
255 (outputs package-outputs ; list of strings
256 (default '("out")))
a18eda27
LC
257
258 ; lists of
259 ; <search-path-specification>,
260 ; for native and cross
261 ; inputs
262 (native-search-paths package-native-search-paths (default '()))
263 (search-paths package-search-paths (default '()))
05962f29
LC
264 (replacement package-replacement ; package | #f
265 (default #f) (thunked))
e3ce5d70 266
d45122f5
LC
267 (synopsis package-synopsis) ; one-line description
268 (description package-description) ; one or two paragraphs
1fb78cb2 269 (license package-license)
45753b65 270 (home-page package-home-page)
4e097f86
LC
271 (supported-systems package-supported-systems ; list of strings
272 (default %supported-systems))
35f3c5f5 273 (maintainers package-maintainers (default '()))
45753b65 274
062c6927
LC
275 (properties package-properties (default '())) ; alist for anything else
276
35f3c5f5
LC
277 (location package-location
278 (default (and=> (current-source-location)
279 source-properties->location))))
e3ce5d70 280
946b72c9
LC
281(set-record-type-printer! <package>
282 (lambda (package port)
283 (let ((loc (package-location package))
284 (format simple-format))
2e1bafb0 285 (format port "#<package ~a-~a ~a~a>"
946b72c9
LC
286 (package-name package)
287 (package-version package)
2e1bafb0
LC
288 (if loc
289 (format #f "~a:~a "
290 (location-file loc)
291 (location-line loc))
292 "")
946b72c9
LC
293 (number->string (object-address
294 package)
295 16)))))
296
d66c7096 297(define (package-field-location package field)
f903dc05
LC
298 "Return the source code location of the definition of FIELD for PACKAGE, or
299#f if it could not be determined."
300 (define (goto port line column)
301 (unless (and (= (port-column port) (- column 1))
302 (= (port-line port) (- line 1)))
303 (unless (eof-object? (read-char port))
304 (goto port line column))))
d66c7096
LC
305
306 (match (package-location package)
307 (($ <location> file line column)
308 (catch 'system
309 (lambda ()
0b8749b7
LC
310 ;; In general we want to keep relative file names for modules.
311 (with-fluids ((%file-port-name-canonicalization 'relative))
312 (call-with-input-file (search-path %load-path file)
313 (lambda (port)
314 (goto port line column)
315 (match (read port)
316 (('package inits ...)
317 (let ((field (assoc field inits)))
318 (match field
319 ((_ value)
320 ;; Put the `or' here, and not in the first argument of
321 ;; `and=>', to work around a compiler bug in 2.0.5.
322 (or (and=> (source-properties value)
323 source-properties->location)
324 (and=> (source-properties field)
325 source-properties->location)))
326 (_
327 #f))))
328 (_
329 #f))))))
d66c7096 330 (lambda _
f903dc05 331 #f)))
d66c7096
LC
332 (_ #f)))
333
d36622dc
LC
334
335;; Error conditions.
336
337(define-condition-type &package-error &error
338 package-error?
339 (package package-error-package))
340
341(define-condition-type &package-input-error &package-error
342 package-input-error?
343 (input package-error-invalid-input))
344
9b222abe
LC
345(define-condition-type &package-cross-build-system-error &package-error
346 package-cross-build-system-error?)
347
d36622dc 348
2847050a
LC
349(define (package-full-name package)
350 "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
351 (string-append (package-name package) "-" (package-version package)))
352
ac10e0e1
LC
353(define (%standard-patch-inputs)
354 (let ((ref (lambda (module var)
355 (module-ref (resolve-interface module) var))))
356 `(("tar" ,(ref '(gnu packages base) 'tar))
357 ("xz" ,(ref '(gnu packages compression) 'xz))
358 ("bzip2" ,(ref '(gnu packages compression) 'bzip2))
359 ("gzip" ,(ref '(gnu packages compression) 'gzip))
360 ("lzip" ,(ref '(gnu packages compression) 'lzip))
17287d7d 361 ("unzip" ,(ref '(gnu packages zip) 'unzip))
9cca706c 362 ("patch" ,(ref '(gnu packages base) 'patch))
ec3b1c57
LC
363 ("locales" ,(ref '(gnu packages commencement)
364 'glibc-utf8-locales-final)))))
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
456 (define (apply-patch patch)
457 (format (current-error-port) "applying '~a'...~%" patch)
458
459 ;; Use '--force' so that patches that do not apply perfectly are
460 ;; rejected.
1590e8a1
LC
461 (zero? (system* (string-append #+patch "/bin/patch")
462 "--force" #+@flags "--input" patch)))
cf87cc89
LC
463
464 (define (first-file directory)
465 ;; Return the name of the first file in DIRECTORY.
466 (car (scandir directory
467 (lambda (name)
468 (not (member name '("." "..")))))))
469
470 ;; Encoding/decoding errors shouldn't be silent.
471 (fluid-set! %default-port-conversion-strategy 'error)
472
1590e8a1 473 (when #+locales
cf87cc89
LC
474 ;; First of all, install a UTF-8 locale so that UTF-8 file names
475 ;; are correctly interpreted. During bootstrap, LOCALES is #f.
1590e8a1 476 (setenv "LOCPATH" (string-append #+locales "/lib/locale"))
cf87cc89
LC
477 (setlocale LC_ALL "en_US.UTF-8"))
478
1590e8a1
LC
479 (setenv "PATH" (string-append #+xz "/bin" ":"
480 #+decomp "/bin"))
cf87cc89
LC
481
482 ;; SOURCE may be either a directory or a tarball.
1590e8a1 483 (and (if (file-is-directory? #+source)
cf87cc89
LC
484 (let* ((store (or (getenv "NIX_STORE") "/gnu/store"))
485 (len (+ 1 (string-length store)))
1590e8a1 486 (base (string-drop #+source len))
cf87cc89
LC
487 (dash (string-index base #\-))
488 (directory (string-drop base (+ 1 dash))))
489 (mkdir directory)
1590e8a1 490 (copy-recursively #+source directory)
cf87cc89 491 #t)
1590e8a1
LC
492 #+(if (string=? decompression-type "unzip")
493 #~(zero? (system* "unzip" #+source))
494 #~(zero? (system* (string-append #+tar "/bin/tar")
495 "xvf" #+source))))
cf87cc89
LC
496 (let ((directory (first-file ".")))
497 (format (current-error-port)
498 "source is under '~a'~%" directory)
499 (chdir directory)
500
1590e8a1
LC
501 (and (every apply-patch '#+patches)
502 #+@(if snippet
cf87cc89
LC
503 #~((let ((module (make-fresh-user-module)))
504 (module-use-interfaces! module
505 (map resolve-interface
1590e8a1 506 '#+modules))
cf87cc89 507 ((@ (system base compile) compile)
1590e8a1 508 '#+snippet
cf87cc89
LC
509 #:to 'value
510 #:opts %auto-compilation-options
511 #:env module)))
512 #~())
513
514 (begin (chdir "..") #t)
1590e8a1 515 (zero? (system* (string-append #+tar "/bin/tar")
cf87cc89
LC
516 "cvfa" #$output directory)))))))
517
518 (let ((name (tarxz-name original-file-name))
519 (modules (delete-duplicates (cons '(guix build utils) modules))))
520 (gexp->derivation name build
521 #:graft? #f
522 #:system system
523 #:modules modules
524 #:guile-for-build guile-for-build))))
ac10e0e1 525
113aef68
LC
526(define (transitive-inputs inputs)
527 (let loop ((inputs inputs)
a3d73f59
LC
528 (result '()))
529 (match inputs
530 (()
531 (delete-duplicates (reverse result))) ; XXX: efficiency
532 (((and i (name (? package? p) sub ...)) rest ...)
533 (let ((t (map (match-lambda
534 ((dep-name derivation ...)
535 (cons (string-append name "/" dep-name)
536 derivation)))
537 (package-propagated-inputs p))))
538 (loop (append t rest)
539 (append t (cons i result)))))
540 ((input rest ...)
541 (loop rest (cons input result))))))
542
7d193ec3
EB
543(define (package-direct-inputs package)
544 "Return all the direct inputs of PACKAGE---i.e, its direct inputs along
545with their propagated inputs."
546 (append (package-native-inputs package)
547 (package-inputs package)
548 (package-propagated-inputs package)))
549
113aef68
LC
550(define (package-transitive-inputs package)
551 "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
552with their propagated inputs, recursively."
7d193ec3 553 (transitive-inputs (package-direct-inputs package)))
113aef68 554
9c1edabd
LC
555(define (package-transitive-target-inputs package)
556 "Return the transitive target inputs of PACKAGE---i.e., its direct inputs
557along with their propagated inputs, recursively. This only includes inputs
558for the target system, and not native inputs."
559 (transitive-inputs (append (package-inputs package)
560 (package-propagated-inputs package))))
561
562(define (package-transitive-native-inputs package)
563 "Return the transitive native inputs of PACKAGE---i.e., its direct inputs
564along with their propagated inputs, recursively. This only includes inputs
565for the host system (\"native inputs\"), and not target inputs."
566 (transitive-inputs (package-native-inputs package)))
567
113aef68
LC
568(define (package-transitive-propagated-inputs package)
569 "Return the propagated inputs of PACKAGE, and their propagated inputs,
570recursively."
571 (transitive-inputs (package-propagated-inputs package)))
572
a193b824
MW
573(define-syntax define-memoized/v
574 (lambda (form)
575 "Define a memoized single-valued unary procedure with docstring.
576The procedure argument is compared to cached keys using `eqv?'."
577 (syntax-case form ()
578 ((_ (proc arg) docstring body body* ...)
579 (string? (syntax->datum #'docstring))
580 #'(define proc
581 (let ((cache (make-hash-table)))
582 (define (proc arg)
583 docstring
584 (match (hashv-get-handle cache arg)
585 ((_ . value)
586 value)
587 (_
588 (let ((result (let () body body* ...)))
589 (hashv-set! cache arg result)
590 result))))
591 proc))))))
c37a74bd 592
a193b824 593(define-memoized/v (package-transitive-supported-systems package)
7c3c0374
LC
594 "Return the intersection of the systems supported by PACKAGE and those
595supported by its dependencies."
a193b824
MW
596 (fold (lambda (input systems)
597 (match input
598 ((label (? package? p) . _)
599 (lset-intersection
600 string=? systems (package-transitive-supported-systems p)))
601 (_
602 systems)))
603 (package-supported-systems package)
9bf3ced0 604 (bag-direct-inputs (package->bag package))))
7c3c0374 605
bbceb0ef
LC
606(define* (supported-package? package #:optional (system (%current-system)))
607 "Return true if PACKAGE is supported on SYSTEM--i.e., if PACKAGE and all its
608dependencies are known to build on SYSTEM."
609 (member system (package-transitive-supported-systems package)))
610
cceab875
LC
611(define (bag-direct-inputs bag)
612 "Same as 'package-direct-inputs', but applied to a bag."
613 (append (bag-build-inputs bag)
614 (bag-host-inputs bag)
615 (bag-target-inputs bag)))
616
0d5a559f
LC
617(define (bag-transitive-inputs bag)
618 "Same as 'package-transitive-inputs', but applied to a bag."
cceab875 619 (transitive-inputs (bag-direct-inputs bag)))
0d5a559f
LC
620
621(define (bag-transitive-build-inputs bag)
622 "Same as 'package-transitive-native-inputs', but applied to a bag."
623 (transitive-inputs (bag-build-inputs bag)))
624
625(define (bag-transitive-host-inputs bag)
626 "Same as 'package-transitive-target-inputs', but applied to a bag."
627 (transitive-inputs (bag-host-inputs bag)))
628
629(define (bag-transitive-target-inputs bag)
630 "Return the \"target inputs\" of BAG, recursively."
631 (transitive-inputs (bag-target-inputs bag)))
632
a2ebaddd
LC
633\f
634;;;
635;;; Package derivations.
636;;;
637
638(define %derivation-cache
639 ;; Package to derivation-path mapping.
e4588af9 640 (make-weak-key-hash-table 100))
a2ebaddd 641
e509d152
LC
642(define (cache package system thunk)
643 "Memoize the return values of THUNK as the derivation of PACKAGE on
644SYSTEM."
bce7526f
LC
645 ;; FIXME: This memoization should be associated with the open store, because
646 ;; otherwise it breaks when switching to a different store.
e509d152
LC
647 (let ((vals (call-with-values thunk list)))
648 ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
649 ;; same value for all structs (as of Guile 2.0.6), and because pointer
650 ;; equality is sufficient in practice.
8dcec914
LC
651 (hashq-set! %derivation-cache package
652 `((,system ,@vals)
653 ,@(or (hashq-ref %derivation-cache package)
654 '())))
e509d152
LC
655 (apply values vals)))
656
657(define-syntax-rule (cached package system body ...)
658 "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
659Return the cached result when available."
8dcec914
LC
660 (let ((thunk (lambda () body ...))
661 (key system))
e509d152
LC
662 (match (hashq-ref %derivation-cache package)
663 ((alist (... ...))
8dcec914 664 (match (assoc-ref alist key)
e509d152
LC
665 ((vals (... ...))
666 (apply values vals))
667 (#f
8dcec914 668 (cache package key thunk))))
e509d152 669 (#f
8dcec914 670 (cache package key thunk)))))
a2ebaddd 671
a63062b5
LC
672(define* (expand-input store package input system #:optional cross-system)
673 "Expand INPUT, an input tuple, such that it contains only references to
674derivation paths or store paths. PACKAGE is only used to provide contextual
675information in exceptions."
592ef6c8
LC
676 (define (intern file)
677 ;; Add FILE to the store. Set the `recursive?' bit to #t, so that
678 ;; file permissions are preserved.
a9ebd9ef 679 (add-to-store store (basename file) #t "sha256" file))
592ef6c8 680
a63062b5
LC
681 (define derivation
682 (if cross-system
05962f29
LC
683 (cut package-cross-derivation store <> cross-system system
684 #:graft? #f)
685 (cut package-derivation store <> system #:graft? #f)))
a63062b5
LC
686
687 (match input
688 (((? string? name) (? package? package))
689 (list name (derivation package)))
690 (((? string? name) (? package? package)
691 (? string? sub-drv))
692 (list name (derivation package)
693 sub-drv))
694 (((? string? name)
695 (and (? string?) (? derivation-path?) drv))
696 (list name drv))
697 (((? string? name)
698 (and (? string?) (? file-exists? file)))
699 ;; Add FILE to the store. When FILE is in the sub-directory of a
700 ;; store path, it needs to be added anyway, so it can be used as a
701 ;; source.
702 (list name (intern file)))
703 (((? string? name) (? origin? source))
704 (list name (package-source-derivation store source system)))
705 (x
706 (raise (condition (&package-input-error
707 (package package)
708 (input x)))))))
592ef6c8 709
0d5a559f
LC
710(define* (package->bag package #:optional
711 (system (%current-system))
05962f29
LC
712 (target (%current-target-system))
713 #:key (graft? (%graft?)))
0d5a559f
LC
714 "Compile PACKAGE into a bag for SYSTEM, possibly cross-compiled to TARGET,
715and return it."
716 ;; Bind %CURRENT-SYSTEM and %CURRENT-TARGET-SYSTEM so that thunked field
717 ;; values can refer to it.
718 (parameterize ((%current-system system)
719 (%current-target-system target))
05962f29
LC
720 (match (if graft?
721 (or (package-replacement package) package)
722 package)
0d5a559f
LC
723 (($ <package> name version source build-system
724 args inputs propagated-inputs native-inputs self-native-input?
725 outputs)
05962f29 726 (or (make-bag build-system (string-append name "-" version)
d3d337d2 727 #:system system
0d5a559f
LC
728 #:target target
729 #:source source
730 #:inputs (append (inputs)
731 (propagated-inputs))
732 #:outputs outputs
733 #:native-inputs `(,@(if (and target self-native-input?)
734 `(("self" ,package))
735 '())
736 ,@(native-inputs))
737 #:arguments (args))
738 (raise (if target
739 (condition
740 (&package-cross-build-system-error
741 (package package)))
742 (condition
743 (&package-error
744 (package package))))))))))
745
05962f29
LC
746(define (input-graft store system)
747 "Return a procedure that, given an input referring to a package with a
748graft, returns a pair with the original derivation and the graft's derivation,
749and returns #f for other inputs."
750 (match-lambda
751 ((label (? package? package) sub-drv ...)
752 (let ((replacement (package-replacement package)))
753 (and replacement
754 (let ((orig (package-derivation store package system
755 #:graft? #f))
756 (new (package-derivation store replacement system)))
757 (graft
758 (origin orig)
759 (replacement new)
760 (origin-output (match sub-drv
761 (() "out")
762 ((output) output)))
763 (replacement-output origin-output))))))
764 (x
765 #f)))
766
767(define (input-cross-graft store target system)
768 "Same as 'input-graft', but for cross-compilation inputs."
769 (match-lambda
770 ((label (? package? package) sub-drv ...)
771 (let ((replacement (package-replacement package)))
772 (and replacement
773 (let ((orig (package-cross-derivation store package target system
774 #:graft? #f))
775 (new (package-cross-derivation store replacement
776 target system)))
777 (graft
778 (origin orig)
779 (replacement new)
780 (origin-output (match sub-drv
781 (() "out")
782 ((output) output)))
783 (replacement-output origin-output))))))
784 (_
785 #f)))
786
787(define* (bag-grafts store bag)
788 "Return the list of grafts applicable to BAG. Each graft is a <graft>
789record."
790 (let ((target (bag-target bag))
791 (system (bag-system bag)))
792 (define native-grafts
793 (filter-map (input-graft store system)
794 (append (bag-transitive-build-inputs bag)
795 (bag-transitive-target-inputs bag)
796 (if target
797 '()
798 (bag-transitive-host-inputs bag)))))
799
800 (define target-grafts
801 (if target
802 (filter-map (input-cross-graft store target system)
803 (bag-transitive-host-inputs bag))
804 '()))
805
806 (append native-grafts target-grafts)))
807
808(define* (package-grafts store package
809 #:optional (system (%current-system))
810 #:key target)
811 "Return the list of grafts applicable to PACKAGE as built for SYSTEM and
812TARGET."
813 (let* ((package (or (package-replacement package) package))
814 (bag (package->bag package system target)))
815 (bag-grafts store bag)))
816
d3d337d2
LC
817(define* (bag->derivation store bag
818 #:optional context)
819 "Return the derivation to build BAG for SYSTEM. Optionally, CONTEXT can be
820a package object describing the context in which the call occurs, for improved
821error reporting."
822 (if (bag-target bag)
823 (bag->cross-derivation store bag)
824 (let* ((system (bag-system bag))
825 (inputs (bag-transitive-inputs bag))
826 (input-drvs (map (cut expand-input store context <> system)
827 inputs))
828 (paths (delete-duplicates
829 (append-map (match-lambda
830 ((_ (? package? p) _ ...)
831 (package-native-search-paths
832 p))
833 (_ '()))
834 inputs))))
835
836 (apply (bag-build bag)
837 store (bag-name bag) input-drvs
838 #:search-paths paths
839 #:outputs (bag-outputs bag) #:system system
840 (bag-arguments bag)))))
841
842(define* (bag->cross-derivation store bag
843 #:optional context)
844 "Return the derivation to build BAG, which is actually a cross build.
845Optionally, CONTEXT can be a package object denoting the context of the call.
846This is an internal procedure."
847 (let* ((system (bag-system bag))
848 (target (bag-target bag))
849 (host (bag-transitive-host-inputs bag))
850 (host-drvs (map (cut expand-input store context <> system target)
851 host))
852 (target* (bag-transitive-target-inputs bag))
853 (target-drvs (map (cut expand-input store context <> system)
854 target*))
855 (build (bag-transitive-build-inputs bag))
856 (build-drvs (map (cut expand-input store context <> system)
857 build))
858 (all (append build target* host))
859 (paths (delete-duplicates
860 (append-map (match-lambda
861 ((_ (? package? p) _ ...)
862 (package-search-paths p))
863 (_ '()))
864 all)))
865 (npaths (delete-duplicates
866 (append-map (match-lambda
867 ((_ (? package? p) _ ...)
868 (package-native-search-paths
869 p))
870 (_ '()))
871 all))))
872
873 (apply (bag-build bag)
874 store (bag-name bag)
875 #:native-drvs build-drvs
876 #:target-drvs (append host-drvs target-drvs)
877 #:search-paths paths
878 #:native-search-paths npaths
879 #:outputs (bag-outputs bag)
880 #:system system #:target target
881 (bag-arguments bag))))
882
a63062b5 883(define* (package-derivation store package
05962f29
LC
884 #:optional (system (%current-system))
885 #:key (graft? (%graft?)))
59688fc4
LC
886 "Return the <derivation> object of PACKAGE for SYSTEM."
887
e509d152
LC
888 ;; Compute the derivation and cache the result. Caching is important
889 ;; because some derivations, such as the implicit inputs of the GNU build
890 ;; system, will be queried many, many times in a row.
05962f29
LC
891 (cached package (cons system graft?)
892 (let* ((bag (package->bag package system #f #:graft? graft?))
893 (drv (bag->derivation store bag package)))
894 (if graft?
895 (match (bag-grafts store bag)
896 (()
897 drv)
898 (grafts
899 (let ((guile (package-derivation store (default-guile)
900 system #:graft? #f)))
901 (graft-derivation store (bag-name bag) drv grafts
902 #:system system
903 #:guile guile))))
904 drv))))
e3ce5d70 905
9c1edabd 906(define* (package-cross-derivation store package target
05962f29
LC
907 #:optional (system (%current-system))
908 #:key (graft? (%graft?)))
9c1edabd
LC
909 "Cross-build PACKAGE for TARGET (a GNU triplet) from host SYSTEM (a Guix
910system identifying string)."
05962f29
LC
911 (cached package (list system target graft?)
912 (let* ((bag (package->bag package system target #:graft? graft?))
913 (drv (bag->derivation store bag package)))
914 (if graft?
915 (match (bag-grafts store bag)
916 (()
917 drv)
918 (grafts
919 (graft-derivation store (bag-name bag) drv grafts
920 #:system system
921 #:guile
922 (package-derivation store (default-guile)
923 system #:graft? #f))))
924 drv))))
d510ab46 925
de8bcdae
LC
926(define* (package-output store package
927 #:optional (output "out") (system (%current-system)))
d510ab46
LC
928 "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
929symbolic output name, such as \"out\". Note that this procedure calls
930`package-derivation', which is costly."
59688fc4
LC
931 (let ((drv (package-derivation store package system)))
932 (derivation->output-path drv output)))
e87f0591
LC
933
934\f
935;;;
936;;; Monadic interface.
937;;;
938
939(define (set-guile-for-build guile)
940 "This monadic procedure changes the Guile currently used to run the build
941code of derivations to GUILE, a package object."
942 (lambda (store)
943 (let ((guile (package-derivation store guile)))
4e190c28 944 (values (%guile-for-build guile) store))))
e87f0591
LC
945
946(define* (package-file package
947 #:optional file
948 #:key
949 system (output "out") target)
950 "Return as a monadic value the absolute file name of FILE within the
951OUTPUT directory of PACKAGE. When FILE is omitted, return the name of the
952OUTPUT directory of PACKAGE. When TARGET is true, use it as a
953cross-compilation target triplet."
954 (lambda (store)
955 (define compute-derivation
956 (if target
957 (cut package-cross-derivation <> <> target <>)
958 package-derivation))
959
960 (let* ((system (or system (%current-system)))
961 (drv (compute-derivation store package system))
962 (out (derivation->output-path drv output)))
4e190c28
LC
963 (values (if file
964 (string-append out "/" file)
965 out)
966 store))))
e87f0591
LC
967
968(define package->derivation
969 (store-lift package-derivation))
970
971(define package->cross-derivation
972 (store-lift package-cross-derivation))
973
ff40e9b7
LC
974(define-gexp-compiler (package-compiler (package package?) system target)
975 ;; Compile PACKAGE to a derivation for SYSTEM, optionally cross-compiled for
976 ;; TARGET. This is used when referring to a package from within a gexp.
977 (if target
978 (package->cross-derivation package target system)
979 (package->derivation package system)))
980
f220a838
LC
981(define* (origin->derivation source
982 #:optional (system (%current-system)))
983 "When SOURCE is an <origin> object, return its derivation for SYSTEM. When
984SOURCE is a file name, return either the interned file name (if SOURCE is
985outside of the store) or SOURCE itself (if SOURCE is already a store item.)"
986 (match source
6b1f9721 987 (($ <origin> uri method sha256 name (= force ()) #f)
f220a838
LC
988 ;; No patches, no snippet: this is a fixed-output derivation.
989 (method uri 'sha256 sha256 name #:system system))
6b1f9721 990 (($ <origin> uri method sha256 name (= force (patches ...)) snippet
f220a838
LC
991 (flags ...) inputs (modules ...) (imported-modules ...)
992 guile-for-build)
993 ;; Patches and/or a snippet.
994 (mlet %store-monad ((source (method uri 'sha256 sha256 name
995 #:system system))
996 (guile (package->derivation (or guile-for-build
997 (default-guile))
998 system
999 #:graft? #f)))
cf87cc89
LC
1000 (patch-and-repack source patches
1001 #:inputs inputs
1002 #:snippet snippet
1003 #:flags flags
1004 #:system system
1005 #:modules modules
1006 #:imported-modules modules
1007 #:guile-for-build guile)))
f220a838
LC
1008 ((and (? string?) (? direct-store-path?) file)
1009 (with-monad %store-monad
1010 (return file)))
1011 ((? string? file)
1012 (interned-file file (basename file)
1013 #:recursive? #t))))
1014
ff40e9b7
LC
1015(define-gexp-compiler (origin-compiler (origin origin?) system target)
1016 ;; Compile ORIGIN to a derivation for SYSTEM. This is used when referring
1017 ;; to an origin from within a gexp.
1018 (origin->derivation origin system))
1019
f220a838
LC
1020(define package-source-derivation
1021 (store-lower origin->derivation))