Commit | Line | Data |
---|---|---|
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 | |
54 | PYTHON-BUILD-SYSTEM, such that it is compiled with PYTHON instead. The | |
55 | inputs are changed recursively accordingly. If the name of P starts with | |
56 | OLD-PREFIX, this is replaced by NEW-PREFIX; otherwise, NEW-PREFIX is | |
57 | prepended 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 | |
137 | provides 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 |