build: Pass the appropriate flags when building `libstore.a'.
[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)
21 #:use-module (guix store)
ddc29a78 22 #:use-module (guix base32)
d510ab46 23 #:use-module (guix derivations)
e3ce5d70
LC
24 #:use-module (guix build-system)
25 #:use-module (ice-9 match)
062c6927 26 #:use-module (srfi srfi-1)
946b72c9 27 #:use-module (srfi srfi-9 gnu)
d510ab46 28 #:use-module (srfi srfi-11)
d36622dc
LC
29 #:use-module (srfi srfi-34)
30 #:use-module (srfi srfi-35)
cab24961 31 #:re-export (%current-system)
ff352cfb 32 #:export (origin
90c68be8
LC
33 origin?
34 origin-uri
35 origin-method
36 origin-sha256
37 origin-file-name
e4c245f8 38 base32
e3ce5d70
LC
39
40 package
41 package?
42 package-name
43 package-version
2847050a 44 package-full-name
e3ce5d70
LC
45 package-source
46 package-build-system
47 package-arguments
48 package-inputs
49 package-native-inputs
062c6927 50 package-propagated-inputs
e3ce5d70
LC
51 package-outputs
52 package-search-paths
d45122f5 53 package-synopsis
e3ce5d70 54 package-description
e3ce5d70 55 package-license
52bda18a 56 package-home-page
e3ce5d70
LC
57 package-platforms
58 package-maintainers
062c6927 59 package-properties
35f3c5f5 60 package-location
e3ce5d70 61
a3d73f59 62 package-transitive-inputs
113aef68 63 package-transitive-propagated-inputs
e3ce5d70
LC
64 package-source-derivation
65 package-derivation
d36622dc 66 package-cross-derivation
d510ab46 67 package-output
d36622dc
LC
68
69 &package-error
07783858 70 package-error?
d36622dc
LC
71 package-error-package
72 &package-input-error
07783858 73 package-input-error?
d36622dc 74 package-error-invalid-input))
e3ce5d70
LC
75
76;;; Commentary:
77;;;
78;;; This module provides a high-level mechanism to define packages in a
79;;; Guix-based distribution.
80;;;
81;;; Code:
82
90c68be8
LC
83;; The source of a package, such as a tarball URL and fetcher---called
84;; "origin" to avoid name clash with `package-source', `source', etc.
85(define-record-type* <origin>
86 origin make-origin
87 origin?
88 (uri origin-uri) ; string
89 (method origin-method) ; symbol
90 (sha256 origin-sha256) ; bytevector
91 (file-name origin-file-name (default #f))) ; optional file name
e3ce5d70 92
e4c245f8
LC
93(define-syntax base32
94 (lambda (s)
95 "Return the bytevector corresponding to the given Nix-base32
96representation."
97 (syntax-case s ()
98 ((_ str)
99 (string? (syntax->datum #'str))
aba326f7 100 ;; A literal string: do the conversion at expansion time.
e4c245f8
LC
101 (with-syntax ((bv (nix-base32-string->bytevector
102 (syntax->datum #'str))))
aba326f7
LC
103 #''bv))
104 ((_ str)
105 #'(nix-base32-string->bytevector str)))))
e4c245f8 106
35f3c5f5 107;; A package.
d36622dc 108
e3ce5d70
LC
109(define-record-type* <package>
110 package make-package
111 package?
112 (name package-name) ; string
113 (version package-version) ; string
90c68be8 114 (source package-source) ; <origin> instance
e3ce5d70 115 (build-system package-build-system) ; build system
64fddd74 116 (arguments package-arguments ; arguments for the build method
21c203a5 117 (default '()) (thunked))
062c6927 118
e3ce5d70 119 (inputs package-inputs ; input packages or derivations
dd6b9a37 120 (default '()) (thunked))
062c6927
LC
121 (propagated-inputs package-propagated-inputs ; same, but propagated
122 (default '()))
e3ce5d70
LC
123 (native-inputs package-native-inputs ; native input packages/derivations
124 (default '()))
c9d01150
LC
125 (self-native-input? package-self-native-input? ; whether to use itself as
126 ; a native input when cross-
127 (default #f)) ; compiling
062c6927 128
e3ce5d70
LC
129 (outputs package-outputs ; list of strings
130 (default '("out")))
131 (search-paths package-search-paths ; list of (ENV-VAR (DIRS ...))
132 (default '())) ; tuples; see
133 ; `set-path-environment-variable'
134 ; (aka. "setup-hook")
135
d45122f5
LC
136 (synopsis package-synopsis) ; one-line description
137 (description package-description) ; one or two paragraphs
1fb78cb2 138 (license package-license)
45753b65 139 (home-page package-home-page)
e3ce5d70 140 (platforms package-platforms (default '()))
35f3c5f5 141 (maintainers package-maintainers (default '()))
45753b65 142
062c6927
LC
143 (properties package-properties (default '())) ; alist for anything else
144
35f3c5f5
LC
145 (location package-location
146 (default (and=> (current-source-location)
147 source-properties->location))))
e3ce5d70 148
946b72c9
LC
149(set-record-type-printer! <package>
150 (lambda (package port)
151 (let ((loc (package-location package))
152 (format simple-format))
153 (format port "#<package ~a-~a ~a:~a ~a>"
154 (package-name package)
155 (package-version package)
156 (location-file loc)
157 (location-line loc)
158 (number->string (object-address
159 package)
160 16)))))
161
d36622dc
LC
162
163;; Error conditions.
164
165(define-condition-type &package-error &error
166 package-error?
167 (package package-error-package))
168
169(define-condition-type &package-input-error &package-error
170 package-input-error?
171 (input package-error-invalid-input))
172
173
2847050a
LC
174(define (package-full-name package)
175 "Return the full name of PACKAGE--i.e., `NAME-VERSION'."
176 (string-append (package-name package) "-" (package-version package)))
177
b642e4b8
LC
178(define* (package-source-derivation store source
179 #:optional (system (%current-system)))
180 "Return the derivation path for SOURCE, a package source, for SYSTEM."
e3ce5d70 181 (match source
90c68be8 182 (($ <origin> uri method sha256 name)
b642e4b8
LC
183 (method store uri 'sha256 sha256 name
184 #:system system))))
e3ce5d70 185
113aef68
LC
186(define (transitive-inputs inputs)
187 (let loop ((inputs inputs)
a3d73f59
LC
188 (result '()))
189 (match inputs
190 (()
191 (delete-duplicates (reverse result))) ; XXX: efficiency
192 (((and i (name (? package? p) sub ...)) rest ...)
193 (let ((t (map (match-lambda
194 ((dep-name derivation ...)
195 (cons (string-append name "/" dep-name)
196 derivation)))
197 (package-propagated-inputs p))))
198 (loop (append t rest)
199 (append t (cons i result)))))
200 ((input rest ...)
201 (loop rest (cons input result))))))
202
113aef68
LC
203(define (package-transitive-inputs package)
204 "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
205with their propagated inputs, recursively."
206 (transitive-inputs (append (package-native-inputs package)
207 (package-inputs package)
208 (package-propagated-inputs package))))
209
210(define (package-transitive-propagated-inputs package)
211 "Return the propagated inputs of PACKAGE, and their propagated inputs,
212recursively."
213 (transitive-inputs (package-propagated-inputs package)))
214
a2ebaddd
LC
215\f
216;;;
217;;; Package derivations.
218;;;
219
220(define %derivation-cache
221 ;; Package to derivation-path mapping.
e4588af9 222 (make-weak-key-hash-table 100))
a2ebaddd 223
e509d152
LC
224(define (cache package system thunk)
225 "Memoize the return values of THUNK as the derivation of PACKAGE on
226SYSTEM."
227 (let ((vals (call-with-values thunk list)))
228 ;; Use `hashq-set!' instead of `hash-set!' because `hash' returns the
229 ;; same value for all structs (as of Guile 2.0.6), and because pointer
230 ;; equality is sufficient in practice.
231 (hashq-set! %derivation-cache package `((,system ,@vals)))
232 (apply values vals)))
233
234(define-syntax-rule (cached package system body ...)
235 "Memoize the result of BODY for the arguments PACKAGE and SYSTEM.
236Return the cached result when available."
237 (let ((thunk (lambda () body ...)))
238 (match (hashq-ref %derivation-cache package)
239 ((alist (... ...))
240 (match (assoc-ref alist system)
241 ((vals (... ...))
242 (apply values vals))
243 (#f
244 (cache package system thunk))))
245 (#f
246 (cache package system thunk)))))
a2ebaddd 247
e3ce5d70
LC
248(define* (package-derivation store package
249 #:optional (system (%current-system)))
e509d152
LC
250 "Return the derivation path and corresponding <derivation> object of
251PACKAGE for SYSTEM."
592ef6c8
LC
252 (define (intern file)
253 ;; Add FILE to the store. Set the `recursive?' bit to #t, so that
254 ;; file permissions are preserved.
a9ebd9ef 255 (add-to-store store (basename file) #t "sha256" file))
592ef6c8
LC
256
257 (define expand-input
258 ;; Expand the given input tuple such that it contains only
259 ;; references to derivation paths or store paths.
260 (match-lambda
261 (((? string? name) (? package? package))
b642e4b8 262 (list name (package-derivation store package system)))
592ef6c8
LC
263 (((? string? name) (? package? package)
264 (? string? sub-drv))
b642e4b8 265 (list name (package-derivation store package system)
592ef6c8
LC
266 sub-drv))
267 (((? string? name)
268 (and (? string?) (? derivation-path?) drv))
269 (list name drv))
270 (((? string? name)
271 (and (? string?) (? file-exists? file)))
272 ;; Add FILE to the store. When FILE is in the sub-directory of a
273 ;; store path, it needs to be added anyway, so it can be used as a
274 ;; source.
275 (list name (intern file)))
276 (((? string? name) (? origin? source))
b642e4b8 277 (list name (package-source-derivation store source system)))
592ef6c8
LC
278 (x
279 (raise (condition (&package-input-error
280 (package package)
281 (input x)))))))
282
e509d152
LC
283 ;; Compute the derivation and cache the result. Caching is important
284 ;; because some derivations, such as the implicit inputs of the GNU build
285 ;; system, will be queried many, many times in a row.
286 (cached package system
21c203a5
LC
287
288 ;; Bind %CURRENT-SYSTEM so that thunked field values can refer
289 ;; to it.
290 (parameterize ((%current-system system))
291 (match package
292 (($ <package> name version source (= build-system-builder builder)
293 args inputs propagated-inputs native-inputs self-native-input?
294 outputs)
295 ;; TODO: For `search-paths', add a builder prologue that calls
296 ;; `set-path-environment-variable'.
297 (let ((inputs (map expand-input
298 (package-transitive-inputs package))))
299
300 (apply builder
301 store (package-full-name package)
302 (and source
303 (package-source-derivation store source system))
304 inputs
305 #:outputs outputs #:system system
306 (args))))))))
e3ce5d70
LC
307
308(define* (package-cross-derivation store package)
309 ;; TODO
310 #f)
d510ab46
LC
311
312(define* (package-output store package output
313 #:optional (system (%current-system)))
314 "Return the output path of PACKAGE's OUTPUT for SYSTEM---where OUTPUT is the
315symbolic output name, such as \"out\". Note that this procedure calls
316`package-derivation', which is costly."
317 (let-values (((_ drv)
318 (package-derivation store package system)))
319 (derivation-output-path
320 (assoc-ref (derivation-outputs drv) output))))