gnu: emacs-org: Update to 9.4.
[jackhill/guix/guix.git] / guix / build-system / python.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
4 ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
5 ;;;
6 ;;; This file is part of GNU Guix.
7 ;;;
8 ;;; GNU Guix is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
12 ;;;
13 ;;; GNU Guix is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;;; GNU General Public License for more details.
17 ;;;
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21 (define-module (guix build-system python)
22 #:use-module (guix store)
23 #:use-module (guix utils)
24 #:use-module (guix memoization)
25 #:use-module (guix packages)
26 #:use-module (guix derivations)
27 #:use-module (guix search-paths)
28 #:use-module (guix build-system)
29 #:use-module (guix build-system gnu)
30 #:use-module (ice-9 match)
31 #:use-module (srfi srfi-1)
32 #:use-module (srfi srfi-26)
33 #:export (%python-build-system-modules
34 package-with-python2
35 strip-python2-variant
36 default-python
37 default-python2
38 python-build
39 python-build-system
40 pypi-uri))
41
42 ;; Commentary:
43 ;;
44 ;; Standard build procedure for Python packages using 'setup.py'. This is
45 ;; implemented as an extension of 'gnu-build-system'.
46 ;;
47 ;; Code:
48
49 (define* (pypi-uri name version #:optional (extension ".tar.gz"))
50 "Return a URI string for the Python package hosted on the Python Package
51 Index (PyPI) corresponding to NAME and VERSION. EXTENSION is the file name
52 extension, such as '.tar.gz'."
53 (string-append "https://files.pythonhosted.org/packages/source/"
54 (string-take name 1) "/" name "/"
55 name "-" version extension))
56
57 (define %python-build-system-modules
58 ;; Build-side modules imported by default.
59 `((guix build python-build-system)
60 ,@%gnu-build-system-modules))
61
62 (define (default-python)
63 "Return the default Python package."
64 ;; Lazily resolve the binding to avoid a circular dependency.
65 (let ((python (resolve-interface '(gnu packages python))))
66 (module-ref python 'python-wrapper)))
67
68 (define (default-python2)
69 "Return the default Python 2 package."
70 (let ((python (resolve-interface '(gnu packages python))))
71 (module-ref python 'python-2)))
72
73 (define* (package-with-explicit-python python old-prefix new-prefix
74 #:key variant-property)
75 "Return a procedure of one argument, P. The procedure creates a package with
76 the same fields as P, which is assumed to use PYTHON-BUILD-SYSTEM, such that
77 it is compiled with PYTHON instead. The inputs are changed recursively
78 accordingly. If the name of P starts with OLD-PREFIX, this is replaced by
79 NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name.
80
81 When VARIANT-PROPERTY is present, it is used as a key to search for
82 pre-defined variants of this transformation recorded in the 'properties' field
83 of packages. The property value must be the promise of a package. This is a
84 convenient way for package writers to force the transformation to use
85 pre-defined variants."
86 (define package-variant
87 (if variant-property
88 (lambda (package)
89 (assq-ref (package-properties package)
90 variant-property))
91 (const #f)))
92
93 (define (transform p)
94 (cond
95 ;; If VARIANT-PROPERTY is present, use that.
96 ((package-variant p)
97 => force)
98
99 ;; Otherwise build the new package object graph.
100 ((eq? (package-build-system p) python-build-system)
101 (package
102 (inherit p)
103 (location (package-location p))
104 (name (let ((name (package-name p)))
105 (string-append new-prefix
106 (if (string-prefix? old-prefix name)
107 (substring name
108 (string-length old-prefix))
109 name))))
110 (arguments
111 (let ((python (if (promise? python)
112 (force python)
113 python)))
114 (ensure-keyword-arguments (package-arguments p)
115 `(#:python ,python))))))
116 (else p)))
117
118 (define (cut? p)
119 (or (not (eq? (package-build-system p) python-build-system))
120 (package-variant p)))
121
122 (package-mapping transform cut?))
123
124 (define package-with-python2
125 ;; Note: delay call to 'default-python2' until after the 'arguments' field
126 ;; of packages is accessed to avoid a circular dependency when evaluating
127 ;; the top-level of (gnu packages python).
128 (package-with-explicit-python (delay (default-python2))
129 "python-" "python2-"
130 #:variant-property 'python2-variant))
131
132 (define (strip-python2-variant p)
133 "Remove the 'python2-variant' property from P."
134 (package
135 (inherit p)
136 (properties (alist-delete 'python2-variant (package-properties p)))))
137
138 (define* (lower name
139 #:key source inputs native-inputs outputs system target
140 (python (default-python))
141 #:allow-other-keys
142 #:rest arguments)
143 "Return a bag for NAME."
144 (define private-keywords
145 '(#:source #:target #:python #:inputs #:native-inputs))
146
147 (and (not target) ;XXX: no cross-compilation
148 (bag
149 (name name)
150 (system system)
151 (host-inputs `(,@(if source
152 `(("source" ,source))
153 '())
154 ,@inputs
155
156 ;; Keep the standard inputs of 'gnu-build-system'.
157 ,@(standard-packages)))
158 (build-inputs `(("python" ,python)
159 ,@native-inputs))
160 (outputs outputs)
161 (build python-build)
162 (arguments (strip-keyword-arguments private-keywords arguments)))))
163
164 (define* (python-build store name inputs
165 #:key
166 (tests? #t)
167 (test-target "test")
168 (use-setuptools? #t)
169 (configure-flags ''())
170 (phases '(@ (guix build python-build-system)
171 %standard-phases))
172 (outputs '("out"))
173 (search-paths '())
174 (system (%current-system))
175 (guile #f)
176 (imported-modules %python-build-system-modules)
177 (modules '((guix build python-build-system)
178 (guix build utils))))
179 "Build SOURCE using PYTHON, and with INPUTS. This assumes that SOURCE
180 provides a 'setup.py' file as its build system."
181 (define builder
182 `(begin
183 (use-modules ,@modules)
184 (python-build #:name ,name
185 #:source ,(match (assoc-ref inputs "source")
186 (((? derivation? source))
187 (derivation->output-path source))
188 ((source)
189 source)
190 (source
191 source))
192 #:configure-flags ,configure-flags
193 #:system ,system
194 #:test-target ,test-target
195 #:tests? ,tests?
196 #:use-setuptools? ,use-setuptools?
197 #:phases ,phases
198 #:outputs %outputs
199 #:search-paths ',(map search-path-specification->sexp
200 search-paths)
201 #:inputs %build-inputs)))
202
203 (define guile-for-build
204 (match guile
205 ((? package?)
206 (package-derivation store guile system #:graft? #f))
207 (#f ; the default
208 (let* ((distro (resolve-interface '(gnu packages commencement)))
209 (guile (module-ref distro 'guile-final)))
210 (package-derivation store guile system #:graft? #f)))))
211
212 (build-expression->derivation store name builder
213 #:inputs inputs
214 #:system system
215 #:modules imported-modules
216 #:outputs outputs
217 #:guile-for-build guile-for-build))
218
219 (define python-build-system
220 (build-system
221 (name 'python)
222 (description "The standard Python build system")
223 (lower lower)))
224
225 ;;; python.scm ends here