1 # Copyright 1999-2025 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
8 VERIFY_SIG_METHOD=sigstore
11 inherit autotools check-reqs flag-o-matic linux-info llvm-r1
12 inherit multiprocessing pax-utils python-utils-r1 toolchain-funcs
16 MY_P="Python-${MY_PV%_p*}"
17 PYVER="$(ver_cut 1-2)t"
18 PATCHSET="python-gentoo-patches-${MY_PV}"
20 DESCRIPTION="Freethreading (no-GIL) version of Python programming language"
22 https://www.python.org/
23 https://github.com/python/cpython/
26 https://www.python.org/ftp/python/${PV%%_*}/${MY_P}.tar.xz
27 https://dev.gentoo.org/~mgorny/dist/python/${PATCHSET}.tar.xz
29 https://www.python.org/ftp/python/${PV%%_*}/${MY_P}.tar.xz.sigstore
32 S="${WORKDIR}/${MY_P}"
37 bluetooth build debug +ensurepip examples gdbm jit
38 libedit +ncurses pgo +readline +sqlite +ssl test tk valgrind
40 REQUIRED_USE="jit? ( ${LLVM_REQUIRED_USE} )"
41 RESTRICT="!test? ( test )"
43 # Do not add a dependency on dev-lang/python to this ebuild.
44 # If you need to apply a patch which requires python for bootstrapping, please
45 # run the bootstrap code on your dev box and include the results in the
46 # patchset. See bug 447752.
51 >=dev-libs/expat-2.1:=
54 dev-python/gentoo-common
55 >=sys-libs/zlib-1.1.3:=
57 ensurepip? ( dev-python/ensurepip-pip )
58 gdbm? ( sys-libs/gdbm:=[berkdb] )
59 kernel_linux? ( sys-apps/util-linux:= )
60 ncurses? ( >=sys-libs/ncurses-5.2:= )
62 !libedit? ( >=sys-libs/readline-4.1:= )
63 libedit? ( dev-libs/libedit:= )
65 sqlite? ( >=dev-db/sqlite-3.3.8:3= )
66 ssl? ( >=dev-libs/openssl-1.1.1:= )
74 # bluetooth requires headers from bluez
77 bluetooth? ( net-wireless/bluez )
79 dev-python/ensurepip-pip
80 dev-python/ensurepip-setuptools
81 dev-python/ensurepip-wheel
83 valgrind? ( dev-debug/valgrind )
85 # autoconf-archive needed to eautoreconf
87 dev-build/autoconf-archive
92 llvm-core/clang:${LLVM_SLOT}
93 llvm-core/llvm:${LLVM_SLOT}
96 verify-sig? ( >=sec-keys/openpgp-keys-python-20221025 )
99 !build? ( app-misc/mime-types )
101 if [[ ${PV} != *_alpha* ]]; then
103 dev-lang/python-exec[python_targets_python${PYVER/./_}(-)]
107 # https://www.python.org/downloads/metadata/sigstore/
108 VERIFY_SIG_CERT_IDENTITY=hugo@python.org
109 VERIFY_SIG_CERT_OIDC_ISSUER=https://github.com/login/oauth
111 # large file tests involve a 2.5G file being copied (duplicated)
112 CHECKREQS_DISK_BUILD=5500M
114 QA_PKGCONFIG_VERSION=${PYVER%t}
115 # false positives -- functions specific to *BSD
116 QA_CONFIG_IMPL_DECL_SKIP=( chflags lchflags )
118 declare -rgA PYTHON_KERNEL_CHECKS=(
119 ["CROSS_MEMORY_ATTACH"]="test_external_inspection" #bug 938589
120 ["DNOTIFY"]="test_fcntl" # bug 938662
124 if use pgo || use test; then
125 check-reqs_pkg_pretend
128 ewarn "Freethreading build is considered experimental upstream. Using it"
129 ewarn "could lead to unexpected breakage, including race conditions"
130 ewarn "and crashes, respectively. Please do not file Gentoo bugs, unless"
131 ewarn "you can reproduce the problem with dev-lang/python. Instead,"
132 ewarn "please consider reporting freethreading problems upstream."
136 if [[ ${MERGE_TYPE} != binary ]]; then
137 use jit && llvm-r1_pkg_setup
138 if use test || use pgo; then
142 for f in "${!PYTHON_KERNEL_CHECKS[@]}"; do
143 CONFIG_CHECK+="~${f} "
151 if use verify-sig; then
152 verify-sig_verify_detached "${DISTDIR}"/${MY_P}.tar.xz{,.sigstore}
158 # Ensure that internal copies of expat and libffi are not used.
159 # TODO: Makefile has annoying deps on expat headers
160 #rm -r Modules/expat || die
163 "${WORKDIR}/${PATCHSET}"
168 # force the correct number of jobs
169 # https://bugs.gentoo.org/737660
170 sed -i -e "s:-j0:-j$(makeopts_jobs):" Makefile.pre.in || die
172 # breaks tests when using --with-wheel-pkg-dir
173 rm -r Lib/test/wheeldata || die
178 build_cbuild_python() {
179 # Hack to workaround get_libdir not being able to handle CBUILD, bug #794181
180 local cbuild_libdir=$(unset PKG_CONFIG_PATH ; $(tc-getBUILD_PKG_CONFIG) --keep-system-libs --libs-only-L libffi)
182 # pass system CFLAGS & LDFLAGS as _NODIST, otherwise they'll get
183 # propagated to sysconfig for built extensions
185 # -fno-lto to avoid bug #700012 (not like it matters for mini-CBUILD Python anyway)
186 local -x CFLAGS_NODIST="${BUILD_CFLAGS} -fno-lto"
187 local -x LDFLAGS_NODIST=${BUILD_LDFLAGS}
188 local -x CFLAGS= LDFLAGS=
189 local -x BUILD_CFLAGS="${CFLAGS_NODIST}"
190 local -x BUILD_LDFLAGS=${LDFLAGS_NODIST}
192 # We need to build our own Python on CBUILD first, and feed it in.
194 local myeconfargs_cbuild=(
197 --prefix="${BROOT}"/usr
198 --libdir="${cbuild_libdir:2}"
200 # Avoid needing to load the right libpython.so.
203 # As minimal as possible for the mini CBUILD Python
204 # we build just for cross to satisfy --with-build-python.
207 --disable-optimizations
210 mkdir "${WORKDIR}"/${P}-${CBUILD} || die
211 pushd "${WORKDIR}"/${P}-${CBUILD} &> /dev/null || die
213 # Avoid as many dependencies as possible for the cross build.
215 cat > Modules/Setup.local <<-EOF || die
221 _curses _curses_panel
226 # We disabled these for CBUILD because Python's setup.py can't handle locating
227 # libdir correctly for cross. This should be rechecked for the pure Makefile approach,
228 # and uncommented if needed.
232 ECONF_SOURCE="${S}" econf_build "${myeconfargs_cbuild[@]}"
234 # Unfortunately, we do have to build this immediately, and
235 # not in src_compile, because CHOST configure for Python
236 # will check the existence of the --with-build-python value
239 popd &> /dev/null || die
243 # disable automagic bluetooth headers detection
244 if ! use bluetooth; then
245 local -x ac_cv_header_bluetooth_bluetooth_h=no
249 filter-flags -malign-double
251 # Export CXX so it ends up in /usr/lib/python3.X/config/Makefile.
252 # PKG_CONFIG needed for cross.
253 tc-export CXX PKG_CONFIG
257 dbmliborder+="${dbmliborder:+:}gdbm"
260 # Set baseline test skip flags.
262 # this is actually test_gdb.test_pretty_print
264 # https://bugs.gentoo.org/933840
265 -x test_perf_profiler
268 # Arch-specific skips. See #931888 for a collection of these.
277 -x test_free_threading
279 -x test_numeric_tower
295 -x test_external_inspection
299 powerpc64-*) # big endian
312 -x test_multiprocessing_fork
313 -x test_multiprocessing_forkserver
314 -x test_multiprocessing_spawn
324 # Kernel-config specific skips
325 for option in "${!PYTHON_KERNEL_CHECKS[@]}"; do
326 if ! linux_config_exists || ! linux_chkconfig_present "${option}"
328 COMMON_TEST_SKIPS+=( -x "${PYTHON_KERNEL_CHECKS[${option}]}" )
332 # musl-specific skips
333 use elibc_musl && COMMON_TEST_SKIPS+=(
334 # various musl locale deficiencies
336 -x test_c_locale_coercion
340 # known issues with find_library on musl
341 # https://bugs.python.org/issue21622
344 # fpathconf, ttyname errno values
349 local profile_task_flags=(
356 # We use a timeout because of how often we've had hang issues
357 # here. It also matches the default upstream PROFILE_TASK.
360 "${COMMON_TEST_SKIPS[@]}"
364 # All of these seem to occasionally hang for PGO inconsistently
365 # They'll even hang here but be fine in src_test sometimes.
366 # bug #828535 (and related: bug #788022)
370 -x test_multiprocessing_fork
374 # Hangs (actually runs indefinitely executing itself w/ many cpython builds)
379 if has_version "app-arch/rpm" ; then
380 # Avoid sandbox failure (attempts to write to /var/lib/rpm)
381 profile_task_flags+=(
385 # PGO sometimes fails randomly
386 local -x PROFILE_TASK="${profile_task_flags[*]} || true"
390 # glibc-2.30 removes it; since we can't cleanly force-rebuild
391 # Python on glibc upgrade, remove it proactively to give
392 # a chance for users rebuilding python before glibc
393 ac_cv_header_stropts_h=no
396 --without-static-libpython
398 --infodir='${prefix}/share/info'
399 --mandir='${prefix}/share/man'
400 --with-computed-gotos
401 --with-dbmliborder="${dbmliborder}"
403 --enable-loadable-sqlite-extensions
407 --with-system-libmpdec
408 --with-platlibdir=lib
409 --with-pkg-config=yes
410 --with-wheel-pkg-dir="${EPREFIX}"/usr/lib/python/ensurepip
413 $(use_with debug assertions)
414 $(use_enable jit experimental-jit)
415 $(use_enable pgo optimizations)
416 $(use_with readline readline "$(usex libedit editline readline)")
420 # https://bugs.gentoo.org/700012
422 append-cflags $(test-flags-CC -ffat-lto-objects)
428 # Force-disable modules we don't want built.
429 # See Modules/Setup for docs on how this works. Setup.local contains our local deviations.
430 cat > Modules/Setup.local <<-EOF || die
433 $(usev !gdbm '_gdbm _dbm')
434 $(usev !sqlite '_sqlite3')
435 $(usev !ssl '_hashlib _ssl')
436 $(usev !ncurses '_curses _curses_panel')
437 $(usev !readline 'readline')
438 $(usev !tk '_tkinter')
441 # disable implicit optimization/debugging flags
444 if tc-is-cross-compiler ; then
447 # Point the imminent CHOST build to the Python we just
449 --with-build-python="${WORKDIR}"/${P}-${CBUILD}/python
453 # pass system CFLAGS & LDFLAGS as _NODIST, otherwise they'll get
454 # propagated to sysconfig for built extensions
455 local -x CFLAGS_NODIST=${CFLAGS}
456 local -x LDFLAGS_NODIST=${LDFLAGS}
457 local -x CFLAGS= LDFLAGS=
459 # Fix implicit declarations on cross and prefix builds. Bug #674070.
461 append-cppflags -I"${ESYSROOT}"/usr/include/ncursesw
464 econf "${myeconfargs[@]}"
466 if grep -q "#define POSIX_SEMAPHORES_NOT_ENABLED 1" pyconfig.h; then
467 eerror "configure has detected that the sem_open function is broken."
468 eerror "Please ensure that /dev/shm is mounted as a tmpfs with mode 1777."
469 die "Broken sem_open function (bug 496328)"
472 # install epython.py as part of stdlib
473 echo "EPYTHON='python${PYVER}'" > Lib/epython.py || die
477 # Ensure sed works as expected
478 # https://bugs.gentoo.org/594768
480 export PYTHONSTRICTEXTENSIONBUILD=1
482 # Save PYTHONDONTWRITEBYTECODE so that 'has_version' doesn't
483 # end up writing bytecode & violating sandbox.
485 local -x _PYTHONDONTWRITEBYTECODE=${PYTHONDONTWRITEBYTECODE}
487 # Gentoo hack to disable accessing system site-packages
488 export GENTOO_CPYTHON_BUILD=1
493 local -x PYTHONDONTWRITEBYTECODE=
494 local -x TMPDIR=/var/tmp
497 # also need to clear the flags explicitly here or they end up
499 emake CPPFLAGS= CFLAGS= LDFLAGS=
501 # Restore saved value from above.
502 local -x PYTHONDONTWRITEBYTECODE=${_PYTHONDONTWRITEBYTECODE}
504 # Work around bug 329499. See also bug 413751 and 457194.
505 if has_version dev-libs/libffi[pax-kernel]; then
513 # Tests will not work when cross compiling.
514 if tc-is-cross-compiler; then
515 elog "Disabling tests due to crosscompiling."
519 # this just happens to skip test_support.test_freeze that is broken
520 # without bundled expat
521 # TODO: get a proper skip for it upstream
522 local -x LOGNAME=buildbot
527 -j "$(makeopts_jobs)"
528 "${COMMON_TEST_SKIPS[@]}"
533 local -x PYTHONDONTWRITEBYTECODE=
534 local -x TMPDIR=/var/tmp
536 nonfatal emake -Onone test EXTRATESTOPTS="${test_opts[*]}" \
537 CPPFLAGS= CFLAGS= LDFLAGS= < /dev/tty
540 [[ ${ret} -eq 0 ]] || die "emake test failed"
544 local libdir=${ED}/usr/lib/python${PYVER}
546 # -j1 hack for now for bug #843458
547 emake -j1 DESTDIR="${D}" TEST_MODULES=no altinstall
549 # Fix collisions between different slots of Python.
550 rm "${ED}/usr/$(get_libdir)/libpython3.so" || die
551 # Fix collision with GIL-enabled build.
552 rm "${ED}/usr/bin/python${PYVER%t}" || die
553 mv "${ED}"/usr/bin/pydoc{${PYVER%t},${PYVER}} || die
554 mv "${ED}"/usr/share/man/man1/python{${PYVER%t},${PYVER}}.1 || die
556 # Cheap hack to get version with ABIFLAGS
557 local abiver=$(cd "${ED}/usr/include"; echo python*)
558 if [[ ${abiver} != python${PYVER} ]]; then
559 # Replace python3.X with a symlink to python3.Xm
560 rm "${ED}/usr/bin/python${PYVER}" || die
561 dosym "${abiver}" "/usr/bin/python${PYVER}"
562 # Create python3.X-config symlink
563 dosym "${abiver}-config" "/usr/bin/python${PYVER}-config"
564 # Create python-3.5m.pc symlink
565 dosym "python-${PYVER}.pc" "/usr/$(get_libdir)/pkgconfig/${abiver/${PYVER}/-${PYVER}}.pc"
568 # python seems to get rebuilt in src_install (bug 569908)
569 # Work around it for now.
570 if has_version dev-libs/libffi[pax-kernel]; then
571 pax-mark E "${ED}/usr/bin/${abiver}"
573 pax-mark m "${ED}/usr/bin/${abiver}"
576 rm -r "${libdir}"/ensurepip/_bundled || die
577 if ! use sqlite; then
578 rm -r "${libdir}/"sqlite3 || die
581 # rename to avoid collision with dev-lang/python
582 mv "${ED}"/usr/bin/idle{${PYVER%t},${PYVER}} || die
584 rm -r "${ED}/usr/bin/idle${PYVER%t}" || die
585 rm -r "${libdir}/"{idlelib,tkinter} || die
588 ln -s ../python/EXTERNALLY-MANAGED "${libdir}/EXTERNALLY-MANAGED" || die
590 dodoc Misc/{ACKS,HISTORY,NEWS}
592 if use examples; then
594 find Tools -name __pycache__ -exec rm -fr {} + || die
597 insinto /usr/share/gdb/auto-load/usr/$(get_libdir) #443510
599 printf 'e:\n\t@echo $(INSTSONAME)\ninclude Makefile\n' |
600 emake --no-print-directory -s -f - 2>/dev/null
602 newins Tools/gdb/libpython.py "${libname}"-gdb.py
604 newconfd "${FILESDIR}/pydoc.conf" pydoc-${PYVER}
605 newinitd "${FILESDIR}/pydoc.init" pydoc-${PYVER}
607 -e "s:@PYDOC_PORT_VARIABLE@:PYDOC${PYVER/./_}_PORT:" \
608 -e "s:@PYDOC@:pydoc${PYVER}:" \
609 -i "${ED}/etc/conf.d/pydoc-${PYVER}" \
610 "${ED}/etc/init.d/pydoc-${PYVER}" || die "sed failed"
612 # python-exec wrapping support
613 local pymajor=${PYVER%.*}
614 local EPYTHON=python${PYVER}
615 local scriptdir=${D}$(python_get_scriptdir)
616 mkdir -p "${scriptdir}" || die
618 ln -s "../../../bin/${abiver}" "${scriptdir}/python${pymajor}" || die
619 ln -s "python${pymajor}" "${scriptdir}/python" || die
620 # python-config and pythonX-config
621 # note: we need to create a wrapper rather than symlinking it due
622 # to some random dirname(argv[0]) magic performed by python-config
623 cat > "${scriptdir}/python${pymajor}-config" <<-EOF || die
625 exec "${abiver}-config" "\${@}"
627 chmod +x "${scriptdir}/python${pymajor}-config" || die
628 ln -s "python${pymajor}-config" "${scriptdir}/python-config" || die
630 ln -s "../../../bin/pydoc${PYVER}" "${scriptdir}/pydoc" || die
633 ln -s "../../../bin/idle${PYVER}" "${scriptdir}/idle" || die