distro: recutils: Allow builds with glibc 2.16+.
[jackhill/guix/guix.git] / guix / packages.scm
CommitLineData
e3ce5d70
LC
1;;; Guix --- Nix package management from Guile. -*- coding: utf-8 -*-
2;;; Copyright (C) 2012 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of Guix.
5;;;
6;;; Guix is free software; you can redistribute it and/or modify it
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;;;
11;;; Guix is distributed in the hope that it will be useful, but
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
17;;; along with Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (guix packages)
20 #:use-module (guix utils)
21 #:use-module (guix store)
22 #:use-module (guix build-system)
23 #:use-module (ice-9 match)
062c6927 24 #:use-module (srfi srfi-1)
35f3c5f5 25 #:use-module (srfi srfi-9)
946b72c9 26 #:use-module (srfi srfi-9 gnu)
d36622dc
LC
27 #:use-module (srfi srfi-34)
28 #:use-module (srfi srfi-35)
35f3c5f5
LC
29 #:export (location
30 location?
31 location-file
32 location-line
33 location-column
34
90c68be8
LC
35 origin
36 origin?
37 origin-uri
38 origin-method
39 origin-sha256
40 origin-file-name
e4c245f8 41 base32
e3ce5d70
LC
42
43 package
44 package?
45 package-name
46 package-version
47 package-source
48 package-build-system
49 package-arguments
50 package-inputs
51 package-native-inputs
062c6927 52 package-propagated-inputs
e3ce5d70
LC
53 package-outputs
54 package-search-paths
55 package-description
56 package-long-description
57 package-license
58 package-platforms
59 package-maintainers
062c6927 60 package-properties
35f3c5f5 61 package-location
e3ce5d70 62
a3d73f59 63 package-transitive-inputs
e3ce5d70
LC
64 package-source-derivation
65 package-derivation
d36622dc
LC
66 package-cross-derivation
67
68 &package-error
69 package-error-package
70 &package-input-error
71 package-error-invalid-input))
e3ce5d70
LC
72
73;;; Commentary:
74;;;
75;;; This module provides a high-level mechanism to define packages in a
76;;; Guix-based distribution.
77;;;
78;;; Code:
79
35f3c5f5
LC
80;; A source location.
81(define-record-type <location>
82 (make-location file line column)
83 location?
84 (file location-file) ; file name
85 (line location-line) ; 1-indexed line
86 (column location-column)) ; 0-indexed column
87
88(define location
89 (memoize
90 (lambda (file line column)
91 "Return the <location> object for the given FILE, LINE, and COLUMN."
92 (and line column file
93 (make-location file line column)))))
94
95(define (source-properties->location loc)
96 "Return a location object based on the info in LOC, an alist as returned
97by Guile's `source-properties', `frame-source', `current-source-location',
98etc."
99 (let ((file (assq-ref loc 'filename))
100 (line (assq-ref loc 'line))
101 (col (assq-ref loc 'column)))
102 (location file (and line (+ line 1)) col)))
103
104
90c68be8
LC
105;; The source of a package, such as a tarball URL and fetcher---called
106;; "origin" to avoid name clash with `package-source', `source', etc.
107(define-record-type* <origin>
108 origin make-origin
109 origin?
110 (uri origin-uri) ; string
111 (method origin-method) ; symbol
112 (sha256 origin-sha256) ; bytevector
113 (file-name origin-file-name (default #f))) ; optional file name
e3ce5d70 114
e4c245f8
LC
115(define-syntax base32
116 (lambda (s)
117 "Return the bytevector corresponding to the given Nix-base32
118representation."
119 (syntax-case s ()
120 ((_ str)
121 (string? (syntax->datum #'str))
122 (with-syntax ((bv (nix-base32-string->bytevector
123 (syntax->datum #'str))))
124 #''bv)))))
125
35f3c5f5 126;; A package.
d36622dc 127
e3ce5d70
LC
128(define-record-type* <package>
129 package make-package
130 package?
131 (name package-name) ; string
132 (version package-version) ; string
90c68be8 133 (source package-source) ; <origin> instance
e3ce5d70 134 (build-system package-build-system) ; build system
64fddd74
LC
135 (arguments package-arguments ; arguments for the build method
136 (default '()))
062c6927 137
e3ce5d70
LC
138 (inputs package-inputs ; input packages or derivations
139 (default '()))
062c6927
LC
140 (propagated-inputs package-propagated-inputs ; same, but propagated
141 (default '()))
e3ce5d70
LC
142 (native-inputs package-native-inputs ; native input packages/derivations
143 (default '()))
c9d01150
LC
144 (self-native-input? package-self-native-input? ; whether to use itself as
145 ; a native input when cross-
146 (default #f)) ; compiling
062c6927 147
e3ce5d70
LC
148 (outputs package-outputs ; list of strings
149 (default '("out")))
150 (search-paths package-search-paths ; list of (ENV-VAR (DIRS ...))
151 (default '())) ; tuples; see
152 ; `set-path-environment-variable'
153 ; (aka. "setup-hook")
154
155 (description package-description) ; one-line description
156 (long-description package-long-description) ; one or two paragraphs
157 (license package-license (default '()))
45753b65 158 (home-page package-home-page)
e3ce5d70 159 (platforms package-platforms (default '()))
35f3c5f5 160 (maintainers package-maintainers (default '()))
45753b65 161
062c6927
LC
162 (properties package-properties (default '())) ; alist for anything else
163
35f3c5f5
LC
164 (location package-location
165 (default (and=> (current-source-location)
166 source-properties->location))))
e3ce5d70 167
946b72c9
LC
168(set-record-type-printer! <package>
169 (lambda (package port)
170 (let ((loc (package-location package))
171 (format simple-format))
172 (format port "#<package ~a-~a ~a:~a ~a>"
173 (package-name package)
174 (package-version package)
175 (location-file loc)
176 (location-line loc)
177 (number->string (object-address
178 package)
179 16)))))
180
d36622dc
LC
181
182;; Error conditions.
183
184(define-condition-type &package-error &error
185 package-error?
186 (package package-error-package))
187
188(define-condition-type &package-input-error &package-error
189 package-input-error?
190 (input package-error-invalid-input))
191
192
e3ce5d70
LC
193(define (package-source-derivation store source)
194 "Return the derivation path for SOURCE, a package source."
195 (match source
90c68be8 196 (($ <origin> uri method sha256 name)
e3ce5d70
LC
197 (method store uri 'sha256 sha256 name))))
198
a3d73f59
LC
199(define (package-transitive-inputs package)
200 "Return the transitive inputs of PACKAGE---i.e., its direct inputs along
201with their propagated inputs, recursively."
202 (let loop ((inputs (concatenate (list (package-native-inputs package)
203 (package-inputs package)
204 (package-propagated-inputs package))))
205 (result '()))
206 (match inputs
207 (()
208 (delete-duplicates (reverse result))) ; XXX: efficiency
209 (((and i (name (? package? p) sub ...)) rest ...)
210 (let ((t (map (match-lambda
211 ((dep-name derivation ...)
212 (cons (string-append name "/" dep-name)
213 derivation)))
214 (package-propagated-inputs p))))
215 (loop (append t rest)
216 (append t (cons i result)))))
217 ((input rest ...)
218 (loop rest (cons input result))))))
219
e3ce5d70
LC
220(define* (package-derivation store package
221 #:optional (system (%current-system)))
222 "Return the derivation of PACKAGE for SYSTEM."
223 (match package
224 (($ <package> name version source (= build-system-builder builder)
c9d01150
LC
225 args inputs propagated-inputs native-inputs self-native-input?
226 outputs)
e3ce5d70
LC
227 ;; TODO: For `search-paths', add a builder prologue that calls
228 ;; `set-path-environment-variable'.
229 (let ((inputs (map (match-lambda
230 (((? string? name) (and package ($ <package>)))
231 (list name (package-derivation store package)))
232 (((? string? name) (and package ($ <package>))
233 (? string? sub-drv))
234 (list name (package-derivation store package)
235 sub-drv))
236 (((? string? name)
93a0a8b3 237 (and (? string?) (? derivation-path?) drv))
e67ac6e6
LC
238 (list name drv))
239 (((? string? name)
93a0a8b3
LC
240 (and (? string?) (? file-exists? file)))
241 ;; Add FILE to the store. When FILE is in the
242 ;; sub-directory of a store path, it needs to be
243 ;; added anyway, so it can be used as a source.
e67ac6e6
LC
244 (list name
245 (add-to-store store (basename file)
d36622dc
LC
246 #t #f "sha256" file)))
247 (x
248 (raise (condition (&package-input-error
249 (package package)
250 (input x))))))
a3d73f59 251 (package-transitive-inputs package))))
e3ce5d70
LC
252 (apply builder
253 store (string-append name "-" version)
254 (package-source-derivation store source)
255 inputs
256 #:outputs outputs #:system system
03671375
LC
257 (if (procedure? args)
258 (args system)
259 args))))))
e3ce5d70
LC
260
261(define* (package-cross-derivation store package)
262 ;; TODO
263 #f)