diff --git a/.gitignore b/.gitignore index 1107137..67901af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /*.tar.* +/*-jit_stencils.h /*.src.rpm /results_python3* diff --git a/download-jit-stencils-from-koji.sh b/download-jit-stencils-from-koji.sh new file mode 100644 index 0000000..296af97 --- /dev/null +++ b/download-jit-stencils-from-koji.sh @@ -0,0 +1,23 @@ +set -eu +export LANG=C.utf-8 + +taskid=$(echo "$1" | sed -E 's/.*=|^([0-9]+)/\1/') +filter='.*-debugsource-.*\.(x86_64|aarch64)\.rpm' + +download_stdout=$(koji download-task $taskid --filter "$filter" | tee /dev/stderr) +files=$(echo "$download_stdout" | grep -E '^Downloading ' | sed -E 's/.*\s+(\S+)/\1/' | sort) + +for file in $files; do + nvra=${file/.rpm} + snvra=${nvra/-debugsource} + version=$(echo $nvra | sed -E -e 's|.*-([^-]+)-[^-]+|\1|' -e 's|~||') + arch=$(echo $nvra | sed -E 's|.*\.([^.]+)|\1|') + rpm2cpio $file | cpio -idmv ./usr/src/debug/${snvra}/build/{debug,optimized}/jit_stencils-${arch}-redhat-linux-gnu.h + for build in debug optimized; do + mv -v ./usr/src/debug/${snvra}/build/${build}/jit_stencils-${arch}-redhat-linux-gnu.h Python-${version}-${arch}-${build}-jit_stencils.h > /dev/stderr + echo Python-${version}-${arch}-${build}-jit_stencils.h + done + rmdir ./usr/src/debug/${snvra}{/build{/{debug,optimized},},} || : + rm -v $file > /dev/stderr +done +rmdir ./usr{/src{/debug,},} || : diff --git a/python3.14.spec b/python3.14.spec index 1649c29..11dc475 100644 --- a/python3.14.spec +++ b/python3.14.spec @@ -78,10 +78,13 @@ License: Python-2.0.1 # PEP 744: JIT Compilation # Whether to build with the experimental JIT compiler -# We can only have this on Fedora 41+, where clang 19+ is available -# And only on certain architectures: https://peps.python.org/pep-0744/#support +# Only possible on certain architectures: https://peps.python.org/pep-0744/#support # The freethreading build (when enabled) does not support JIT yet -%bcond jit %[(0%{?fedora} >= 41) && ("%{_arch}" == "x86_64" || "%{_arch}" == "aarch64")] +%bcond jit %["%{_arch}" == "x86_64" || "%{_arch}" == "aarch64"] +# Whether to build the JIT stencils (or else use the prebuilt ones) +# We can only do this on Fedora 41+, where clang 19 is available +# We don't do it in RHEL, see https://github.com/fedora-eln/eln/issues/207 +%bcond jit_build_stencils %[%{with jit} && 0%{?fedora} >= 41] %if %{with jit} # When built with JIT, it still needs to be enabled on runtime via PYTHON_JIT=1 %global jit_flag --enable-experimental-jit=yes-off @@ -293,7 +296,7 @@ BuildRequires: glibc-all-langpacks BuildRequires: tzdata %endif -%if %{with jit} +%if %{with jit_build_stencils} BuildRequires: clang(major) = 19 BuildRequires: llvm(major) = 19 %endif @@ -347,6 +350,24 @@ Source10: idle3.desktop # AppData file for idle3 Source11: idle3.appdata.xml +# Pre-generated JIT stencils (see PEP 774) +# As the PEP was deferred, we use stencils we built for ourselves. +# Only used on platforms without the required LLVM version. +# +# When updating Python: +# 1. touch the .h files (create them empty) +# 2. scratch build Python on platform with required LLVM version (usually rawhide) +# 3. download the files from Koji: +# $ bash download-jit-stencils-from-koji.sh KOJI_TASK_URL|KOJI_TASK_ID +# 4. add the files to lookaside cache with fedpkg new-sources +Source30: download-jit-stencils-from-koji.sh +Source31: Python-%{upstream_version}-aarch64-debug-jit_stencils.h +Source32: Python-%{upstream_version}-aarch64-optimized-jit_stencils.h +Source33: Python-%{upstream_version}-x86_64-debug-jit_stencils.h +Source34: Python-%{upstream_version}-x86_64-optimized-jit_stencils.h +%global jit_stencils_source %{_sourcedir}/Python-%{upstream_version}-%{_arch}-${ConfName}-jit_stencils.h +%global jit_stencils_filename jit_stencils-%{_arch}-redhat-linux-gnu.h + # (Patches taken from github.com/fedora-python/cpython) # 00251 # 5ac6e7781923cbb3e4606e3bca381a1167d322e5 @@ -1045,6 +1066,16 @@ BuildPython() { $ExtraConfigArgs \ %{nil} +%if %{with jit} && %{without jit_build_stencils} + if [[ ! "$ConfName" =~ ^freethreading ]]; then + cp -a %{jit_stencils_source} %{jit_stencils_filename} + # Hackish way of preventing PGO task to delete the stencils. + # Upstream issue: https://github.com/python/cpython/issues/141808 + # Upstream PR: https://github.com/python/cpython/pull/141809 + sed -i '/rm -f jit_stencils.h/d' Makefile + fi +%endif + %global flags_override EXTRA_CFLAGS="$MoreCFlags" CFLAGS_NODIST="$CFLAGS_NODIST $MoreCFlags" %if %{without bootstrap} @@ -1397,6 +1428,16 @@ for Module in %{buildroot}/%{dynload_dir}/*.so ; do esac done +# Assert the pre-generated JIT stencils are up to date +%if %{with jit_build_stencils} +for ConfName in %{?with_debug_build:debug} optimized; do + if [ -s %{jit_stencils_source} ]; then + diff -u %{jit_stencils_source} build/${ConfName}/%{jit_stencils_filename} + else + echo "%{jit_stencils_source} is empty, not checking if it is up to date" + fi +done +%endif # ====================================================== # Running the upstream test suite diff --git a/rpmlint.toml b/rpmlint.toml index 0864a1c..9ddef32 100644 --- a/rpmlint.toml +++ b/rpmlint.toml @@ -37,6 +37,9 @@ Filters = [ # if this regex needs to be relaxed in the future, make sure it **does not** match pyc files in __pycache__ 'python-bytecode-without-source /usr/lib(64)?/python3\.\d+t?/(encodings|pydoc_data)/[^/]+.pyc', + # https://docs.fedoraproject.org/en-US/packaging-guidelines/RPM_Source_Dir/#_exceptions + 'use-of-RPM_SOURCE_DIR', + # DUPLICATE FILES # test data are often duplicated '(E|W): files-duplicate /usr/lib(64)?/python3\.\d+t?/(test|__phello__)/', diff --git a/sources b/sources index 3a6d2f0..8aaba44 100644 --- a/sources +++ b/sources @@ -1 +1,5 @@ SHA512 (Python-3.14.0.tar.xz) = 46e9e205c3a084cba68bf7f267ab2fd0862a05430165e0eb713f2d6b3a1a4452f72f563de5de55caea824be9df56f66dd568f4814941667a9bb0954229772c53 +SHA512 (Python-3.14.0-aarch64-debug-jit_stencils.h) = 850952abc9ee83be51a67d64d013e31abd6a9e4331045ae169f684107d98fba9c91ef28fd1bf60e75c8975b600665afc9aec258b7e5b61abafa834996b16fb18 +SHA512 (Python-3.14.0-aarch64-optimized-jit_stencils.h) = d7b50e8bb2341f0404781f3f17dca9ac489efd8e25b832eb34346e4b88f3084e9c4482f981e51db4a9596df05c4138642252f52d0712dac9dda15cee21db196c +SHA512 (Python-3.14.0-x86_64-debug-jit_stencils.h) = 51484d6b19a2483f67589c4d57f2df25f28d089a591f19c5eef6564006db5f7d5afa52181df2cd925a550e358ee5562c8f02ef0f8de7628f5f1fa242fd89a56a +SHA512 (Python-3.14.0-x86_64-optimized-jit_stencils.h) = c84dda9956690faf372a09d9a532311d975ae69c4bf2a91102c30086dca16bef9a2c0ebb2f372437cfad64585e7a872db74476f5c502dc9635a25dd9e0b710d4