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