tests: Clarify filtering of the "debug" output.
[jackhill/guix/guix.git] / guix / packages.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
aba326f7 2;;; Copyright © 2012, 2013 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)
d510ab46 29 #:use-module (srfi srfi-11)
a63062b5 30 #:use-module (srfi srfi-26)
d36622dc
LC
31 #:use-module (srfi srfi-34)
32 #:use-module (srfi srfi-35)
cd52703a
LC
33 #:re-export (%current-system
34 %current-target-system)
ff352cfb 35 #:export (origin
90c68be8
LC
36 origin?
37 origin-uri
38 origin-method
39 origin-sha256
40 origin-file-name
e4c245f8 41 base32
e3ce5d70 42
a18eda27
LC
43 <search-path-specification>
44 search-path-specification
45 search-path-specification?
46 search-path-specification->sexp
47
e3ce5d70
LC
48 package
49 package?
50 package-name
51 package-version
2847050a 52 package-full-name
e3ce5d70
LC
53 package-source
54 package-build-system
55 package-arguments
56 package-inputs
57 package-native-inputs
062c6927 58 package-propagated-inputs
e3ce5d70 59 package-outputs
a18eda27 60 package-native-search-paths
e3ce5d70 61 package-search-paths
d45122f5 62 package-synopsis
e3ce5d70 63 package-description
e3ce5d70 64 package-license
52bda18a 65 package-home-page
e3ce5d70
LC
66 package-platforms
67 package-maintainers
062c6927 68 package-properties
35f3c5f5 69 package-location
d66c7096 70 package-field-location
e3ce5d70 71
a3d73f59 72 package-transitive-inputs
9c1edabd
LC
73 package-transitive-target-inputs
74 package-transitive-native-inputs
113aef68 75 package-transitive-propagated-inputs
e3ce5d70
LC
76 package-source-derivation
77 package-derivation
d36622dc 78 package-cross-derivation
d510ab46 79 package-output
d36622dc
LC
80
81 &package-error
07783858 82 package-error?
d36622dc
LC
83 package-error-package
84 &package-input-error
07783858 85 package-input-error?
9b222abe
LC
86 package-error-invalid-input
87 &package-cross-build-system-error
88 package-cross-build-system-error?))
e3ce5d70
LC
89
90;;; Commentary:
91;;;
92;;; This module provides a high-level mechanism to define packages in a
93;;; Guix-based distribution.
94;;;
95;;; Code:
96
90c68be8
LC
97;; The source of a package, such as a tarball URL and fetcher---called
98;; "origin" to avoid name clash with `package-source', `source', etc.
99(define-record-type* <origin>
100 origin make-origin
101 origin?
102 (uri origin-uri) ; string
103 (method origin-method) ; symbol
104 (sha256 origin-sha256) ; bytevector
105 (file-name origin-file-name (default #f))) ; optional file name
e3ce5d70 106
e4c245f8
LC
107(define-syntax base32
108 (lambda (s)
109 "Return the bytevector corresponding to the given Nix-base32
110representation."
111 (syntax-case s ()
112 ((_ str)
113 (string? (syntax->datum #'str))
aba326f7 114 ;; A literal string: do the conversion at expansion time.
e4c245f8
LC
115 (with-syntax ((bv (nix-base32-string->bytevector
116 (syntax->datum #'str))))
aba326f7
LC
117 #''bv))
118 ((_ str)
119 #'(nix-base32-string->bytevector str)))))
e4c245f8 120
a18eda27
LC
121;; The specification of a search path.
122(define-record-type* <search-path-specification>
123 search-path-specification make-search-path-specification
124 search-path-specification?
125 (variable search-path-specification-variable)
126 (directories search-path-specification-directories)
127 (separator search-path-specification-separator (default ":")))
128
129(define (search-path-specification->sexp spec)
130 "Return an sexp representing SPEC, a <search-path-specification>. The sexp
131corresponds to the arguments expected by `set-path-environment-variable'."
132 (match spec
133 (($ <search-path-specification> variable directories separator)
134 `(,variable ,directories ,separator))))
d36622dc 135
a18eda27 136;; A package.
e3ce5d70
LC
137(define-record-type* <package>
138 package make-package
139 package?
140 (name package-name) ; string
141 (version package-version) ; string
90c68be8 142 (source package-source) ; <origin> instance
e3ce5d70 143 (build-system package-build-system) ; build system
64fddd74 144 (arguments package-arguments ; arguments for the build method
21c203a5 145 (default '()) (thunked))
062c6927 146
e3ce5d70 147 (inputs package-inputs ; input packages or derivations
dd6b9a37 148 (default '()) (thunked))
062c6927 149 (propagated-inputs package-propagated-inputs ; same, but propagated
9d97a1b3 150 (default '()) (thunked))
e3ce5d70 151 (native-inputs package-native-inputs ; native input packages/derivations
a7dc055b 152 (default '()) (thunked))
c9d01150
LC
153 (self-native-input? package-self-native-input? ; whether to use itself as
154 ; a native input when cross-
155 (default #f)) ; compiling
062c6927 156
e3ce5d70
LC
157 (outputs package-outputs ; list of strings
158 (default '("out")))
a18eda27
LC
159
160 ; lists of
161 ; <search-path-specification>,
162 ; for native and cross
163 ; inputs
164 (native-search-paths package-native-search-paths (default '()))
165 (search-paths package-search-paths (default '()))
e3ce5d70 166
d45122f5
LC
167 (synopsis package-synopsis) ; one-line description
168 (description package-description) ; one or two paragraphs
1fb78cb2 169 (license package-license)
45753b65 170 (home-page package-home-page)
e3ce5d70 171 (platforms package-platforms (default '()))
35f3c5f5 172 (maintainers package-maintainers (default '()))
45753b65 173
062c6927
LC
174 (properties package-properties (default '())) ; alist for anything else
175
35f3c5f5
LC
176 (location package-location
177 (default (and=> (current-source-location)
178 source-properties->location))))
e3ce5d70 179
946b72c9
LC
180(set-record-type-printer! <package>
181 (lambda (package port)
182 (let ((loc (package-location package))
183 (format simple-format))
184 (format port "#<package ~a-~a ~a:~a ~a>"
185 (package-name package)
186 (package-version package)
187 (location-file loc)
188 (location-line loc)
189 (number->string (object-address
190 package)
191 16)))))
192
d66c7096 193(define (package-field-location package field)
f903dc05
LC
194 "Return the source code location of the definition of FIELD for PACKAGE, or
195#f if it could not be determined."
196 (define (goto port line column)
197 (unless (and (= (port-column port) (- column 1))
198 (= (port-line port) (- line 1)))
199 (unless (eof-object? (read-char port))
200 (goto port line column))))
d66c7096
LC
201
202 (match (package-location package)
203 (($ <location> file line column)
204 (catch 'system
205 (lambda ()
206 (call-with-input-file (search-path %load-path file)
207 (lambda (port)
f903dc05
LC
208 (goto port line column)
209 (match (read port)
210 (('package inits ...)
211 (let ((field (assoc field inits)))
212 (match field
213 ((_ value)
8e77f41e
LC
214 ;; Put the `or' here, and not in the first argument of
215 ;; `and=>', to work around a compiler bug in 2.0.5.
216 (or (and=> (source-properties value)
217 source-properties->location)
218 (and=> (source-properties field)
219 source-properties->location)))
f903dc05
LC
220 (_
221 #f))))
222 (_
223 #f)))))
d66c7096 224 (lambda _
f903dc05 225 #f)))
d66c7096
LC
226 (_ #f)))
227
d36622dc
LC
228
229;; Error conditions.
230
231(define-condition-type &package-error &error
232 package-error?
233 (package package-error-package))
234
235(define-condition-type &package-input-error &package-error
236 package-input-error?
237 (input package-error-invalid-input))
238
9b222abe
LC
239(define-condition-type &package-cross-build-system-error &package-error
240 package-cross-build-system-error?)
241
d36622dc 242
2847050a
LC
243(define (package-full-name package)
244 "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
245 (string-append (package-name package) "-" (package-version package)))
246
b642e4b8
LC
247(define* (package-source-derivation store source
248 #:optional (system (%current-system)))
249 "Return the derivation path for SOURCE, a package source, for SYSTEM."
e3ce5d70 250 (match source
90c68be8 251 (($ <origin> uri method sha256 name)
b642e4b8 252 (method store uri 'sha256 sha256 name
7357138b
LC
253 #:system system))
254 ((and (? string?) (? store-path?) file)
255 file)
256 ((? string? file)
257 (add-to-store store (basename file) #t "sha256" file))))
e3ce5d70 258
113aef68
LC
259(define (transitive-inputs inputs)
260 (let loop ((inputs inputs)
a3d73f59
LC
261 (result '()))
262 (match inputs
263 (()
264 (delete-duplicates (reverse result))) ; XXX: efficiency
265 (((and i (name (? package? p) sub ...)) rest ...)
266 (let ((t (map (match-lambda
267 ((dep-name derivation ...)
268 (cons (string-append name "/" dep-name)
269 derivation)))
270 (package-propagated-inputs p))))
271 (loop (append t rest)
272 (append t (cons i result)))))
273 ((input rest ...)
274 (loop rest (cons input result))))))
275
113aef68
LC
276(define (package-transitive-inputs package)
277 "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
278with their propagated inputs, recursively."
279 (transitive-inputs (append (package-native-inputs package)
280 (package-inputs package)
281 (package-propagated-inputs package))))
282
9c1edabd
LC
283(define (package-transitive-target-inputs package)
284 "Return the transitive target inputs of PACKAGE---i.e., its direct inputs
285along with their propagated inputs, recursively. This only includes inputs
286for the target system, and not native inputs."
287 (transitive-inputs (append (package-inputs package)
288 (package-propagated-inputs package))))
289
290(define (package-transitive-native-inputs package)
291 "Return the transitive native inputs of PACKAGE---i.e., its direct inputs
292along with their propagated inputs, recursively. This only includes inputs
293for the host system (\"native inputs\"), and not target inputs."
294 (transitive-inputs (package-native-inputs package)))
295
113aef68
LC
296(define (package-transitive-propagated-inputs package)
297 "Return the propagated inputs of PACKAGE, and their propagated inputs,
298recursively."
299 (transitive-inputs (package-propagated-inputs package)))
300
a2ebaddd
LC
301\f
302;;;
303;;; Package derivations.
304;;;
305
306(define %derivation-cache
307 ;; Package to derivation-path mapping.
e4588af9 308 (make-weak-key-hash-table 100))
a2ebaddd 309
e509d152
LC
310(define (cache package system thunk)
311 "Memoize the return values of THUNK as the derivation of PACKAGE on
312SYSTEM."
313 (let ((vals (call-with-values thunk list)))
314 ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
315 ;; same value for all structs (as of Guile 2.0.6), and because pointer
316 ;; equality is sufficient in practice.
317 (hashq-set! %derivation-cache package `((,system ,@vals)))
318 (apply values vals)))
319
320(define-syntax-rule (cached package system body ...)
321 "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
322Return the cached result when available."
323 (let ((thunk (lambda () body ...)))
324 (match (hashq-ref %derivation-cache package)
325 ((alist (... ...))
326 (match (assoc-ref alist system)
327 ((vals (... ...))
328 (apply values vals))
329 (#f
330 (cache package system thunk))))
331 (#f
332 (cache package system thunk)))))
a2ebaddd 333
a63062b5
LC
334(define* (expand-input store package input system #:optional cross-system)
335 "Expand INPUT, an input tuple, such that it contains only references to
336derivation paths or store paths. PACKAGE is only used to provide contextual
337information in exceptions."
592ef6c8
LC
338 (define (intern file)
339 ;; Add FILE to the store. Set the `recursive?' bit to #t, so that
340 ;; file permissions are preserved.
a9ebd9ef 341 (add-to-store store (basename file) #t "sha256" file))
592ef6c8 342
a63062b5
LC
343 (define derivation
344 (if cross-system
345 (cut package-cross-derivation store <> cross-system system)
346 (cut package-derivation store <> system)))
347
348 (match input
349 (((? string? name) (? package? package))
350 (list name (derivation package)))
351 (((? string? name) (? package? package)
352 (? string? sub-drv))
353 (list name (derivation package)
354 sub-drv))
355 (((? string? name)
356 (and (? string?) (? derivation-path?) drv))
357 (list name drv))
358 (((? string? name)
359 (and (? string?) (? file-exists? file)))
360 ;; Add FILE to the store. When FILE is in the sub-directory of a
361 ;; store path, it needs to be added anyway, so it can be used as a
362 ;; source.
363 (list name (intern file)))
364 (((? string? name) (? origin? source))
365 (list name (package-source-derivation store source system)))
366 (x
367 (raise (condition (&package-input-error
368 (package package)
369 (input x)))))))
592ef6c8 370
a63062b5
LC
371(define* (package-derivation store package
372 #:optional (system (%current-system)))
373 "Return the derivation path and corresponding <derivation> object of
374PACKAGE for SYSTEM."
e509d152
LC
375 ;; Compute the derivation and cache the result. Caching is important
376 ;; because some derivations, such as the implicit inputs of the GNU build
377 ;; system, will be queried many, many times in a row.
378 (cached package system
21c203a5
LC
379
380 ;; Bind %CURRENT-SYSTEM so that thunked field values can refer
381 ;; to it.
9c1edabd
LC
382 (parameterize ((%current-system system)
383 (%current-target-system #f))
21c203a5
LC
384 (match package
385 (($ <package> name version source (= build-system-builder builder)
386 args inputs propagated-inputs native-inputs self-native-input?
387 outputs)
a18eda27 388 (let* ((inputs (package-transitive-inputs package))
a63062b5
LC
389 (input-drvs (map (cut expand-input
390 store package <> system)
391 inputs))
a18eda27
LC
392 (paths (delete-duplicates
393 (append-map (match-lambda
394 ((_ (? package? p) _ ...)
395 (package-native-search-paths
396 p))
397 (_ '()))
398 inputs))))
21c203a5
LC
399
400 (apply builder
401 store (package-full-name package)
402 (and source
403 (package-source-derivation store source system))
a18eda27
LC
404 input-drvs
405 #:search-paths paths
21c203a5
LC
406 #:outputs outputs #:system system
407 (args))))))))
e3ce5d70 408
9c1edabd 409(define* (package-cross-derivation store package target
a63062b5 410 #:optional (system (%current-system)))
9c1edabd
LC
411 "Cross-build PACKAGE for TARGET (a GNU triplet) from host SYSTEM (a Guix
412system identifying string)."
413 (cached package (cons system target)
414
415 ;; Bind %CURRENT-SYSTEM so that thunked field values can refer
416 ;; to it.
417 (parameterize ((%current-system system)
418 (%current-target-system target))
419 (match package
420 (($ <package> name version source
421 (= build-system-cross-builder builder)
422 args inputs propagated-inputs native-inputs self-native-input?
423 outputs)
9b222abe
LC
424 (unless builder
425 (raise (condition
426 (&package-cross-build-system-error
427 (package package)))))
428
9c1edabd
LC
429 (let* ((inputs (package-transitive-target-inputs package))
430 (input-drvs (map (cut expand-input
431 store package <>
432 system target)
433 inputs))
434 (host (append (if self-native-input?
435 `(("self" ,package))
436 '())
437 (package-transitive-native-inputs package)))
438 (host-drvs (map (cut expand-input
439 store package <> system)
440 host))
441 (all (append host inputs))
442 (paths (delete-duplicates
443 (append-map (match-lambda
444 ((_ (? package? p) _ ...)
445 (package-search-paths p))
446 (_ '()))
447 all)))
448 (npaths (delete-duplicates
449 (append-map (match-lambda
450 ((_ (? package? p) _ ...)
451 (package-native-search-paths
452 p))
453 (_ '()))
454 all))))
455
456 (apply builder
457 store (package-full-name package) target
458 (and source
459 (package-source-derivation store source system))
460 input-drvs host-drvs
461 #:search-paths paths
462 #:native-search-paths npaths
463 #:outputs outputs #:system system
464 (args))))))))
d510ab46
LC
465
466(define* (package-output store package output
467 #:optional (system (%current-system)))
468 "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
469symbolic output name, such as \"out\". Note that this procedure calls
470`package-derivation', which is costly."
471 (let-values (((_ drv)
472 (package-derivation store package system)))
473 (derivation-output-path
474 (assoc-ref (derivation-outputs drv) output))))