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