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