python.scm 8.8 KB

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