projects/guix·blob wip-node-riscv64 · refs

1244 lines · 62.3 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013 Nikita Karetnikov <[email protected]>
3;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2021, 2023 Ludovic Courtès <[email protected]>
4;;; Copyright © 2013, 2014, 2015, 2016 Andreas Enge <[email protected]>
5;;; Copyright © 2014, 2015 Mark H Weaver <[email protected]>
6;;; Copyright © 2014, 2017, 2019 Eric Bavier <[email protected]>
7;;; Copyright © 2014, 2015 Federico Beffa <[email protected]>
8;;; Copyright © 2015 Omar Radwan <[email protected]>
9;;; Copyright © 2015 Pierre-Antoine Rault <[email protected]>
10;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ricardo Wurmus <[email protected]>
11;;; Copyright © 2015, 2016 Christine Lemmer-Webber <[email protected]>
12;;; Copyright © 2015 Eric Dvorsak <[email protected]>
13;;; Copyright © 2015, 2016 David Thompson <[email protected]>
14;;; Copyright © 2015, 2016, 2017, 2021 Leo Famulari <[email protected]>
15;;; Copyright © 2015, 2017 Ben Woodcroft <[email protected]>
16;;; Copyright © 2015, 2016 Erik Edrosa <[email protected]>
17;;; Copyright © 2015-2020, 2023 Efraim Flashner <[email protected]>
18;;; Copyright © 2015, 2017 Kyle Meyer <[email protected]>
19;;; Copyright © 2015, 2016 Chris Marusich <[email protected]>
20;;; Copyright © 2016 Danny Milosavljevic <[email protected]>
21;;; Copyright © 2016 Lukas Gradl <[email protected]>
22;;; Copyright © 2016, 2018 Hartmut Goebel <[email protected]>
23;;; Copyright © 2016 Daniel Pimentel <[email protected]>
24;;; Copyright © 2016 Sou Bunnbu <[email protected]>
25;;; Copyright © 2016, 2017 Troy Sankey <[email protected]>
26;;; Copyright © 2016, 2017 Nikita <[email protected]>
27;;; Copyright © 2016 Dylan Jeffers <sapientech@[email protected]>
28;;; Copyright © 2016 David Craven <[email protected]>
29;;; Copyright © 2016-2022 Marius Bakke <[email protected]>
30;;; Copyright © 2016, 2017 Stefan Reichör <[email protected]>
31;;; Copyright © 2016, 2017 Alex Vong <[email protected]>
32;;; Copyright © 2016, 2017, 2018 Arun Isaac <[email protected]>
33;;; Copyright © 2016–2018, 2021, 2022 Tobias Geerinckx-Rice <[email protected]>
34;;; Copyright © 2016, 2017, 2018, 2021 Julien Lepiller <[email protected]>
35;;; Copyright © 2016, 2017 Thomas Danckaert <[email protected]>
36;;; Copyright © 2017 Carlo Zancanaro <[email protected]>
37;;; Copyright © 2017 Frederick M. Muriithi <[email protected]>
38;;; Copyright © 2017, 2018 Adriano Peluso <[email protected]>
39;;; Copyright © 2017 Ben Sturmfels <[email protected]>
40;;; Copyright © 2017, 2018, 2019 Mathieu Othacehe <[email protected]>
41;;; Copyright © 2017 José Miguel Sánchez García <[email protected]>
42;;; Copyright © 2017 Roel Janssen <[email protected]>
43;;; Copyright © 2017, 2018 Kei Kebreau <[email protected]>
44;;; Copyright © 2017 Rutger Helling <[email protected]>
45;;; Copyright © 2017 Brendan Tildesley <[email protected]>
46;;; Copyright © 2018 Ethan R. Jones <[email protected]
47;;; Copyright © 2018 Fis Trivial <[email protected]>
48;;; Copyright © 2018 Vijayalakshmi Vedantham <[email protected]>
49;;; Copyright © 2018 Mathieu Lirzin <[email protected]>
50;;; Copyright © 2018 Adam Massmann <[email protected]>
51;;; Copyright © 2016, 2018 Tomáš Čech <[email protected]>
52;;; Copyright © 2018 Nicolas Goaziou <[email protected]>
53;;; Copyright © 2018 Oleg Pykhalov <[email protected]>
54;;; Copyright © 2018 Clément Lassieur <[email protected]>
55;;; Copyright © 2018, 2019, 2020, 2021 Maxim Cournoyer <[email protected]>
56;;; Copyright © 2018 Luther Thompson <[email protected]>
57;;; Copyright © 2018 Vagrant Cascadian <[email protected]>
58;;; Copyright © 2019, 2024 Tanguy Le Carrour <[email protected]>
59;;; Copyright © 2020, 2023 Janneke Nieuwenhuizen <[email protected]>
60;;; Copyright © 2020, 2021 Greg Hogan <[email protected]>
61;;; Copyright © 2022 Philip McGrath <[email protected]>
62;;; Copyright © 2022 jgart <[email protected]>
63;;; Copyright © 2021 Lars-Dominik Braun <[email protected]>
64;;;
65;;; This file is part of GNU Guix.
66;;;
67;;; GNU Guix is free software; you can redistribute it and/or modify it
68;;; under the terms of the GNU General Public License as published by
69;;; the Free Software Foundation; either version 3 of the License, or (at
70;;; your option) any later version.
71;;;
72;;; GNU Guix is distributed in the hope that it will be useful, but
73;;; WITHOUT ANY WARRANTY; without even the implied warranty of
74;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75;;; GNU General Public License for more details.
76;;;
77;;; You should have received a copy of the GNU General Public License
78;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
79
80(define-module (gnu packages python)
81 #:use-module ((guix licenses) #:prefix license:)
82 #:use-module (gnu packages)
83 #:use-module (gnu packages base)
84 #:use-module (gnu packages bash)
85 #:use-module (gnu packages check)
86 #:use-module (gnu packages compression)
87 #:use-module (gnu packages crypto)
88 #:use-module (gnu packages dbm)
89 #:use-module (gnu packages libffi)
90 #:use-module (gnu packages pkg-config)
91 #:use-module (gnu packages python-build)
92 #:use-module (gnu packages readline)
93 #:use-module (gnu packages sqlite)
94 #:use-module (gnu packages tcl)
95 #:use-module (gnu packages tls)
96 #:use-module (gnu packages xml)
97 #:use-module (guix gexp)
98 #:use-module (guix packages)
99 #:use-module (guix download)
100 #:use-module (guix search-paths)
101 #:use-module (guix utils)
102 #:use-module (guix build-system gnu)
103 #:use-module (guix build-system trivial)
104 #:use-module (srfi srfi-1)
105 #:use-module (srfi srfi-26)
106
107 #:export (customize-site
108 guix-pythonpath-search-path))
109
110(define* (customize-site version)
111 "Generate a install-sitecustomize.py phase, using VERSION."
112 `(lambda* (#:key native-inputs inputs outputs #:allow-other-keys)
113 (let* ((out (assoc-ref outputs "out"))
114 (site-packages (string-append
115 out "/lib/python"
116 ,(version-major+minor version)
117 "/site-packages"))
118 (sitecustomize.py (assoc-ref (or native-inputs inputs)
119 "sitecustomize.py"))
120 (dest (string-append site-packages "/sitecustomize.py")))
121 (mkdir-p site-packages)
122 (copy-file sitecustomize.py dest)
123 ;; Set the correct permissions on the installed file, else the byte
124 ;; compilation phase fails with a permission denied error.
125 (chmod dest #o644))))
126
127(define (guix-pythonpath-search-path version)
128 "Generate a GUIX_PYTHONPATH search path specification, using VERSION."
129 (search-path-specification (variable "GUIX_PYTHONPATH")
130 (files (list (string-append
131 "lib/python"
132 (version-major+minor version)
133 "/site-packages")))))
134
135(define-public python-2.7
136 (package
137 (name "python2")
138 (version "2.7.18")
139 (source
140 (origin
141 (method url-fetch)
142 (uri (string-append "https://www.python.org/ftp/python/"
143 version "/Python-" version ".tar.xz"))
144 (sha256
145 (base32
146 "0hzgxl94hnflis0d6m4szjx0b52gah7wpmcg5g00q7am6xwhwb5n"))
147 (patches (search-patches "python-2.7-search-paths.patch"
148 "python-2-deterministic-build-info.patch"
149 "python-2.7-site-prefixes.patch"
150 "python-2.7-source-date-epoch.patch"
151 "python-2.7-adjust-tests.patch"
152 "python-cross-compile.patch"
153 "python-2.7-CVE-2021-3177.patch"
154 "python-2.7-expat-compat.patch"
155 "python-2.7-no-static-lib.patch"))
156 (modules '((guix build utils)))
157 (snippet
158 '(begin
159 ;; Ensure the bundled copies of these libraries are not used.
160 (for-each delete-file-recursively
161 '("Modules/_ctypes/libffi" "Modules/expat" "Modules/zlib"))
162
163 (substitute* "Modules/Setup.dist"
164 ;; Link Expat instead of embedding the bundled one.
165 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
166
167 ;; Suboptimal to delete failing tests here, but if we delete them in
168 ;; the arguments then we need to make sure to strip out that phase
169 ;; when it gets inherited by python and python-minimal.
170 (for-each delete-file
171 '("Lib/test/test_compileall.py"
172 "Lib/test/test_ctypes.py" ; fails on mips64el
173 "Lib/test/test_distutils.py"
174 "Lib/test/test_import.py"
175 "Lib/test/test_shutil.py"
176 "Lib/test/test_socket.py"
177 "Lib/test/test_subprocess.py"))))))
178 (outputs '("out"
179 "tk" ;tkinter; adds 50 MiB to the closure
180 "idle")) ;programming environment; weighs 5MB
181 (build-system gnu-build-system)
182 (arguments
183 `(#:test-target "test"
184 #:configure-flags
185 (list "--enable-shared" ;allow embedding
186 "--with-system-expat" ;for XML support
187 "--with-system-ffi" ;build ctypes
188 "--with-ensurepip=install" ;install pip and setuptools
189 "--with-computed-gotos" ;main interpreter loop optimization
190 "--enable-unicode=ucs4"
191
192 ;; FIXME: These flags makes Python significantly faster, but
193 ;; leads to non-reproducible binaries.
194 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
195 ;; "--enable-optimizations"
196
197 ;; Prevent the installed _sysconfigdata.py from retaining a reference
198 ;; to coreutils.
199 "INSTALL=install -c"
200 "MKDIR_P=mkdir -p"
201
202 ;; Disable runtime check failing if cross-compiling, see:
203 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
204 ,@(if (%current-target-system)
205 '("ac_cv_buggy_getaddrinfo=no"
206 "ac_cv_file__dev_ptmx=no"
207 "ac_cv_file__dev_ptc=no")
208 '())
209 ;; -fno-semantic-interposition reinstates some optimizations by gcc
210 ;; leading to around 15% speedup. This is the default starting from
211 ;; python 3.10.
212 "CFLAGS=-fno-semantic-interposition"
213 (string-append "LDFLAGS=-Wl,-rpath="
214 (assoc-ref %outputs "out") "/lib"
215 " -fno-semantic-interposition")
216 ;; Add a reference to libxcrypt in LIBS so that the sysconfigdata
217 ;; file records it and propagates it to programs linking against
218 ;; Python.
219 (let ((libxcrypt
220 (false-if-exception
221 (dirname
222 (search-input-file %build-inputs
223 "lib/libcrypt.so.1")))))
224 (string-append
225 "LIBS="
226 (if libxcrypt
227 (string-append "-L" libxcrypt)
228 ""))))
229 ;; With no -j argument tests use all available cpus, so provide one.
230 #:make-flags
231 (list (string-append
232 (format #f "TESTOPTS=-j~d" (parallel-job-count))
233 ;; Exclude the following tests as they fail
234 ;; non-deterministically with "error: [Errno 104] Connection
235 ;; reset by peer." Python 3 seems unaffected. A potential fix,
236 ;; yet to be backported to Python 2, is available at:
237 ;; https://github.com/python/cpython/commit/529525fb5a8fd9b96ab4021311a598c77588b918.
238 " --exclude test_urllib2_localnet test_httplib"))
239
240 #:modules ((ice-9 ftw) (ice-9 match)
241 (guix build utils) (guix build gnu-build-system))
242 #:phases
243 (modify-phases %standard-phases
244 (add-before
245 'configure 'patch-lib-shells
246 (lambda _
247 ;; This variable is used in setup.py to enable cross compilation
248 ;; specific switches. As it is not set properly by configure
249 ;; script, set it manually.
250 ,@(if (%current-target-system)
251 '((setenv "_PYTHON_HOST_PLATFORM" ""))
252 '())
253 ;; Filter for existing files, since some may not exist in all
254 ;; versions of python that are built with this recipe.
255 (substitute* (filter file-exists?
256 '("Lib/subprocess.py"
257 "Lib/popen2.py"
258 "Lib/distutils/tests/test_spawn.py"
259 "Lib/test/support/__init__.py"
260 "Lib/test/test_subprocess.py"))
261 (("/bin/sh") (which "sh")))))
262 ,@(if (system-hurd?)
263 `((add-before 'build 'patch-regen-for-hurd
264 (lambda* (#:key inputs #:allow-other-keys)
265 (let ((libc (assoc-ref inputs "libc")))
266 (substitute* "Lib/plat-generic/regen"
267 (("/usr/include/") (string-append libc "/include/")))))))
268 '())
269 (add-before 'configure 'do-not-record-configure-flags
270 (lambda* (#:key configure-flags #:allow-other-keys)
271 ;; Remove configure flags from the installed '_sysconfigdata.py'
272 ;; and 'Makefile' so we don't end up keeping references to the
273 ;; build tools.
274 ;;
275 ;; Preserve at least '--with-system-ffi' since otherwise the
276 ;; thing tries to build libffi, fails, and we end up with a
277 ;; Python that lacks ctypes.
278 (substitute* "configure"
279 (("^CONFIG_ARGS=.*$")
280 (format #f "CONFIG_ARGS='~a'\n"
281 (if (member "--with-system-ffi" configure-flags)
282 "--with-system-ffi"
283 ""))))))
284 (add-before 'check 'pre-check
285 (lambda _
286 ;; 'Lib/test/test_site.py' needs a valid $HOME
287 (setenv "HOME" (getcwd))))
288 (add-after 'unpack 'set-source-file-times-to-1980
289 ;; XXX One of the tests uses a ZIP library to pack up some of the
290 ;; source tree, and fails with "ZIP does not support timestamps
291 ;; before 1980". Work around this by setting the file times in the
292 ;; source tree to sometime in early 1980.
293 (lambda _
294 (let ((circa-1980 (* 10 366 24 60 60)))
295 (ftw "." (lambda (file stat flag)
296 (utime file circa-1980 circa-1980)
297 #t)))))
298 (add-after 'install 'remove-tests
299 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
300 ;; because these files are used by some libraries out there.
301 (lambda* (#:key outputs #:allow-other-keys)
302 (let ((out (assoc-ref outputs "out")))
303 (match (scandir (string-append out "/lib")
304 (lambda (name)
305 (string-prefix? "python" name)))
306 ((pythonX.Y)
307 (let ((testdir (string-append out "/lib/" pythonX.Y
308 "/test")))
309 (with-directory-excursion testdir
310 (for-each delete-file-recursively
311 (scandir testdir
312 (match-lambda
313 ((or "." "..") #f)
314 ("support" #f)
315 (file
316 (not
317 (string-prefix? "test_support."
318 file))))))
319 (call-with-output-file "__init__.py" (const #t))))
320 (let ((libdir (string-append out "/lib/" pythonX.Y)))
321 (for-each
322 (lambda (directory)
323 (let ((dir (string-append libdir "/" directory)))
324 (when (file-exists? dir)
325 (delete-file-recursively dir))))
326 '("email/test" "ctypes/test" "unittest/test" "tkinter/test"
327 "sqlite3/test" "bsddb/test" "lib-tk/test" "json/tests"
328 "distutils/tests"))))))))
329 (add-after 'install 'add-libxcrypt-reference-pkgconfig
330 (lambda* (#:key inputs outputs #:allow-other-keys)
331 (define out (assoc-ref outputs "out"))
332 (define libxcrypt
333 (false-if-exception
334 (dirname (search-input-file inputs "lib/libcrypt.so.1"))))
335 (when libxcrypt
336 (substitute*
337 (find-files (string-append out "/lib/pkgconfig")
338 ".*\\.pc")
339 (("-lcrypt")
340 (string-append "-L" libxcrypt " -lcrypt"))))))
341 (add-after 'remove-tests 'move-tk-inter
342 (lambda* (#:key outputs #:allow-other-keys)
343 ;; When Tkinter support is built move it to a separate output so
344 ;; that the main output doesn't contain a reference to Tcl/Tk.
345 (let ((out (assoc-ref outputs "out"))
346 (tk (assoc-ref outputs "tk")))
347 (when tk
348 (match (find-files out "tkinter.*\\.so")
349 ((tkinter.so)
350 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
351 ;; want it under TK/lib/pythonX.Y/site-packages.
352 (let* ((len (string-length out))
353 (target (string-append
354 tk "/"
355 (string-drop
356 (dirname (dirname tkinter.so))
357 len)
358 "/site-packages")))
359 (install-file tkinter.so target)
360 (delete-file tkinter.so))))))))
361 (add-after 'move-tk-inter 'move-idle
362 (lambda* (#:key outputs #:allow-other-keys)
363 ;; when idle is built, move it to a separate output to save some
364 ;; space (5MB)
365 (let ((out (assoc-ref outputs "out"))
366 (idle (assoc-ref outputs "idle")))
367 (when idle
368 (for-each
369 (lambda (file)
370 (let ((target (string-append idle "/bin/" (basename file))))
371 (install-file file (dirname target))
372 (delete-file file)))
373 (find-files (string-append out "/bin") "^idle"))
374 (match (find-files out "^idlelib$" #:directories? #t)
375 ((idlelib)
376 (let* ((len (string-length out))
377 (target (string-append idle "/"
378 (string-drop idlelib len)
379 "/site-packages")))
380 (mkdir-p (dirname target))
381 (rename-file idlelib target))))))))
382 (add-after 'move-idle 'rebuild-bytecode
383 (lambda* (#:key outputs #:allow-other-keys)
384 (let ((out (assoc-ref outputs "out")))
385 ;; Disable hash randomization to ensure the generated .pycs
386 ;; are reproducible.
387 (setenv "PYTHONHASHSEED" "0")
388 (for-each
389 (lambda (output)
390 (for-each (lambda (opt)
391 (format #t "Compiling with optimization level: ~a\n"
392 (if (null? opt) "none" (car opt)))
393 (apply invoke
394 `(,,(if (%current-target-system)
395 "python2"
396 '(string-append out "/bin/python"))
397 ,@opt
398 "-m" "compileall"
399 "-f" ; force rebuild
400 ;; Don't build lib2to3, because it contains
401 ;; Python 3 code.
402 "-x" "lib2to3/.*"
403 ,output)))
404 ;; Python 2 has a single file extension (.pyo) for the
405 ;; chosen level of optimization, so it doesn't make
406 ;; sense to byte compile with more than one level.
407 (list '() '("-OO"))))
408 (map cdr outputs)))))
409 (add-after 'install 'install-sitecustomize.py
410 ,(customize-site version)))))
411 (inputs
412 (list bzip2
413 expat
414 gdbm
415 libffi ; for ctypes
416 libxcrypt ; crypto module slated for removal in 3.13, re-enable
417 ; python tests of libxcrypt when that happens
418 sqlite ; for sqlite extension
419 openssl-1.1
420 readline
421 zlib
422 tcl
423 tk)) ; for tkinter
424 (native-inputs
425 `(("pkg-config" ,pkg-config)
426 ("sitecustomize.py" ,(local-file (search-auxiliary-file
427 "python/sitecustomize.py")))
428 ;; When cross-compiling, a native version of Python itself is needed.
429 ,@(if (%current-target-system)
430 `(("python2" ,this-package)
431 ("which" ,which))
432 '())))
433 (native-search-paths
434 (list (guix-pythonpath-search-path version)))
435 (home-page "https://www.python.org")
436 (synopsis "High-level, dynamically-typed programming language")
437 (description
438 "Python is a remarkably powerful dynamic programming language that
439is used in a wide variety of application domains. Some of its key
440distinguishing features include: clear, readable syntax; strong
441introspection capabilities; intuitive object orientation; natural
442expression of procedural code; full modularity, supporting hierarchical
443packages; exception-based error handling; and very high level dynamic
444data types.")
445 (properties '((cpe-name . "python")))
446 (license license:psfl)))
447
448;; Current 2.x version.
449(define-public python-2 python-2.7)
450
451(define-public python-3.10
452 (package
453 (inherit python-2)
454 (name "python")
455 (version "3.10.7")
456 (source (origin
457 (method url-fetch)
458 (uri (string-append "https://www.python.org/ftp/python/"
459 version "/Python-" version ".tar.xz"))
460 (patches (search-patches
461 "python-3-arm-alignment.patch"
462 "python-3-deterministic-build-info.patch"
463 "python-3-fix-tests.patch"
464 "python-3-hurd-configure.patch"
465 "python-3-reproducible-build.patch"
466 "python-3-search-paths.patch"))
467 (sha256
468 (base32
469 "0j6wvh2ad5jjq5n7sjmj1k66mh6lipabavchc3rb4vsinwaq9vbf"))
470 (modules '((guix build utils)))
471 (snippet
472 '(begin
473 ;; Delete the bundled copy of libexpat.
474 (delete-file-recursively "Modules/expat")
475 (substitute* "Modules/Setup"
476 ;; Link Expat instead of embedding the bundled one.
477 (("^#pyexpat.*") "pyexpat pyexpat.c -lexpat\n"))
478 ;; Delete windows binaries
479 (for-each delete-file
480 (find-files "Lib/distutils/command" "\\.exe$"))))))
481 (arguments
482 (substitute-keyword-arguments (package-arguments python-2)
483 ((#:configure-flags flags)
484 `(append ,flags '("--without-static-libpython")))
485 ((#:make-flags _)
486 `(list (string-append
487 (format #f "TESTOPTS=-j~d" (parallel-job-count))
488 ;; test_mmap fails on low-memory systems
489 " --exclude test_mmap test_socket"
490 ,@(if (system-hurd?)
491 '(" test_posix" ;multiple errors
492 " test_time"
493 " test_pty"
494 " test_shutil"
495 " test_tempfile" ;chflags: invalid argument:
496 ; tbv14c9t/dir0/dir0/dir0/test0.txt
497 " test_asyncio" ;runs over 10min
498 " test_os" ;stty: 'standard input':
499 ; Inappropriate ioctl for device
500 " test_openpty" ;No such file or directory
501 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
502 ; 32752 != 4
503 " test_compileall" ;multiple errors
504 " test_poll" ;list index out of range
505 " test_subprocess" ;runs over 10min
506 " test_asyncore" ;multiple errors
507 " test_threadsignals"
508 " test_eintr" ;Process return code is -14
509 " test_io" ;multiple errors
510 " test_logging"
511 " test_signal"
512 " test_threading" ;runs over 10min
513 " test_flags" ;ERROR
514 " test_bidirectional_pty"
515 " test_create_unix_connection"
516 " test_unix_sock_client_ops"
517 " test_open_unix_connection"
518 " test_open_unix_connection_error"
519 " test_read_pty_output"
520 " test_write_pty"
521 " test_concurrent_futures" ;freeze
522 " test_venv" ;freeze
523 " test_multiprocessing_forkserver" ;runs over 10min
524 " test_multiprocessing_spawn" ;runs over 10min
525 " test_builtin"
526 " test_capi"
527 " test_dbm_ndbm"
528 " test_exceptions"
529 " test_faulthandler"
530 " test_getopt"
531 " test_importlib"
532 " test_json"
533 " test_multiprocessing_fork"
534 " test_multiprocessing_main_handling"
535 " test_pdb "
536 " test_regrtest"
537 " test_sqlite")
538 '()))))
539 ((#:phases phases)
540 `(modify-phases ,phases
541 ,@(if (system-hurd?)
542 `((delete 'patch-regen-for-hurd) ;regen was removed after 3.5.9
543 (add-after 'unpack 'disable-multi-processing
544 (lambda _
545 (substitute* "Makefile.pre.in"
546 (("-j0") "-j1")))))
547 '())
548 (add-after 'unpack 'remove-vendored-wheel-content
549 (lambda _
550 ;; Delete .exe from embedded .whl (zip) files
551 (for-each
552 (lambda (whl)
553 (let ((dir "whl-content")
554 (circa-1980 (* 10 366 24 60 60)))
555 (mkdir-p dir)
556 (with-directory-excursion dir
557 (let ((whl (string-append "../" whl)))
558 (invoke "unzip" whl)
559 (for-each delete-file
560 (find-files "." "\\.exe$"))
561 (delete-file whl)
562
563 ;; Search for cacert.pem, delete it, and rewrite the
564 ;; file which directs python to look for it.
565 (let ((cacert (find-files "." "cacert\\.pem")))
566 (unless (null? cacert)
567 (let ((certifi (dirname (car cacert))))
568 (delete-file (string-append certifi "/cacert.pem"))
569 (delete-file (string-append certifi "/core.py"))
570 (with-output-to-file (string-append certifi "/core.py")
571 (lambda _
572 (display "\"\"\"
573certifi.py
574~~~~~~~~~~
575This file is a Guix-specific version of core.py.
576
577This module returns the installation location of SSL_CERT_FILE or
578/etc/ssl/certs/ca-certificates.crt, or its contents.
579\"\"\"
580import os
581
582_CA_CERTS = None
583
584try:
585 _CA_CERTS = os.environ [\"SSL_CERT_FILE\"]
586except:
587 _CA_CERTS = os.path.join(\"/etc\", \"ssl\", \"certs\", \"ca-certificates.crt\")
588
589def where() -> str:
590 return _CA_CERTS
591
592def contents() -> str:
593 with open(where(), \"r\", encoding=\"ascii\") as data:
594 return data.read()"))))))
595
596 ;; Reset timestamps to prevent them from ending
597 ;; up in the Zip archive.
598 (ftw "." (lambda (file stat flag)
599 (utime file circa-1980 circa-1980)
600 #t))
601 (apply invoke "zip" "-X" whl
602 (find-files "." #:directories? #t))))
603 (delete-file-recursively dir)))
604 (find-files "Lib/ensurepip" "\\.whl$"))))
605 (add-before 'check 'set-TZDIR
606 (lambda* (#:key inputs native-inputs #:allow-other-keys)
607 ;; test_email requires the Olson time zone database.
608 (setenv "TZDIR"
609 (string-append (assoc-ref
610 (or native-inputs inputs) "tzdata")
611 "/share/zoneinfo"))))
612 (replace 'rebuild-bytecode
613 (lambda* (#:key outputs #:allow-other-keys)
614 (let ((out (assoc-ref outputs "out")))
615 ;; Disable hash randomization to ensure the generated .pycs
616 ;; are reproducible.
617 (setenv "PYTHONHASHSEED" "0")
618
619 (for-each (lambda (output)
620 ;; XXX: Delete existing pycs generated by the build
621 ;; system beforehand because the -f argument does
622 ;; not necessarily overwrite all files, leading to
623 ;; indeterministic results.
624 (for-each (lambda (pyc)
625 (delete-file pyc))
626 (find-files output "\\.pyc$"))
627
628 (apply invoke
629 `(,,(if (%current-target-system)
630 "python3"
631 '(string-append out
632 "/bin/python3"))
633 "-m" "compileall"
634 "-o" "0" "-o" "1" "-o" "2"
635 "-f" ; force rebuild
636 "--invalidation-mode=unchecked-hash"
637 ;; Don't build lib2to3, because it's
638 ;; Python 2 code.
639 "-x" "lib2to3/.*"
640 ,output)))
641 (map cdr outputs)))))
642 (replace 'install-sitecustomize.py
643 ,(customize-site version))))))
644 (inputs
645 (modify-inputs (package-inputs python-2.7)
646 (replace "openssl" openssl)))
647 (native-inputs
648 (let ((inputs (modify-inputs (package-native-inputs python-2)
649 (prepend tzdata-for-tests
650 unzip
651 (@ (gnu packages compression) zip)))))
652 (if (%current-target-system)
653 (modify-inputs inputs (prepend this-package))
654 inputs)))
655 (native-search-paths
656 (list (guix-pythonpath-search-path version)
657 ;; Used to locate tzdata by the zoneinfo module introduced in
658 ;; Python 3.9.
659 (search-path-specification
660 (variable "PYTHONTZPATH")
661 (files (list "share/zoneinfo")))))))
662
663(define-public python-3.12
664 (package
665 (name "python-next")
666 (version "3.12.2")
667 (source
668 (origin
669 (method url-fetch)
670 (uri (string-append "https://www.python.org/ftp/python/" version
671 "/Python-" version ".tar.xz"))
672 (sha256
673 (base32 "0w6qyfhc912xxav9x9pifwca40b4l49vy52wai9j0gc1mhni2a5y"))
674 (patches (search-patches "python-3-deterministic-build-info.patch"
675 "python-3.12-fix-tests.patch"
676 "python-3-hurd-configure.patch"))
677 (modules '((guix build utils)))
678 (snippet '(begin
679 ;; Delete the bundled copy of libexpat.
680 (delete-file-recursively "Modules/expat")
681 (substitute* "Modules/Setup"
682 ;; Link Expat instead of embedding the bundled one.
683 (("^#pyexpat.*")
684 "pyexpat pyexpat.c -lexpat\n"))
685 ;; Delete windows binaries
686 (for-each delete-file
687 (find-files "Lib/distutils/command" "\\.exe$"))))))
688 (outputs '("out" "tk" ;tkinter; adds 50 MiB to the closure
689 "idle")) ;programming environment; weighs 5MB
690 (build-system gnu-build-system)
691 (arguments
692 `(#:test-target "test"
693 #:configure-flags (list "--enable-shared" ;allow embedding
694 "--with-system-expat" ;for XML support
695 "--with-system-ffi" ;build ctypes
696 "--with-ensurepip=install" ;install pip and setuptools
697 "--with-computed-gotos" ;main interpreter loop optimization
698 "--enable-unicode=ucs4"
699 "--without-static-libpython"
700 "--enable-loadable-sqlite-extensions"
701
702 ;; FIXME: These flags makes Python significantly faster,
703 ;; but leads to non-reproducible binaries.
704 ;; "--with-lto" ;increase size by 20MB, but 15% speedup
705 ;; "--enable-optimizations"
706
707 ;; Prevent the installed _sysconfigdata.py from retaining
708 ;; a reference to coreutils.
709 "INSTALL=install -c"
710 "MKDIR_P=mkdir -p"
711
712 ;; Disable runtime check failing if cross-compiling, see:
713 ;; https://lists.yoctoproject.org/pipermail/poky/2013-June/008997.html
714 ,@(if (%current-target-system)
715 '("ac_cv_buggy_getaddrinfo=no"
716 "ac_cv_file__dev_ptmx=no"
717 "ac_cv_file__dev_ptc=no")
718 '())
719 ;; -fno-semantic-interposition reinstates some
720 ;; optimizations by gcc leading to around 15% speedup.
721 ;; This is the default starting from python 3.10.
722 "CFLAGS=-fno-semantic-interposition"
723 (string-append "LDFLAGS=-Wl,-rpath="
724 (assoc-ref %outputs "out")
725 "/lib"
726 " -fno-semantic-interposition"))
727 ;; With no -j argument tests use all available cpus, so provide one.
728 #:make-flags (list (string-append (format #f "TESTOPTS=-j~d"
729 (parallel-job-count))
730 ;; those tests fail on low-memory systems
731 " --exclude"
732 " test_mmap"
733 " test_socket"
734 " test_threading"
735 " test_asyncio"
736 " test_shutdown"
737 ,@(if (system-hurd?)
738 '(" test_posix" ;multiple errors
739 " test_time"
740 " test_pty"
741 " test_shutil"
742 " test_tempfile" ;chflags: invalid argument:
743 ;; tbv14c9t/dir0/dir0/dir0/test0.txt
744 " test_os" ;stty: 'standard input':
745 ;; Inappropriate ioctl for device
746 " test_openpty" ;No such file or directory
747 " test_selectors" ;assertEqual(NUM_FDS // 2, len(fds))
748 ;; 32752 != 4
749 " test_compileall" ;multiple errors
750 " test_poll" ;list index out of range
751 " test_subprocess" ;runs over 10min
752 " test_asyncore" ;multiple errors
753 " test_threadsignals"
754 " test_eintr" ;Process return code is -14
755 " test_io" ;multiple errors
756 " test_logging"
757 " test_signal"
758 " test_flags" ;ERROR
759 " test_bidirectional_pty"
760 " test_create_unix_connection"
761 " test_unix_sock_client_ops"
762 " test_open_unix_connection"
763 " test_open_unix_connection_error"
764 " test_read_pty_output"
765 " test_write_pty"
766 " test_concurrent_futures" ;freeze
767 " test_venv" ;freeze
768 " test_multiprocessing_forkserver" ;runs over 10min
769 " test_multiprocessing_spawn" ;runs over 10min
770 " test_builtin"
771 " test_capi"
772 " test_dbm_ndbm"
773 " test_exceptions"
774 " test_faulthandler"
775 " test_getopt"
776 " test_importlib"
777 " test_json"
778 " test_multiprocessing_fork"
779 " test_multiprocessing_main_handling"
780 " test_pdb "
781 " test_regrtest"
782 " test_sqlite")
783 '())))
784
785 #:modules ((ice-9 ftw)
786 (ice-9 match)
787 (guix build utils)
788 (guix build gnu-build-system))
789
790 #:phases (modify-phases %standard-phases
791 ,@(if (system-hurd?)
792 `((add-after 'unpack
793 'disable-multi-processing
794 (lambda _
795 (substitute* "Makefile.pre.in"
796 (("-j0")
797 "-j1")))))
798 '())
799 (add-before 'configure 'patch-lib-shells
800 (lambda _
801 ;; This variable is used in setup.py to enable cross compilation
802 ;; specific switches. As it is not set properly by configure
803 ;; script, set it manually.
804 ,@(if (%current-target-system)
805 '((setenv "_PYTHON_HOST_PLATFORM" ""))
806 '())
807 ;; Filter for existing files, since some may not exist in all
808 ;; versions of python that are built with this recipe.
809 (substitute* (filter file-exists?
810 '("Lib/subprocess.py"
811 "Lib/popen2.py"
812 "Lib/distutils/tests/test_spawn.py"
813 "Lib/test/support/__init__.py"
814 "Lib/test/test_subprocess.py"))
815 (("/bin/sh")
816 (which "sh")))))
817 (add-before 'configure 'do-not-record-configure-flags
818 (lambda* (#:key configure-flags #:allow-other-keys)
819 ;; Remove configure flags from the installed '_sysconfigdata.py'
820 ;; and 'Makefile' so we don't end up keeping references to the
821 ;; build tools.
822 ;;
823 ;; Preserve at least '--with-system-ffi' since otherwise the
824 ;; thing tries to build libffi, fails, and we end up with a
825 ;; Python that lacks ctypes.
826 (substitute* "configure"
827 (("^CONFIG_ARGS=.*$")
828 (format #f "CONFIG_ARGS='~a'\n"
829 (if (member "--with-system-ffi"
830 configure-flags)
831 "--with-system-ffi" ""))))))
832 (add-before 'check 'pre-check
833 (lambda _
834 ;; 'Lib/test/test_site.py' needs a valid $HOME
835 (setenv "HOME"
836 (getcwd))))
837 (add-after 'unpack 'set-source-file-times-to-1980
838 ;; XXX One of the tests uses a ZIP library to pack up some of the
839 ;; source tree, and fails with "ZIP does not support timestamps
840 ;; before 1980". Work around this by setting the file times in the
841 ;; source tree to sometime in early 1980.
842 (lambda _
843 (let ((circa-1980 (* 10 366 24 60 60)))
844 (ftw "."
845 (lambda (file stat flag)
846 (utime file circa-1980 circa-1980) #t)))))
847 (add-after 'unpack 'remove-windows-binaries
848 (lambda _
849 ;; Delete .exe from embedded .whl (zip) files
850 (for-each (lambda (whl)
851 (let ((dir "whl-content")
852 (circa-1980 (* 10 366 24 60 60)))
853 (mkdir-p dir)
854 (with-directory-excursion dir
855 (let ((whl (string-append "../" whl)))
856 (invoke "unzip" whl)
857 (for-each delete-file
858 (find-files "." "\\.exe$"))
859 (delete-file whl)
860 ;; Reset timestamps to prevent them from ending
861 ;; up in the Zip archive.
862 (ftw "."
863 (lambda (file stat flag)
864 (utime file circa-1980
865 circa-1980) #t))
866 (apply invoke "zip" "-X" whl
867 (find-files "."
868 #:directories? #t))))
869 (delete-file-recursively dir)))
870 (find-files "Lib/ensurepip" "\\.whl$"))))
871 (add-after 'install 'remove-tests
872 ;; Remove 25 MiB of unneeded unit tests. Keep test_support.*
873 ;; because these files are used by some libraries out there.
874 (lambda* (#:key outputs #:allow-other-keys)
875 (let ((out (assoc-ref outputs "out")))
876 (match (scandir (string-append out "/lib")
877 (lambda (name)
878 (string-prefix? "python" name)))
879 ((pythonX.Y)
880 (let ((testdir (string-append out "/lib/" pythonX.Y
881 "/test")))
882 (with-directory-excursion testdir
883 (for-each delete-file-recursively
884 (scandir testdir
885 (match-lambda
886 ((or "." "..")
887 #f)
888 ("support" #f)
889 (file (not (string-prefix?
890 "test_support."
891 file))))))
892 (call-with-output-file "__init__.py"
893 (const #t))))
894 (let ((libdir (string-append out "/lib/" pythonX.Y)))
895 (for-each (lambda (directory)
896 (let ((dir (string-append libdir "/"
897 directory)))
898 (when (file-exists? dir)
899 (delete-file-recursively dir))))
900 '("email/test" "ctypes/test"
901 "unittest/test"
902 "tkinter/test"
903 "sqlite3/test"
904 "bsddb/test"
905 "lib-tk/test"
906 "json/tests"
907 "distutils/tests"))))))))
908 (add-after 'remove-tests 'move-tk-inter
909 (lambda* (#:key outputs inputs #:allow-other-keys)
910 ;; When Tkinter support is built move it to a separate output so
911 ;; that the main output doesn't contain a reference to Tcl/Tk.
912 (let ((out (assoc-ref outputs "out"))
913 (tk (assoc-ref outputs "tk")))
914 (when tk
915 (match (find-files out "tkinter.*\\.so")
916 ((tkinter.so)
917 ;; The .so is in OUT/lib/pythonX.Y/lib-dynload, but we
918 ;; want it under TK/lib/pythonX.Y/site-packages.
919 (let* ((len (string-length out))
920 (target (string-append tk "/"
921 (string-drop (dirname
922 (dirname
923 tkinter.so))
924 len)
925 "/site-packages")))
926 (install-file tkinter.so target)
927 (delete-file tkinter.so))))
928 ;; Remove explicit store path references.
929 (let ((tcl (assoc-ref inputs "tcl"))
930 (tk (assoc-ref inputs "tk")))
931 (substitute* (find-files (string-append out "/lib")
932 "^(_sysconfigdata_.*\\.py|Makefile)$")
933 (((string-append "-L" tk "/lib"))
934 "")
935 (((string-append "-L" tcl "/lib"))
936 "")))))))
937 (add-after 'move-tk-inter 'move-idle
938 (lambda* (#:key outputs #:allow-other-keys)
939 ;; when idle is built, move it to a separate output to save some
940 ;; space (5MB)
941 (let ((out (assoc-ref outputs "out"))
942 (idle (assoc-ref outputs "idle")))
943 (when idle
944 (for-each (lambda (file)
945 (let ((target (string-append idle
946 "/bin/"
947 (basename
948 file))))
949 (install-file file
950 (dirname target))
951 (delete-file file)))
952 (find-files (string-append out "/bin")
953 "^idle"))
954 (match (find-files out "^idlelib$"
955 #:directories? #t)
956 ((idlelib)
957 (let* ((len (string-length out))
958 (target (string-append idle "/"
959 (string-drop
960 idlelib len)
961 "/site-packages")))
962 (mkdir-p (dirname target))
963 (rename-file idlelib target))))))))
964 (add-after 'move-idle 'rebuild-bytecode
965 (lambda* (#:key outputs #:allow-other-keys)
966 (let ((out (assoc-ref outputs "out")))
967 ;; Disable hash randomization to ensure the generated .pycs
968 ;; are reproducible.
969 (setenv "PYTHONHASHSEED" "0")
970
971 (for-each (lambda (output)
972 ;; XXX: Delete existing pycs generated by the build
973 ;; system beforehand because the -f argument does
974 ;; not necessarily overwrite all files, leading to
975 ;; indeterministic results.
976 (for-each (lambda (pyc)
977 (delete-file pyc))
978 (find-files output "\\.pyc$"))
979
980 (apply invoke
981 `(,,(if (%current-target-system)
982 "python3"
983 '(string-append out
984 "/bin/python3")) "-m"
985 "compileall"
986 "-o"
987 "0"
988 "-o"
989 "1"
990 "-o"
991 "2"
992 "-f" ;force rebuild
993 "--invalidation-mode=unchecked-hash"
994 ;; Don't build lib2to3, because it's
995 ;; Python 2 code.
996 "-x"
997 "lib2to3/.*"
998 ,output)))
999 (map cdr outputs)))))
1000 (add-before 'check 'set-TZDIR
1001 (lambda* (#:key inputs native-inputs #:allow-other-keys)
1002 ;; test_email requires the Olson time zone database.
1003 (setenv "TZDIR"
1004 (string-append (assoc-ref (or native-inputs
1005 inputs) "tzdata")
1006 "/share/zoneinfo"))))
1007 (add-after 'install 'install-sitecustomize.py
1008 ,(customize-site version)))))
1009 (inputs (list bzip2
1010 expat
1011 gdbm
1012 libffi ;for ctypes
1013 sqlite ;for sqlite extension
1014 openssl
1015 readline
1016 zlib
1017 tcl
1018 tk)) ;for tkinter
1019 (native-inputs `(("tzdata" ,tzdata-for-tests)
1020 ("unzip" ,unzip)
1021 ("zip" ,(@ (gnu packages compression) zip))
1022 ("pkg-config" ,pkg-config)
1023 ("sitecustomize.py" ,(local-file (search-auxiliary-file
1024 "python/sitecustomize.py")))
1025 ;; When cross-compiling, a native version of Python itself is needed.
1026 ,@(if (%current-target-system)
1027 `(("python" ,this-package)
1028 ("which" ,which))
1029 '())))
1030 (native-search-paths
1031 (list (guix-pythonpath-search-path version)
1032 ;; Used to locate tzdata by the zoneinfo module introduced in
1033 ;; Python 3.9.
1034 (search-path-specification
1035 (variable "PYTHONTZPATH")
1036 (files (list "share/zoneinfo")))))
1037 (home-page "https://www.python.org")
1038 (synopsis "High-level, dynamically-typed programming language")
1039 (description
1040 "Python is a remarkably powerful dynamic programming language that
1041is used in a wide variety of application domains. Some of its key
1042distinguishing features include: clear, readable syntax; strong
1043introspection capabilities; intuitive object orientation; natural
1044expression of procedural code; full modularity, supporting hierarchical
1045packages; exception-based error handling; and very high level dynamic
1046data types.")
1047 (properties '((cpe-name . "python")))
1048 (license license:psfl)))
1049
1050;; Next 3.x version.
1051(define-public python-next python-3.12)
1052
1053;; Current 3.x version.
1054(define-public python-3 python-3.10)
1055
1056;; Current major version.
1057(define-public python python-3)
1058
1059;; Minimal variants of Python, mostly used to break the cycle between Tk and
1060;; Python (Tk -> libxcb -> Python.)
1061
1062(define-public python2-minimal
1063 (package/inherit python-2
1064 (name "python2-minimal")
1065 (outputs '("out"))
1066
1067 ;; Keep zlib, which is used by 'pip' (via the 'zipimport' module), which
1068 ;; is invoked upon 'make install'. 'pip' also expects 'ctypes' and thus
1069 ;; libffi. Expat is needed for XML support which is expected by a lot
1070 ;; of libraries out there.
1071 (inputs (list expat libffi zlib))))
1072
1073(define-public python-minimal
1074 (package/inherit python
1075 (name "python-minimal")
1076 (outputs '("out"))
1077
1078 ;; Build fails due to missing ctypes without libffi.
1079 ;; OpenSSL is a mandatory dependency of Python 3.x, for urllib;
1080 ;; zlib is required by 'zipimport', used by pip. Expat is needed
1081 ;; for XML support, which is generally expected to be available.
1082 (inputs (list expat libffi openssl zlib))))
1083
1084(define-public python-debug
1085 (package/inherit python
1086 (name "python-debug")
1087 (outputs '("out" "debug"))
1088 (build-system gnu-build-system)
1089 (arguments
1090 (substitute-keyword-arguments (package-arguments python)
1091 ((#:configure-flags flags '())
1092 `(cons "--with-pydebug" ,flags))))
1093 (synopsis
1094 "Python with the debug hooks enabled")
1095 (description
1096 "This variant of Python provides an interpreter built with
1097@code{--with-pydebug} to help develop and debug extensions. See
1098@url{https://pythonextensionpatterns.readthedocs.io/en/latest/debugging/debug.html},
1099for more information.")))
1100
1101(define* (wrap-python3 python
1102 #:optional
1103 (name (string-append (package-name python) "-wrapper")))
1104 (package/inherit python
1105 (name name)
1106 (source #f)
1107 (build-system trivial-build-system)
1108 (outputs '("out"))
1109 (inputs `(("bash" ,bash)))
1110 (propagated-inputs `(("python" ,python)))
1111 (arguments
1112 (list #:modules '((guix build utils))
1113 #:builder
1114 #~(begin
1115 (use-modules (guix build utils))
1116 (let ((bin (string-append #$output "/bin"))
1117 (python (string-append
1118 ;; XXX: '%build-inputs' contains the native
1119 ;; Python when cross-compiling.
1120 #$(if (%current-target-system)
1121 (this-package-input "python")
1122 #~(assoc-ref %build-inputs "python"))
1123 "/bin/")))
1124 (mkdir-p bin)
1125 (for-each
1126 (lambda (old new)
1127 (symlink (string-append python old)
1128 (string-append bin "/" new)))
1129 `("python3" ,"pydoc3" ,"pip3")
1130 `("python" ,"pydoc" ,"pip"))
1131 ;; python-config outputs search paths based upon its location,
1132 ;; use a bash wrapper to avoid changing its outputs.
1133 (let ((bash (string-append (assoc-ref %build-inputs "bash")
1134 "/bin/bash"))
1135 (old (string-append python "python3-config"))
1136 (new (string-append bin "/python-config")))
1137 (with-output-to-file new
1138 (lambda ()
1139 (format #t "#!~a~%" bash)
1140 (format #t "exec \"~a\" \"$@\"~%" old)
1141 (chmod new #o755))))))))
1142 (synopsis "Wrapper for the Python 3 commands")
1143 (description
1144 "This package provides wrappers for the commands of Python@tie{}3.x such
1145that they can also be invoked under their usual names---e.g., @command{python}
1146instead of @command{python3} or @command{pip} instead of @command{pip3}.
1147
1148To function properly, this package should not be installed together with the
1149@code{python} package: this package uses the @code{python} package as a
1150propagated input, so installing this package already makes both the versioned
1151and the unversioned commands available.")))
1152
1153(define-public python-wrapper (wrap-python3 python))
1154(define-public python-minimal-wrapper (wrap-python3 python-minimal))
1155
1156;; The Python used in pyproject-build-system.
1157(define-public python-sans-pip
1158 (hidden-package
1159 (package/inherit python
1160 (arguments
1161 (substitute-keyword-arguments (package-arguments python)
1162 ((#:configure-flags flags #~())
1163 #~(append '("--with-ensurepip=no")
1164 (delete "--with-ensurepip=install" #$flags))))))))
1165
1166(define-public python-sans-pip-wrapper
1167 (wrap-python3 python-sans-pip))
1168
1169(define-public python-toolchain
1170 (let ((base (package/inherit python-sans-pip-wrapper)))
1171 (package
1172 (inherit base)
1173 (properties '())
1174 (name "python-toolchain")
1175 (propagated-inputs
1176 (modify-inputs (package-propagated-inputs base)
1177 (append python-pip
1178 python-pypa-build
1179 python-setuptools
1180 python-wheel)))
1181 (synopsis "Python toolchain")
1182 (description
1183 "Python toolchain including Python itself, setuptools and pip.
1184Use this package if you need a minimal Python toolchain instead of just
1185the interpreter."))))
1186
1187(define-public micropython
1188 (package
1189 (name "micropython")
1190 (version "1.19")
1191 (source
1192 (origin
1193 (method url-fetch)
1194 (uri (string-append "https://github.com/micropython/micropython/"
1195 "releases/download/v" version
1196 "/micropython-" version ".tar.xz"))
1197 (sha256
1198 (base32 "090bbls5vnicynjyjqqd5zqwx8d6zxp7wlnrxgh0b4s8cyf5i8zj"))
1199 (modules '((guix build utils)))
1200 (snippet
1201 '(begin
1202 (delete-file-recursively "ports/cc3200/FreeRTOS")
1203 (with-directory-excursion "lib"
1204 ;; TODO: Unbundle axtls and berkley-db-1.xx
1205 (for-each delete-file-recursively
1206 '("libffi" "lwip" "stm32lib" "nrfx")))))))
1207 (build-system gnu-build-system)
1208 (arguments
1209 (list #:phases
1210 #~(modify-phases %standard-phases
1211 (add-before 'build 'build-mpy-cross
1212 (lambda* (#:key make-flags #:allow-other-keys)
1213 (with-directory-excursion "mpy-cross"
1214 (apply invoke "make" make-flags))))
1215 (add-after 'build-mpy-cross 'prepare-build
1216 (lambda _
1217 (chdir "ports/unix")
1218 ;; see: https://github.com/micropython/micropython/pull/4246
1219 (substitute* "Makefile"
1220 (("-Os") "-Os -ffp-contract=off"))))
1221 (add-before 'install-license-files 'chdir-back
1222 ;; We don't build in the root directory so the file isn't found.
1223 (lambda _
1224 (chdir "../..")))
1225 (delete 'configure)) ; no configure
1226 #:make-flags
1227 #~(list (string-append "PREFIX=" #$output)
1228 "V=1")
1229 #:test-target "test"))
1230 (native-inputs (list pkg-config python-wrapper))
1231 (inputs
1232 (list libffi))
1233 (home-page "https://micropython.org/")
1234 (synopsis "Python implementation for microcontrollers and constrained systems")
1235 (description "MicroPython is a lean and efficient implementation of the
1236Python 3 programming language that includes a small subset of the Python
1237standard library and is optimised to run on microcontrollers and in constrained
1238environments. MicroPython is packed full of advanced features such as an
1239interactive prompt, arbitrary precision integers, closures, list comprehension,
1240generators, exception handling and more. Still it is compact enough to fit and
1241run within just 256k of code space and 16k of RAM. MicroPython aims to be as
1242compatible with normal Python as possible to allow you to transfer code with
1243ease from the desktop to a microcontroller or embedded system.")
1244 (license license:expat)))