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