gnu: valgrind: Don't build on mipsel64-linux.
[jackhill/guix/guix.git] / guix / packages.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
9b5b5c17 2;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
e3ce5d70 3;;;
233e7676 4;;; This file is part of GNU Guix.
e3ce5d70 5;;;
233e7676 6;;; GNU Guix is free software; you can redistribute it and/or modify it
e3ce5d70
LC
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
233e7676 11;;; GNU Guix is distributed in the hope that it will be useful, but
e3ce5d70
LC
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
233e7676 17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
e3ce5d70
LC
18
19(define-module (guix packages)
20 #:use-module (guix utils)
c0cd1b3e 21 #:use-module (guix records)
e3ce5d70 22 #:use-module (guix store)
ddc29a78 23 #:use-module (guix base32)
d510ab46 24 #:use-module (guix derivations)
e3ce5d70
LC
25 #:use-module (guix build-system)
26 #:use-module (ice-9 match)
062c6927 27 #:use-module (srfi srfi-1)
946b72c9 28 #:use-module (srfi srfi-9 gnu)
a63062b5 29 #:use-module (srfi srfi-26)
d36622dc
LC
30 #:use-module (srfi srfi-34)
31 #:use-module (srfi srfi-35)
cd52703a
LC
32 #:re-export (%current-system
33 %current-target-system)
ff352cfb 34 #:export (origin
90c68be8
LC
35 origin?
36 origin-uri
37 origin-method
38 origin-sha256
39 origin-file-name
ac10e0e1
LC
40 origin-patches
41 origin-patch-flags
42 origin-patch-inputs
43 origin-patch-guile
f9cc8971
LC
44 origin-snippet
45 origin-modules
46 origin-imported-modules
e4c245f8 47 base32
e3ce5d70 48
a18eda27
LC
49 <search-path-specification>
50 search-path-specification
51 search-path-specification?
52 search-path-specification->sexp
53
e3ce5d70
LC
54 package
55 package?
56 package-name
57 package-version
2847050a 58 package-full-name
e3ce5d70
LC
59 package-source
60 package-build-system
61 package-arguments
62 package-inputs
63 package-native-inputs
062c6927 64 package-propagated-inputs
e3ce5d70 65 package-outputs
a18eda27 66 package-native-search-paths
e3ce5d70 67 package-search-paths
d45122f5 68 package-synopsis
e3ce5d70 69 package-description
e3ce5d70 70 package-license
52bda18a 71 package-home-page
4e097f86 72 package-supported-systems
e3ce5d70 73 package-maintainers
062c6927 74 package-properties
35f3c5f5 75 package-location
d66c7096 76 package-field-location
e3ce5d70 77
7d193ec3 78 package-direct-inputs
a3d73f59 79 package-transitive-inputs
9c1edabd
LC
80 package-transitive-target-inputs
81 package-transitive-native-inputs
113aef68 82 package-transitive-propagated-inputs
e3ce5d70
LC
83 package-source-derivation
84 package-derivation
d36622dc 85 package-cross-derivation
d510ab46 86 package-output
d36622dc 87
4e097f86
LC
88 %supported-systems
89
d36622dc 90 &package-error
07783858 91 package-error?
d36622dc
LC
92 package-error-package
93 &package-input-error
07783858 94 package-input-error?
9b222abe
LC
95 package-error-invalid-input
96 &package-cross-build-system-error
0d5a559f
LC
97 package-cross-build-system-error?
98
99 package->bag
d3d337d2 100 bag->derivation
0d5a559f
LC
101 bag-transitive-inputs
102 bag-transitive-host-inputs
103 bag-transitive-build-inputs
104 bag-transitive-target-inputs))
e3ce5d70
LC
105
106;;; Commentary:
107;;;
108;;; This module provides a high-level mechanism to define packages in a
109;;; Guix-based distribution.
110;;;
111;;; Code:
112
90c68be8
LC
113;; The source of a package, such as a tarball URL and fetcher---called
114;; "origin" to avoid name clash with `package-source', `source', etc.
115(define-record-type* <origin>
116 origin make-origin
117 origin?
118 (uri origin-uri) ; string
9b5b5c17 119 (method origin-method) ; procedure
90c68be8 120 (sha256 origin-sha256) ; bytevector
ac10e0e1
LC
121 (file-name origin-file-name (default #f)) ; optional file name
122 (patches origin-patches (default '())) ; list of file names
f9cc8971 123 (snippet origin-snippet (default #f)) ; sexp or #f
ac10e0e1
LC
124 (patch-flags origin-patch-flags ; list of strings
125 (default '("-p1")))
1d9bc459
LC
126
127 ;; Patching requires Guile, GNU Patch, and a few more. These two fields are
128 ;; used to specify these dependencies when needed.
ac10e0e1
LC
129 (patch-inputs origin-patch-inputs ; input list or #f
130 (default #f))
f9cc8971
LC
131 (modules origin-modules ; list of module names
132 (default '()))
133 (imported-modules origin-imported-modules ; list of module names
134 (default '()))
1d9bc459 135 (patch-guile origin-patch-guile ; package or #f
ac10e0e1 136 (default #f)))
e3ce5d70 137
f1096964
LC
138(define (print-origin origin port)
139 "Write a concise representation of ORIGIN to PORT."
140 (match origin
141 (($ <origin> uri method sha256 file-name patches)
142 (simple-format port "#<origin ~s ~a ~s ~a>"
143 uri (bytevector->base32-string sha256)
144 patches
145 (number->string (object-address origin) 16)))))
146
147(set-record-type-printer! <origin> print-origin)
148
e4c245f8
LC
149(define-syntax base32
150 (lambda (s)
151 "Return the bytevector corresponding to the given Nix-base32
152representation."
153 (syntax-case s ()
154 ((_ str)
155 (string? (syntax->datum #'str))
aba326f7 156 ;; A literal string: do the conversion at expansion time.
e4c245f8
LC
157 (with-syntax ((bv (nix-base32-string->bytevector
158 (syntax->datum #'str))))
aba326f7
LC
159 #''bv))
160 ((_ str)
161 #'(nix-base32-string->bytevector str)))))
e4c245f8 162
a18eda27
LC
163;; The specification of a search path.
164(define-record-type* <search-path-specification>
165 search-path-specification make-search-path-specification
166 search-path-specification?
167 (variable search-path-specification-variable)
168 (directories search-path-specification-directories)
169 (separator search-path-specification-separator (default ":")))
170
171(define (search-path-specification->sexp spec)
172 "Return an sexp representing SPEC, a <search-path-specification>. The sexp
173corresponds to the arguments expected by `set-path-environment-variable'."
174 (match spec
175 (($ <search-path-specification> variable directories separator)
176 `(,variable ,directories ,separator))))
d36622dc 177
4e097f86
LC
178(define %supported-systems
179 ;; This is the list of system types that are supported. By default, we
180 ;; expect all packages to build successfully here.
181 '("x86_64-linux" "i686-linux" "mips64el-linux"))
182
a18eda27 183;; A package.
e3ce5d70
LC
184(define-record-type* <package>
185 package make-package
186 package?
187 (name package-name) ; string
188 (version package-version) ; string
90c68be8 189 (source package-source) ; <origin> instance
e3ce5d70 190 (build-system package-build-system) ; build system
64fddd74 191 (arguments package-arguments ; arguments for the build method
21c203a5 192 (default '()) (thunked))
062c6927 193
e3ce5d70 194 (inputs package-inputs ; input packages or derivations
dd6b9a37 195 (default '()) (thunked))
062c6927 196 (propagated-inputs package-propagated-inputs ; same, but propagated
9d97a1b3 197 (default '()) (thunked))
e3ce5d70 198 (native-inputs package-native-inputs ; native input packages/derivations
a7dc055b 199 (default '()) (thunked))
c9d01150
LC
200 (self-native-input? package-self-native-input? ; whether to use itself as
201 ; a native input when cross-
202 (default #f)) ; compiling
062c6927 203
e3ce5d70
LC
204 (outputs package-outputs ; list of strings
205 (default '("out")))
a18eda27
LC
206
207 ; lists of
208 ; <search-path-specification>,
209 ; for native and cross
210 ; inputs
211 (native-search-paths package-native-search-paths (default '()))
212 (search-paths package-search-paths (default '()))
e3ce5d70 213
d45122f5
LC
214 (synopsis package-synopsis) ; one-line description
215 (description package-description) ; one or two paragraphs
1fb78cb2 216 (license package-license)
45753b65 217 (home-page package-home-page)
4e097f86
LC
218 (supported-systems package-supported-systems ; list of strings
219 (default %supported-systems))
35f3c5f5 220 (maintainers package-maintainers (default '()))
45753b65 221
062c6927
LC
222 (properties package-properties (default '())) ; alist for anything else
223
35f3c5f5
LC
224 (location package-location
225 (default (and=> (current-source-location)
226 source-properties->location))))
e3ce5d70 227
946b72c9
LC
228(set-record-type-printer! <package>
229 (lambda (package port)
230 (let ((loc (package-location package))
231 (format simple-format))
2e1bafb0 232 (format port "#<package ~a-~a ~a~a>"
946b72c9
LC
233 (package-name package)
234 (package-version package)
2e1bafb0
LC
235 (if loc
236 (format #f "~a:~a "
237 (location-file loc)
238 (location-line loc))
239 "")
946b72c9
LC
240 (number->string (object-address
241 package)
242 16)))))
243
d66c7096 244(define (package-field-location package field)
f903dc05
LC
245 "Return the source code location of the definition of FIELD for PACKAGE, or
246#f if it could not be determined."
247 (define (goto port line column)
248 (unless (and (= (port-column port) (- column 1))
249 (= (port-line port) (- line 1)))
250 (unless (eof-object? (read-char port))
251 (goto port line column))))
d66c7096
LC
252
253 (match (package-location package)
254 (($ <location> file line column)
255 (catch 'system
256 (lambda ()
0b8749b7
LC
257 ;; In general we want to keep relative file names for modules.
258 (with-fluids ((%file-port-name-canonicalization 'relative))
259 (call-with-input-file (search-path %load-path file)
260 (lambda (port)
261 (goto port line column)
262 (match (read port)
263 (('package inits ...)
264 (let ((field (assoc field inits)))
265 (match field
266 ((_ value)
267 ;; Put the `or' here, and not in the first argument of
268 ;; `and=>', to work around a compiler bug in 2.0.5.
269 (or (and=> (source-properties value)
270 source-properties->location)
271 (and=> (source-properties field)
272 source-properties->location)))
273 (_
274 #f))))
275 (_
276 #f))))))
d66c7096 277 (lambda _
f903dc05 278 #f)))
d66c7096
LC
279 (_ #f)))
280
d36622dc
LC
281
282;; Error conditions.
283
284(define-condition-type &package-error &error
285 package-error?
286 (package package-error-package))
287
288(define-condition-type &package-input-error &package-error
289 package-input-error?
290 (input package-error-invalid-input))
291
9b222abe
LC
292(define-condition-type &package-cross-build-system-error &package-error
293 package-cross-build-system-error?)
294
d36622dc 295
2847050a
LC
296(define (package-full-name package)
297 "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
298 (string-append (package-name package) "-" (package-version package)))
299
ac10e0e1
LC
300(define (%standard-patch-inputs)
301 (let ((ref (lambda (module var)
302 (module-ref (resolve-interface module) var))))
303 `(("tar" ,(ref '(gnu packages base) 'tar))
304 ("xz" ,(ref '(gnu packages compression) 'xz))
305 ("bzip2" ,(ref '(gnu packages compression) 'bzip2))
306 ("gzip" ,(ref '(gnu packages compression) 'gzip))
307 ("lzip" ,(ref '(gnu packages compression) 'lzip))
308 ("patch" ,(ref '(gnu packages base) 'patch)))))
309
1d9bc459
LC
310(define (default-guile)
311 "Return the default Guile package for SYSTEM."
bdb36958 312 (let ((distro (resolve-interface '(gnu packages commencement))))
1d9bc459 313 (module-ref distro 'guile-final)))
ac10e0e1 314
f9cc8971 315(define* (patch-and-repack store source patches
ac10e0e1 316 #:key
f9cc8971
LC
317 (inputs '())
318 (snippet #f)
ac10e0e1 319 (flags '("-p1"))
f9cc8971
LC
320 (modules '())
321 (imported-modules '())
ac10e0e1
LC
322 (guile-for-build (%guile-for-build))
323 (system (%current-system)))
f9cc8971
LC
324 "Unpack SOURCE (a derivation or store path), apply all of PATCHES, and
325repack the tarball using the tools listed in INPUTS. When SNIPPET is true,
326it must be an s-expression that will run from within the directory where
327SOURCE was unpacked, after all of PATCHES have been applied. MODULES and
328IMPORTED-MODULES specify modules to use/import for use by SNIPPET."
329 (define source-file-name
330 ;; SOURCE is usually a derivation, but it could be a store file.
331 (if (derivation? source)
332 (derivation->output-path source)
333 source))
334
ac10e0e1 335 (define decompression-type
f9cc8971
LC
336 (cond ((string-suffix? "gz" source-file-name) "gzip")
337 ((string-suffix? "bz2" source-file-name) "bzip2")
338 ((string-suffix? "lz" source-file-name) "lzip")
339 (else "xz")))
ac10e0e1
LC
340
341 (define original-file-name
f9cc8971
LC
342 ;; Remove the store prefix plus the slash, hash, and hyphen.
343 (let* ((sans (string-drop source-file-name
344 (+ (string-length (%store-prefix)) 1)))
345 (dash (string-index sans #\-)))
346 (string-drop sans (+ 1 dash))))
ac10e0e1 347
3ca00bb5
LC
348 (define (numeric-extension? file-name)
349 ;; Return true if FILE-NAME ends with digits.
857ecb3d
LC
350 (and=> (file-extension file-name)
351 (cut string-every char-set:hex-digit <>)))
3ca00bb5
LC
352
353 (define (tarxz-name file-name)
354 ;; Return a '.tar.xz' file name based on FILE-NAME.
355 (let ((base (if (numeric-extension? file-name)
356 original-file-name
357 (file-sans-extension file-name))))
358 (string-append base
359 (if (equal? (file-extension base) "tar")
360 ".xz"
361 ".tar.xz"))))
362
ac10e0e1
LC
363 (define patch-inputs
364 (map (lambda (number patch)
365 (list (string-append "patch" (number->string number))
3f6f7b36
LC
366 (match patch
367 ((? string?)
368 (add-to-store store (basename patch) #t
369 "sha256" patch))
370 ((? origin?)
371 (package-source-derivation store patch)))))
ac10e0e1
LC
372 (iota (length patches))
373
374 patches))
375
376 (define builder
377 `(begin
378 (use-modules (ice-9 ftw)
3ca00bb5
LC
379 (srfi srfi-1)
380 (guix build utils))
ac10e0e1
LC
381
382 (let ((out (assoc-ref %outputs "out"))
383 (xz (assoc-ref %build-inputs "xz"))
384 (decomp (assoc-ref %build-inputs ,decompression-type))
385 (source (assoc-ref %build-inputs "source"))
386 (tar (string-append (assoc-ref %build-inputs "tar")
387 "/bin/tar"))
388 (patch (string-append (assoc-ref %build-inputs "patch")
389 "/bin/patch")))
390 (define (apply-patch input)
391 (let ((patch* (assoc-ref %build-inputs input)))
392 (format (current-error-port) "applying '~a'...~%" patch*)
393 (zero? (system* patch "--batch" ,@flags "--input" patch*))))
394
3ca00bb5
LC
395 (define (first-file directory)
396 ;; Return the name of the first file in DIRECTORY.
397 (car (scandir directory
398 (lambda (name)
399 (not (member name '("." "..")))))))
400
ac10e0e1
LC
401 (setenv "PATH" (string-append xz "/bin" ":"
402 decomp "/bin"))
3ca00bb5
LC
403
404 ;; SOURCE may be either a directory or a tarball.
405 (and (if (file-is-directory? source)
8be3b8a3 406 (let* ((store (or (getenv "NIX_STORE") "/gnu/store"))
3ca00bb5
LC
407 (len (+ 1 (string-length store)))
408 (base (string-drop source len))
409 (dash (string-index base #\-))
410 (directory (string-drop base (+ 1 dash))))
411 (mkdir directory)
412 (copy-recursively source directory)
413 #t)
414 (zero? (system* tar "xvf" source)))
415 (let ((directory (first-file ".")))
ac10e0e1
LC
416 (format (current-error-port)
417 "source is under '~a'~%" directory)
418 (chdir directory)
f9cc8971 419
ac10e0e1 420 (and (every apply-patch ',(map car patch-inputs))
f9cc8971
LC
421
422 ,@(if snippet
423 `((let ((module (make-fresh-user-module)))
424 (module-use-interfaces! module
425 (map resolve-interface
426 ',modules))
427 (module-define! module '%build-inputs
428 %build-inputs)
429 (module-define! module '%outputs %outputs)
430 ((@ (system base compile) compile)
431 ',snippet
432 #:to 'value
433 #:opts %auto-compilation-options
434 #:env module)))
435 '())
436
ac10e0e1
LC
437 (begin (chdir "..") #t)
438 (zero? (system* tar "cvfa" out directory))))))))
439
440
3ca00bb5
LC
441 (let ((name (tarxz-name original-file-name))
442 (inputs (filter-map (match-lambda
443 ((name (? package? p))
444 (and (member name (cons decompression-type
445 '("tar" "xz" "patch")))
446 (list name
447 (package-derivation store p
448 system)))))
449 (or inputs (%standard-patch-inputs))))
450 (modules (delete-duplicates (cons '(guix build utils) modules))))
ac10e0e1 451
3ca00bb5 452 (build-expression->derivation store name builder
dd1a5a15
LC
453 #:inputs `(("source" ,source)
454 ,@inputs
455 ,@patch-inputs)
456 #:system system
3ca00bb5 457 #:modules modules
ac10e0e1
LC
458 #:guile-for-build guile-for-build)))
459
b642e4b8
LC
460(define* (package-source-derivation store source
461 #:optional (system (%current-system)))
462 "Return the derivation path for SOURCE, a package source, for SYSTEM."
e3ce5d70 463 (match source
f9cc8971
LC
464 (($ <origin> uri method sha256 name () #f)
465 ;; No patches, no snippet: this is a fixed-output derivation.
b642e4b8 466 (method store uri 'sha256 sha256 name
7357138b 467 #:system system))
f9cc8971
LC
468 (($ <origin> uri method sha256 name (patches ...) snippet
469 (flags ...) inputs (modules ...) (imported-modules ...)
470 guile-for-build)
471 ;; Patches and/or a snippet.
ac10e0e1 472 (let ((source (method store uri 'sha256 sha256 name
1d9bc459
LC
473 #:system system))
474 (guile (match (or guile-for-build (%guile-for-build)
475 (default-guile))
476 ((? package? p)
477 (package-derivation store p system))
478 ((? derivation? drv)
479 drv))))
f9cc8971
LC
480 (patch-and-repack store source patches
481 #:inputs inputs
482 #:snippet snippet
ac10e0e1
LC
483 #:flags flags
484 #:system system
f9cc8971
LC
485 #:modules modules
486 #:imported-modules modules
1d9bc459 487 #:guile-for-build guile)))
f80594cc 488 ((and (? string?) (? direct-store-path?) file)
7357138b
LC
489 file)
490 ((? string? file)
491 (add-to-store store (basename file) #t "sha256" file))))
e3ce5d70 492
113aef68
LC
493(define (transitive-inputs inputs)
494 (let loop ((inputs inputs)
a3d73f59
LC
495 (result '()))
496 (match inputs
497 (()
498 (delete-duplicates (reverse result))) ; XXX: efficiency
499 (((and i (name (? package? p) sub ...)) rest ...)
500 (let ((t (map (match-lambda
501 ((dep-name derivation ...)
502 (cons (string-append name "/" dep-name)
503 derivation)))
504 (package-propagated-inputs p))))
505 (loop (append t rest)
506 (append t (cons i result)))))
507 ((input rest ...)
508 (loop rest (cons input result))))))
509
7d193ec3
EB
510(define (package-direct-inputs package)
511 "Return all the direct inputs of PACKAGE---i.e, its direct inputs along
512with their propagated inputs."
513 (append (package-native-inputs package)
514 (package-inputs package)
515 (package-propagated-inputs package)))
516
113aef68
LC
517(define (package-transitive-inputs package)
518 "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
519with their propagated inputs, recursively."
7d193ec3 520 (transitive-inputs (package-direct-inputs package)))
113aef68 521
9c1edabd
LC
522(define (package-transitive-target-inputs package)
523 "Return the transitive target inputs of PACKAGE---i.e., its direct inputs
524along with their propagated inputs, recursively. This only includes inputs
525for the target system, and not native inputs."
526 (transitive-inputs (append (package-inputs package)
527 (package-propagated-inputs package))))
528
529(define (package-transitive-native-inputs package)
530 "Return the transitive native inputs of PACKAGE---i.e., its direct inputs
531along with their propagated inputs, recursively. This only includes inputs
532for the host system (\"native inputs\"), and not target inputs."
533 (transitive-inputs (package-native-inputs package)))
534
113aef68
LC
535(define (package-transitive-propagated-inputs package)
536 "Return the propagated inputs of PACKAGE, and their propagated inputs,
537recursively."
538 (transitive-inputs (package-propagated-inputs package)))
539
0d5a559f
LC
540(define (bag-transitive-inputs bag)
541 "Same as 'package-transitive-inputs', but applied to a bag."
542 (transitive-inputs (append (bag-build-inputs bag)
543 (bag-host-inputs bag)
544 (bag-target-inputs bag))))
545
546(define (bag-transitive-build-inputs bag)
547 "Same as 'package-transitive-native-inputs', but applied to a bag."
548 (transitive-inputs (bag-build-inputs bag)))
549
550(define (bag-transitive-host-inputs bag)
551 "Same as 'package-transitive-target-inputs', but applied to a bag."
552 (transitive-inputs (bag-host-inputs bag)))
553
554(define (bag-transitive-target-inputs bag)
555 "Return the \"target inputs\" of BAG, recursively."
556 (transitive-inputs (bag-target-inputs bag)))
557
a2ebaddd
LC
558\f
559;;;
560;;; Package derivations.
561;;;
562
563(define %derivation-cache
564 ;; Package to derivation-path mapping.
e4588af9 565 (make-weak-key-hash-table 100))
a2ebaddd 566
e509d152
LC
567(define (cache package system thunk)
568 "Memoize the return values of THUNK as the derivation of PACKAGE on
569SYSTEM."
bce7526f
LC
570 ;; FIXME: This memoization should be associated with the open store, because
571 ;; otherwise it breaks when switching to a different store.
e509d152
LC
572 (let ((vals (call-with-values thunk list)))
573 ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
574 ;; same value for all structs (as of Guile 2.0.6), and because pointer
575 ;; equality is sufficient in practice.
8dcec914
LC
576 (hashq-set! %derivation-cache package
577 `((,system ,@vals)
578 ,@(or (hashq-ref %derivation-cache package)
579 '())))
e509d152
LC
580 (apply values vals)))
581
582(define-syntax-rule (cached package system body ...)
583 "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
584Return the cached result when available."
8dcec914
LC
585 (let ((thunk (lambda () body ...))
586 (key system))
e509d152
LC
587 (match (hashq-ref %derivation-cache package)
588 ((alist (... ...))
8dcec914 589 (match (assoc-ref alist key)
e509d152
LC
590 ((vals (... ...))
591 (apply values vals))
592 (#f
8dcec914 593 (cache package key thunk))))
e509d152 594 (#f
8dcec914 595 (cache package key thunk)))))
a2ebaddd 596
a63062b5
LC
597(define* (expand-input store package input system #:optional cross-system)
598 "Expand INPUT, an input tuple, such that it contains only references to
599derivation paths or store paths. PACKAGE is only used to provide contextual
600information in exceptions."
592ef6c8
LC
601 (define (intern file)
602 ;; Add FILE to the store. Set the `recursive?' bit to #t, so that
603 ;; file permissions are preserved.
a9ebd9ef 604 (add-to-store store (basename file) #t "sha256" file))
592ef6c8 605
a63062b5
LC
606 (define derivation
607 (if cross-system
608 (cut package-cross-derivation store <> cross-system system)
609 (cut package-derivation store <> system)))
610
611 (match input
612 (((? string? name) (? package? package))
613 (list name (derivation package)))
614 (((? string? name) (? package? package)
615 (? string? sub-drv))
616 (list name (derivation package)
617 sub-drv))
618 (((? string? name)
619 (and (? string?) (? derivation-path?) drv))
620 (list name drv))
621 (((? string? name)
622 (and (? string?) (? file-exists? file)))
623 ;; Add FILE to the store. When FILE is in the sub-directory of a
624 ;; store path, it needs to be added anyway, so it can be used as a
625 ;; source.
626 (list name (intern file)))
627 (((? string? name) (? origin? source))
628 (list name (package-source-derivation store source system)))
629 (x
630 (raise (condition (&package-input-error
631 (package package)
632 (input x)))))))
592ef6c8 633
0d5a559f
LC
634(define* (package->bag package #:optional
635 (system (%current-system))
636 (target (%current-target-system)))
637 "Compile PACKAGE into a bag for SYSTEM, possibly cross-compiled to TARGET,
638and return it."
639 ;; Bind %CURRENT-SYSTEM and %CURRENT-TARGET-SYSTEM so that thunked field
640 ;; values can refer to it.
641 (parameterize ((%current-system system)
642 (%current-target-system target))
643 (match package
644 (($ <package> name version source build-system
645 args inputs propagated-inputs native-inputs self-native-input?
646 outputs)
647 (or (make-bag build-system (package-full-name package)
d3d337d2 648 #:system system
0d5a559f
LC
649 #:target target
650 #:source source
651 #:inputs (append (inputs)
652 (propagated-inputs))
653 #:outputs outputs
654 #:native-inputs `(,@(if (and target self-native-input?)
655 `(("self" ,package))
656 '())
657 ,@(native-inputs))
658 #:arguments (args))
659 (raise (if target
660 (condition
661 (&package-cross-build-system-error
662 (package package)))
663 (condition
664 (&package-error
665 (package package))))))))))
666
d3d337d2
LC
667(define* (bag->derivation store bag
668 #:optional context)
669 "Return the derivation to build BAG for SYSTEM. Optionally, CONTEXT can be
670a package object describing the context in which the call occurs, for improved
671error reporting."
672 (if (bag-target bag)
673 (bag->cross-derivation store bag)
674 (let* ((system (bag-system bag))
675 (inputs (bag-transitive-inputs bag))
676 (input-drvs (map (cut expand-input store context <> system)
677 inputs))
678 (paths (delete-duplicates
679 (append-map (match-lambda
680 ((_ (? package? p) _ ...)
681 (package-native-search-paths
682 p))
683 (_ '()))
684 inputs))))
685
686 (apply (bag-build bag)
687 store (bag-name bag) input-drvs
688 #:search-paths paths
689 #:outputs (bag-outputs bag) #:system system
690 (bag-arguments bag)))))
691
692(define* (bag->cross-derivation store bag
693 #:optional context)
694 "Return the derivation to build BAG, which is actually a cross build.
695Optionally, CONTEXT can be a package object denoting the context of the call.
696This is an internal procedure."
697 (let* ((system (bag-system bag))
698 (target (bag-target bag))
699 (host (bag-transitive-host-inputs bag))
700 (host-drvs (map (cut expand-input store context <> system target)
701 host))
702 (target* (bag-transitive-target-inputs bag))
703 (target-drvs (map (cut expand-input store context <> system)
704 target*))
705 (build (bag-transitive-build-inputs bag))
706 (build-drvs (map (cut expand-input store context <> system)
707 build))
708 (all (append build target* host))
709 (paths (delete-duplicates
710 (append-map (match-lambda
711 ((_ (? package? p) _ ...)
712 (package-search-paths p))
713 (_ '()))
714 all)))
715 (npaths (delete-duplicates
716 (append-map (match-lambda
717 ((_ (? package? p) _ ...)
718 (package-native-search-paths
719 p))
720 (_ '()))
721 all))))
722
723 (apply (bag-build bag)
724 store (bag-name bag)
725 #:native-drvs build-drvs
726 #:target-drvs (append host-drvs target-drvs)
727 #:search-paths paths
728 #:native-search-paths npaths
729 #:outputs (bag-outputs bag)
730 #:system system #:target target
731 (bag-arguments bag))))
732
a63062b5
LC
733(define* (package-derivation store package
734 #:optional (system (%current-system)))
59688fc4
LC
735 "Return the <derivation> object of PACKAGE for SYSTEM."
736
e509d152
LC
737 ;; Compute the derivation and cache the result. Caching is important
738 ;; because some derivations, such as the implicit inputs of the GNU build
739 ;; system, will be queried many, many times in a row.
740 (cached package system
d3d337d2
LC
741 (bag->derivation store (package->bag package system #f)
742 package)))
e3ce5d70 743
9c1edabd 744(define* (package-cross-derivation store package target
a63062b5 745 #:optional (system (%current-system)))
9c1edabd
LC
746 "Cross-build PACKAGE for TARGET (a GNU triplet) from host SYSTEM (a Guix
747system identifying string)."
748 (cached package (cons system target)
d3d337d2
LC
749 (bag->derivation store (package->bag package system target)
750 package)))
d510ab46 751
de8bcdae
LC
752(define* (package-output store package
753 #:optional (output "out") (system (%current-system)))
d510ab46
LC
754 "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
755symbolic output name, such as \"out\". Note that this procedure calls
756`package-derivation', which is costly."
59688fc4
LC
757 (let ((drv (package-derivation store package system)))
758 (derivation->output-path drv output)))