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