python.scm 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2013-2017, 2021-2022 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 gexp)
  27. #:use-module (guix monads)
  28. #:use-module (guix packages)
  29. #:use-module (guix derivations)
  30. #:use-module (guix search-paths)
  31. #:use-module (guix build-system)
  32. #:use-module (guix build-system gnu)
  33. #:use-module (srfi srfi-1)
  34. #:export (%python-build-system-modules
  35. package-with-python2
  36. strip-python2-variant
  37. default-python
  38. default-python2
  39. python-build
  40. python-build-system
  41. pypi-uri))
  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. (define* (pypi-uri name version #:optional (extension ".tar.gz"))
  49. "Return a URI string for the Python package hosted on the Python Package
  50. Index (PyPI) corresponding to NAME and VERSION. EXTENSION is the file name
  51. extension, such as '.tar.gz'."
  52. (string-append "https://files.pythonhosted.org/packages/source/"
  53. (string-take name 1) "/" name "/"
  54. name "-" version extension))
  55. (define %python-build-system-modules
  56. ;; Build-side modules imported by default.
  57. `((guix build python-build-system)
  58. ,@%gnu-build-system-modules))
  59. (define (default-python)
  60. "Return the default Python package."
  61. ;; Lazily resolve the binding to avoid a circular dependency.
  62. (let ((python (resolve-interface '(gnu packages python))))
  63. (module-ref python 'python-wrapper)))
  64. (define (default-python2)
  65. "Return the default Python 2 package."
  66. (let ((python (resolve-interface '(gnu packages python))))
  67. (module-ref python 'python-2)))
  68. (define sanity-check.py
  69. ;; The script used to validate the installation of a Python package.
  70. (search-auxiliary-file "python/sanity-check.py"))
  71. (define* (package-with-explicit-python python old-prefix new-prefix
  72. #:key variant-property)
  73. "Return a procedure of one argument, P. The procedure creates a package with
  74. the same fields as P, which is assumed to use PYTHON-BUILD-SYSTEM, such that
  75. it is compiled with PYTHON instead. The inputs are changed recursively
  76. accordingly. If the name of P starts with OLD-PREFIX, this is replaced by
  77. NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name.
  78. When VARIANT-PROPERTY is present, it is used as a key to search for
  79. pre-defined variants of this transformation recorded in the 'properties' field
  80. of packages. The property value must be the promise of a package. This is a
  81. convenient way for package writers to force the transformation to use
  82. pre-defined variants."
  83. (define package-variant
  84. (if variant-property
  85. (lambda (package)
  86. (assq-ref (package-properties package)
  87. variant-property))
  88. (const #f)))
  89. (define (transform p)
  90. (cond
  91. ;; If VARIANT-PROPERTY is present, use that.
  92. ((package-variant p)
  93. => force)
  94. ;; Otherwise build the new package object graph.
  95. ((eq? (package-build-system p) python-build-system)
  96. (package/inherit p
  97. (location (package-location p))
  98. (name (let ((name (package-name p)))
  99. (string-append new-prefix
  100. (if (string-prefix? old-prefix name)
  101. (substring name
  102. (string-length old-prefix))
  103. name))))
  104. (arguments
  105. (let ((python (if (promise? python)
  106. (force python)
  107. python)))
  108. (ensure-keyword-arguments (package-arguments p)
  109. `(#:python ,python))))))
  110. (else p)))
  111. (define (cut? p)
  112. (or (not (eq? (package-build-system p) python-build-system))
  113. (package-variant p)))
  114. (package-mapping transform cut?))
  115. (define package-with-python2
  116. ;; Note: delay call to 'default-python2' until after the 'arguments' field
  117. ;; of packages is accessed to avoid a circular dependency when evaluating
  118. ;; the top-level of (gnu packages python).
  119. (package-with-explicit-python (delay (default-python2))
  120. "python-" "python2-"
  121. #:variant-property 'python2-variant))
  122. (define (strip-python2-variant p)
  123. "Remove the 'python2-variant' property from P."
  124. (package/inherit p
  125. (properties (alist-delete 'python2-variant (package-properties p)))))
  126. (define* (lower name
  127. #:key source inputs native-inputs outputs system target
  128. (python (default-python))
  129. #:allow-other-keys
  130. #:rest arguments)
  131. "Return a bag for NAME."
  132. (define private-keywords
  133. '(#:target #:python #:inputs #:native-inputs))
  134. (and (not target) ;XXX: no cross-compilation
  135. (bag
  136. (name name)
  137. (system system)
  138. (host-inputs `(,@(if source
  139. `(("source" ,source))
  140. '())
  141. ,@inputs
  142. ;; Keep the standard inputs of 'gnu-build-system'.
  143. ,@(standard-packages)))
  144. (build-inputs `(("python" ,python)
  145. ("sanity-check.py" ,(local-file sanity-check.py))
  146. ,@native-inputs))
  147. (outputs outputs)
  148. (build python-build)
  149. (arguments (strip-keyword-arguments private-keywords arguments)))))
  150. (define* (python-build name inputs
  151. #:key source
  152. (tests? #t)
  153. (test-target "test")
  154. (use-setuptools? #t)
  155. (configure-flags ''())
  156. (phases '%standard-phases)
  157. (outputs '("out"))
  158. (search-paths '())
  159. (system (%current-system))
  160. (guile #f)
  161. (imported-modules %python-build-system-modules)
  162. (modules '((guix build python-build-system)
  163. (guix build utils))))
  164. "Build SOURCE using PYTHON, and with INPUTS. This assumes that SOURCE
  165. provides a 'setup.py' file as its build system."
  166. (define build
  167. (with-imported-modules imported-modules
  168. #~(begin
  169. (use-modules #$@(sexp->gexp modules))
  170. #$(with-build-variables inputs outputs
  171. #~(python-build #:name #$name
  172. #:source #+source
  173. #:configure-flags #$configure-flags
  174. #:use-setuptools? #$use-setuptools?
  175. #:system #$system
  176. #:test-target #$test-target
  177. #:tests? #$tests?
  178. #:phases #$(if (pair? phases)
  179. (sexp->gexp phases)
  180. phases)
  181. #:outputs %outputs
  182. #:search-paths '#$(sexp->gexp
  183. (map search-path-specification->sexp
  184. search-paths))
  185. #:inputs %build-inputs)))))
  186. (mlet %store-monad ((guile (package->derivation (or guile (default-guile))
  187. system #:graft? #f)))
  188. (gexp->derivation name build
  189. #:system system
  190. #:graft? #f ;consistent with 'gnu-build'
  191. #:target #f
  192. #:guile-for-build guile)))
  193. (define python-build-system
  194. (build-system
  195. (name 'python)
  196. (description "The standard Python build system")
  197. (lower lower)))
  198. ;;; python.scm ends here