build-system: Introduce "bags" as an intermediate representation.
[jackhill/guix/guix.git] / guix / build-system / python.scm
CommitLineData
40506d5d 1;;; GNU Guix --- Functional package management for GNU
bdb36958 2;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
11bb85a1 3;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
40506d5d
NK
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 packages)
25 #:use-module (guix derivations)
26 #:use-module (guix build-system)
27 #:use-module (guix build-system gnu)
28 #:use-module (ice-9 match)
11bb85a1
AE
29 #:use-module (srfi srfi-26)
30 #:export (package-with-python2
31 python-build
40506d5d
NK
32 python-build-system))
33
34;; Commentary:
35;;
36;; Standard build procedure for Python packages using 'setup.py'. This is
37;; implemented as an extension of 'gnu-build-system'.
38;;
39;; Code:
40
5282181d
LC
41(define (default-python)
42 "Return the default Python package."
43 ;; Lazily resolve the binding to avoid a circular dependency.
44 (let ((python (resolve-interface '(gnu packages python))))
3df47231 45 (module-ref python 'python-wrapper)))
5282181d 46
11bb85a1
AE
47(define (default-python2)
48 "Return the default Python 2 package."
49 (let ((python (resolve-interface '(gnu packages python))))
50 (module-ref python 'python-2)))
51
52(define (package-with-explicit-python p python old-prefix new-prefix)
53 "Create a package with the same fields as P, which is assumed to use
54PYTHON-BUILD-SYSTEM, such that it is compiled with PYTHON instead. The
55inputs are changed recursively accordingly. If the name of P starts with
56OLD-PREFIX, this is replaced by NEW-PREFIX; otherwise, NEW-PREFIX is
57prepended to the name."
58 (let* ((build-system (package-build-system p))
59 (rewrite-if-package
60 (lambda (content)
7e2b10a5
LC
61 ;; CONTENT may be a file name, in which case it is returned, or a
62 ;; package, which is rewritten with the new PYTHON and NEW-PREFIX.
11bb85a1
AE
63 (if (package? content)
64 (package-with-explicit-python content python
65 old-prefix new-prefix)
66 content)))
67 (rewrite
68 (match-lambda
69 ((name content . rest)
70 (append (list name (rewrite-if-package content)) rest)))))
71 (package (inherit p)
72 (name
73 (let ((name (package-name p)))
74 (if (eq? build-system python-build-system)
75 (string-append new-prefix
76 (if (string-prefix? old-prefix name)
77 (substring name (string-length old-prefix))
78 name))
79 name)))
80 (arguments
81 (let ((arguments (package-arguments p)))
82 (if (eq? build-system python-build-system)
83 (if (member #:python arguments)
84 (substitute-keyword-arguments arguments ((#:python p) python))
85 (append arguments `(#:python ,python)))
86 arguments)))
87 (inputs
88 (map rewrite (package-inputs p)))
89 (native-inputs
90 (map rewrite (package-native-inputs p))))))
91
92(define package-with-python2
93 (cut package-with-explicit-python <> (default-python2) "python-" "python2-"))
94
0d5a559f
LC
95(define* (lower name
96 #:key source inputs native-inputs outputs target
97 (python (default-python))
98 #:allow-other-keys
99 #:rest arguments)
100 "Return a bag for NAME."
101 (define private-keywords
102 '(#:source #:target #:python #:inputs #:native-inputs))
103
104 (and (not target) ;XXX: no cross-compilation
105 (bag
106 (name name)
107 (host-inputs `(,@(if source
108 `(("source" ,source))
109 '())
110 ,@inputs
111
112 ;; Keep the standard inputs of 'gnu-build-system'.
113 ,@(standard-packages)))
114 (build-inputs `(("python" ,python)
115 ,@native-inputs))
116 (outputs outputs)
117 (build python-build)
118 (arguments (strip-keyword-arguments private-keywords arguments)))))
119
120(define* (python-build store name inputs
40506d5d 121 #:key
40506d5d 122 (tests? #t)
5dfd5b82 123 (test-target "test")
40506d5d
NK
124 (configure-flags ''())
125 (phases '(@ (guix build python-build-system)
126 %standard-phases))
127 (outputs '("out"))
128 (search-paths '())
129 (system (%current-system))
130 (guile #f)
131 (imported-modules '((guix build python-build-system)
132 (guix build gnu-build-system)
133 (guix build utils)))
134 (modules '((guix build python-build-system)
40506d5d
NK
135 (guix build utils))))
136 "Build SOURCE using PYTHON, and with INPUTS. This assumes that SOURCE
137provides a 'setup.py' file as its build system."
40506d5d
NK
138 (define builder
139 `(begin
140 (use-modules ,@modules)
141 (python-build #:name ,name
0d5a559f
LC
142 #:source ,(match (assoc-ref inputs "source")
143 (((? derivation? source))
144 (derivation->output-path source))
145 ((source)
146 source)
147 (source
148 source))
40506d5d
NK
149 #:configure-flags ,configure-flags
150 #:system ,system
5dfd5b82 151 #:test-target ,test-target
40506d5d 152 #:tests? ,tests?
1d1f9397 153 #:phases ,phases
40506d5d 154 #:outputs %outputs
40506d5d 155 #:search-paths ',(map search-path-specification->sexp
0d5a559f 156 search-paths)
40506d5d
NK
157 #:inputs %build-inputs)))
158
159 (define guile-for-build
160 (match guile
161 ((? package?)
162 (package-derivation store guile system))
40506d5d 163 (#f ; the default
bdb36958 164 (let* ((distro (resolve-interface '(gnu packages commencement)))
40506d5d
NK
165 (guile (module-ref distro 'guile-final)))
166 (package-derivation store guile system)))))
167
0d5a559f
LC
168 (build-expression->derivation store name builder
169 #:inputs inputs
170 #:system system
171 #:modules imported-modules
172 #:outputs outputs
173 #:guile-for-build guile-for-build))
40506d5d
NK
174
175(define python-build-system
0d5a559f
LC
176 (build-system
177 (name 'python)
178 (description "The standard Python build system")
179 (lower lower)))
40506d5d
NK
180
181;;; python.scm ends here