917 lines
31 KiB
RPMSpec
917 lines
31 KiB
RPMSpec
# Note: When this is updated to 7.4,
|
|
# the installation layout will change in a backwards-incompatible way.
|
|
# That'll be a good time to rename this to pypy2.7 and adapt %%pypyprefix to be
|
|
# %%{_libdir}/pypy%%{pyversion} (see e.g. pypy3.7 or pypy3.8 for inspiration).
|
|
%global basever 7.3
|
|
Name: pypy
|
|
Version: %{basever}.16
|
|
%global pyversion 2.7
|
|
Release: %autorelease -e 0.riscv64
|
|
Summary: Python implementation with a Just-In-Time compiler
|
|
|
|
# PyPy is MIT
|
|
# Python standard library is Python
|
|
# pypy/module/unicodedata is UCD
|
|
# Bundled pycparser is is BSD
|
|
# Bundled pycparser.ply is BSD
|
|
# Bundled bits from cryptography are ASL 2.0 or BSD
|
|
# LGPL and another free license we'd need to ask spot about are present in some
|
|
# java jars that we're not building with atm (in fact, we're deleting them
|
|
# before building). If we restore those we'll have to work out the new
|
|
# licensing terms
|
|
License: MIT and Python and UCD and BSD and (ASL 2.0 or BSD)
|
|
URL: https://www.pypy.org/
|
|
|
|
# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
|
|
ExcludeArch: %{ix86}
|
|
|
|
# High-level configuration of the build:
|
|
|
|
# Whether to use RPM build wheels from the python-{pip,setuptools}-wheel package
|
|
# Uses upstream bundled prebuilt wheels otherwise
|
|
# setuptools >= 45.0 no longer support Python 2.7, hence disabled
|
|
%bcond_with rpmwheels
|
|
|
|
# PyPy consists of an implementation of an interpreter (with JIT compilation)
|
|
# for the full Python language written in a high-level language, leaving many
|
|
# of the implementation details as "pluggable" policies.
|
|
#
|
|
# The implementation language is then compiled down to .c code, from which we
|
|
# obtain a binary.
|
|
#
|
|
# This allows us to build a near-arbitrary collection of different
|
|
# implementations of Python with differing tradeoffs
|
|
#
|
|
# (As it happens, the implementation language is itself Python, albeit a
|
|
# restricted subset "RPython", chosen to making it amenable to being compiled.
|
|
# The result implements the full Python language though)
|
|
|
|
# We could build many different implementations of Python.
|
|
# For now, let's focus on the implementation that appears to be receiving the
|
|
# most attention upstream: the JIT-enabled build, with all standard
|
|
# optimizations
|
|
|
|
# Building a configuration can take significant time:
|
|
|
|
# A build of pypy (with jit) on i686 took 77 mins:
|
|
# [Timer] Timings:
|
|
# [Timer] annotate --- 583.3 s
|
|
# [Timer] rtype_lltype --- 760.9 s
|
|
# [Timer] pyjitpl_lltype --- 567.3 s
|
|
# [Timer] backendopt_lltype --- 375.6 s
|
|
# [Timer] stackcheckinsertion_lltype --- 54.1 s
|
|
# [Timer] database_c --- 852.2 s
|
|
# [Timer] source_c --- 1007.3 s
|
|
# [Timer] compile_c --- 419.9 s
|
|
# [Timer] ===========================================
|
|
# [Timer] Total: --- 4620.5 s
|
|
#
|
|
# A build of pypy (nojit) on x86_64 took about an hour:
|
|
# [Timer] Timings:
|
|
# [Timer] annotate --- 537.5 s
|
|
# [Timer] rtype_lltype --- 667.3 s
|
|
# [Timer] backendopt_lltype --- 385.4 s
|
|
# [Timer] stackcheckinsertion_lltype --- 42.5 s
|
|
# [Timer] database_c --- 625.3 s
|
|
# [Timer] source_c --- 1040.2 s
|
|
# [Timer] compile_c --- 273.9 s
|
|
# [Timer] ===========================================
|
|
# [Timer] Total: --- 3572.0 s
|
|
#
|
|
#
|
|
# A build of pypy-stackless on i686 took about 87 mins:
|
|
# [Timer] Timings:
|
|
# [Timer] annotate --- 584.2 s
|
|
# [Timer] rtype_lltype --- 777.3 s
|
|
# [Timer] backendopt_lltype --- 365.9 s
|
|
# [Timer] stackcheckinsertion_lltype --- 39.3 s
|
|
# [Timer] database_c --- 1089.6 s
|
|
# [Timer] source_c --- 1868.6 s
|
|
# [Timer] compile_c --- 490.4 s
|
|
# [Timer] ===========================================
|
|
# [Timer] Total: --- 5215.3 s
|
|
|
|
|
|
# We will build a "pypy" binary.
|
|
#
|
|
# Unfortunately, the JIT support is only available on some architectures.
|
|
#
|
|
# rpython/jit/backend/detect_cpu.py:getcpuclassname currently supports the
|
|
# following options:
|
|
# 'i386', 'x86'
|
|
# 'x86-without-sse2':
|
|
# 'x86_64'
|
|
# 'armv6', 'armv7' (versions 6 and 7, hard- and soft-float ABI)
|
|
# 'cli'
|
|
# 'llvm'
|
|
#
|
|
# We will only build with JIT support on those architectures, and build without
|
|
# it on the other archs. The resulting binary will typically be slower than
|
|
# CPython for the latter case.
|
|
|
|
%global src_name %{ver_name}-v%{version}-src
|
|
|
|
%ifarch %{ix86} x86_64 %{arm} s390x %{power64} aarch64
|
|
%global with_jit 1
|
|
%else
|
|
%global with_jit 0
|
|
%endif
|
|
|
|
# Should we build a "pypy-stackless" binary?
|
|
%global with_stackless 0
|
|
|
|
# Should we build the emacs JIT-viewing mode?
|
|
%if 0%{?rhel} == 6
|
|
%global with_emacs 0
|
|
%else
|
|
%global with_emacs 1
|
|
%endif
|
|
|
|
# Easy way to enable/disable verbose logging:
|
|
%global verbose_logs 0
|
|
|
|
# Easy way to turn off the selftests:
|
|
%global run_selftests 1
|
|
|
|
%global pypy_include_dir %{pypyprefix}/include
|
|
%global pypyprefix %{_libdir}/%{name}-%{basever}
|
|
%global pylibver 2.7
|
|
%global pymajorlibver 2
|
|
%global ver_name %{name}%{pymajorlibver}
|
|
|
|
# We refer to this subdir of the source tree in a few places during the build:
|
|
%global goal_dir pypy/goal
|
|
|
|
%ifarch %{ix86} x86_64 %{arm}
|
|
%global _package_note_linker gold
|
|
%endif
|
|
|
|
# Source and patches:
|
|
Source0: https://downloads.python.org/pypy/pypy%{pyversion}-v%{version}-src.tar.bz2
|
|
|
|
# Supply various useful RPM macros for building python modules against pypy:
|
|
# __pypy, pypy_sitelib, pypy_sitearch
|
|
Source1: macros.%{name}
|
|
# __pypy2, pypy2_sitelib, pypy2_sitearch
|
|
Source2: macros.%{name}%{pymajorlibver}
|
|
|
|
# Patch for the bundled pip wheel for CVE-2023-5752
|
|
# https://github.com/pypa/pip/pull/12119
|
|
# https://github.com/pypa/pip/pull/12306
|
|
# https://github.com/pypa/pip/pull/12373
|
|
Source3: pip-CVE-2023-5752.patch
|
|
|
|
# Patch pypy.translator.platform so that stdout from "make" etc gets logged,
|
|
# rather than just stderr, so that the command-line invocations of the compiler
|
|
# and linker are captured:
|
|
Patch0: 006-always-log-stdout.patch
|
|
|
|
# Disable the printing of a quote from IRC on startup (these are stored in
|
|
# ROT13 form in lib_pypy/_pypy_irc_topic.py). Some are cute, but some could
|
|
# cause confusion for end-users (and many are in-jokes within the PyPy
|
|
# community that won't make sense outside of it). [Sorry to be a killjoy]
|
|
Patch1: 007-remove-startup-message.patch
|
|
|
|
# Glibc's libcrypt was replaced with libxcrypt in f28, crypt.h header has
|
|
# to be added to privent compilation error.
|
|
# https://fedoraproject.org/wiki/Changes/Replace_glibc_libcrypt_with_libxcrypt
|
|
Patch2: 009-add-libxcrypt-support.patch
|
|
|
|
# Instead of bundled wheels, use our RPM packaged wheels from
|
|
# /usr/share/python-wheels
|
|
# We conditionally apply this, but we use autosetup, so we use Source here
|
|
Source189: 189-use-rpm-wheels.patch
|
|
|
|
# 00382 #
|
|
# Make mailcap refuse to match unsafe filenames/types/params (GH-91993)
|
|
#
|
|
# Upstream: https://github.com/python/cpython/issues/68966
|
|
#
|
|
# Tracker bug: https://bugzilla.redhat.com/show_bug.cgi?id=2075390
|
|
#
|
|
# Backported from python3.
|
|
Patch382: 382-cve-2015-20107.patch
|
|
|
|
# 00394 #
|
|
# gh-98433: Fix quadratic time idna decoding.
|
|
#
|
|
# There was an unnecessary quadratic loop in idna decoding. This restores
|
|
# the behavior to linear.
|
|
#
|
|
# Backported from python3.
|
|
Patch394: 394-cve-2022-45061-cpu-denial-of-service-via-inefficient-idna-decoder.patch
|
|
|
|
# 00399 #
|
|
# CVE-2023-24329
|
|
#
|
|
# gh-102153: Start stripping C0 control and space chars in `urlsplit` (GH-102508)
|
|
#
|
|
# `urllib.parse.urlsplit` has already been respecting the WHATWG spec a bit GH-25595.
|
|
#
|
|
# This adds more sanitizing to respect the "Remove any leading C0 control or space from input" [rule](https://url.spec.whatwg.org/GH-url-parsing:~:text=Remove%%20any%%20leading%%20and%%20trailing%%20C0%%20control%%20or%%20space%%20from%%20input.) in response to [CVE-2023-24329](https://nvd.nist.gov/vuln/detail/CVE-2023-24329).
|
|
#
|
|
# Backported from Python 3.12
|
|
Patch399: 399-cve-2023-24329.patch
|
|
|
|
# Build-time requirements:
|
|
|
|
# pypy's can be rebuilt using itself, rather than with CPython; doing so
|
|
# halves the build time.
|
|
#
|
|
# Turn it off with this boolean, to revert back to rebuilding using CPython
|
|
# and avoid a cycle in the build-time dependency graph:
|
|
|
|
%global use_self_when_building 1
|
|
%if 0%{use_self_when_building}
|
|
BuildRequires: pypy2
|
|
%global bootstrap_python_interp pypy2
|
|
%else
|
|
# exception to use Python 2: https://pagure.io/fesco/issue/2130
|
|
BuildRequires: python27
|
|
%global bootstrap_python_interp python2
|
|
%endif
|
|
|
|
BuildRequires: gcc
|
|
|
|
BuildRequires: libffi-devel
|
|
BuildRequires: tcl-devel
|
|
BuildRequires: tk-devel
|
|
|
|
BuildRequires: sqlite-devel
|
|
|
|
BuildRequires: zlib-devel
|
|
BuildRequires: bzip2-devel
|
|
BuildRequires: ncurses-devel
|
|
BuildRequires: expat-devel
|
|
BuildRequires: openssl-devel
|
|
%if 0%{?fedora} >= 41
|
|
BuildRequires: openssl-devel-engine
|
|
%endif
|
|
BuildRequires: gdbm-devel
|
|
BuildRequires: chrpath
|
|
|
|
BuildRequires: python-rpm-macros
|
|
|
|
%ifarch %{valgrind_arches}
|
|
BuildRequires: valgrind-devel
|
|
%endif
|
|
|
|
%if %{run_selftests}
|
|
# Used by the selftests, though not by the build:
|
|
BuildRequires: gc-devel
|
|
|
|
# For use in the selftests, for recording stats:
|
|
BuildRequires: time
|
|
|
|
# For use in the selftests, for imposing a per-test timeout:
|
|
BuildRequires: perl-interpreter
|
|
%endif
|
|
|
|
# All arches have execstack
|
|
BuildRequires: execstack
|
|
|
|
# For byte-compiling the JIT-viewing mode:
|
|
%if %{with_emacs}
|
|
BuildRequires: emacs
|
|
%endif
|
|
|
|
# For %%autosetup -S git
|
|
BuildRequires: %{_bindir}/git
|
|
|
|
%if %{with rpmwheels}
|
|
BuildRequires: python-setuptools-wheel < 45
|
|
BuildRequires: python-pip-wheel
|
|
%endif
|
|
|
|
# Metadata for the core package (the JIT build):
|
|
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
|
Provides: %{ver_name} = %{version}-%{release}
|
|
Provides: %{ver_name}%{_isa} = %{version}-%{release}
|
|
Provides: pypy%{pyversion} = %{version}-%{release}
|
|
Provides: pypy%{pyversion}%{_isa} = %{version}-%{release}
|
|
Provides: %{ver_name}(abi) = %{basever}
|
|
|
|
%description
|
|
PyPy's implementation of Python, featuring a Just-In-Time compiler on some CPU
|
|
architectures, and various optimized implementations of the standard types
|
|
(strings, dictionaries, etc)
|
|
|
|
%if 0%{with_jit}
|
|
This build of PyPy has JIT-compilation enabled.
|
|
%else
|
|
This build of PyPy has JIT-compilation disabled, as it is not supported on this
|
|
CPU architecture.
|
|
%endif
|
|
|
|
|
|
%package libs
|
|
Summary: Run-time libraries used by PyPy implementations of Python
|
|
|
|
%if %{without rpmwheels}
|
|
# PyPy is MIT and Python and UCD and BSD and (ASL 2.0 or BSD) (see the main package license)
|
|
# setuptools is MIT and bundles:
|
|
# packaging: BSD or ASL 2.0
|
|
# pyparsing: MIT
|
|
# six: MIT
|
|
# pip is MIT and bundles:
|
|
# appdirs: MIT
|
|
# distlib: Python
|
|
# distro: ASL 2.0
|
|
# html5lib: MIT
|
|
# six: MIT
|
|
# colorama: BSD
|
|
# CacheControl: ASL 2.0
|
|
# msgpack-python: ASL 2.0
|
|
# lockfile: MIT
|
|
# progress: ISC
|
|
# ipaddress: Python
|
|
# packaging: ASL 2.0 or BSD
|
|
# pep517: MIT
|
|
# pyparsing: MIT
|
|
# pytoml: MIT
|
|
# retrying: ASL 2.0
|
|
# requests: ASL 2.0
|
|
# chardet: LGPLv2
|
|
# idna: BSD
|
|
# urllib3: MIT
|
|
# certifi: MPLv2.0
|
|
# setuptools: MIT
|
|
# webencodings: BSD
|
|
License: MIT and Python and UCD and BSD and (ASL 2.0 or BSD) and BSD and ASL 2.0 and ISC and LGPLv2 and MPLv2.0 and (ASL 2.0 or BSD)
|
|
%endif
|
|
|
|
# We supply an emacs mode for the JIT viewer.
|
|
# (This doesn't bring in all of emacs, just the directory structure)
|
|
%if %{with_emacs}
|
|
Requires: emacs-filesystem >= %{_emacs_version}
|
|
%endif
|
|
|
|
%if %{with rpmwheels}
|
|
Requires: python-setuptools-wheel < 45
|
|
Requires: python-pip-wheel
|
|
%else
|
|
Provides: bundled(python2dist(setuptools)) = 44.0.0
|
|
Provides: bundled(python2dist(packaging)) = 16.8
|
|
Provides: bundled(python2dist(pyparsing)) = 2.2.1
|
|
Provides: bundled(python2dist(six)) = 1.10.0
|
|
|
|
Provides: bundled(python2dist(pip)) = 20.0.2
|
|
Provides: bundled(python2dist(appdirs)) = 1.4.3
|
|
Provides: bundled(python2dist(CacheControl)) = 0.12.6
|
|
Provides: bundled(python2dist(contextlib2)) = 0.6.0
|
|
Provides: bundled(python2dist(certifi)) = 2019.11.28
|
|
Provides: bundled(python2dist(chardet)) = 3.0.4
|
|
Provides: bundled(python2dist(colorama)) = 0.4.3
|
|
Provides: bundled(python2dist(distlib)) = 0.3.0
|
|
Provides: bundled(python2dist(distro)) = 1.4.0
|
|
Provides: bundled(python2dist(html5lib)) = 1.0.1
|
|
Provides: bundled(python2dist(idna)) = 2.8
|
|
Provides: bundled(python2dist(ipaddress)) = 1.0.23
|
|
Provides: bundled(python2dist(lockfile)) = 0.12.2
|
|
Provides: bundled(python2dist(msgpack)) = 0.6.2
|
|
Provides: bundled(python2dist(packaging)) = 20.1
|
|
Provides: bundled(python2dist(pep517)) = 0.7.0
|
|
Provides: bundled(python2dist(progress)) = 1.5
|
|
Provides: bundled(python2dist(pyparsing)) = 2.4.6
|
|
Provides: bundled(python2dist(pytoml)) = 0.1.21
|
|
Provides: bundled(python2dist(requests)) = 2.22.0
|
|
Provides: bundled(python2dist(retrying)) = 1.3.3
|
|
Provides: bundled(python2dist(setuptools)) = 44.0.0
|
|
Provides: bundled(python2dist(six)) = 1.14.0
|
|
Provides: bundled(python2dist(urllib3)) = 1.25.7
|
|
Provides: bundled(python2dist(webencodings)) = 0.5.1
|
|
%endif
|
|
|
|
# Find the version in lib_pypy/cffi/_pycparser/__init__.py
|
|
Provides: bundled(python2dist(pycparser)) = 2.22
|
|
|
|
# Find the version in lib_pypy/cffi/_pycparser/ply/__init__.py
|
|
Provides: bundled(python2dist(ply)) = 3.9
|
|
|
|
# Find the version in lib_pypy/_cffi_ssl/cryptography/__about__.py
|
|
Provides: bundled(python2dist(cryptography)) = 2.7
|
|
|
|
Provides: %{ver_name}-libs = %{version}-%{release}
|
|
Provides: %{ver_name}-libs%{_isa} = %{version}-%{release}
|
|
Provides: pypy%{pyversion}-libs = %{version}-%{release}
|
|
Provides: pypy%{pyversion}-libs%{_isa} = %{version}-%{release}
|
|
|
|
%description libs
|
|
Libraries required by the various PyPy implementations of Python.
|
|
|
|
|
|
%package devel
|
|
Summary: Development tools for working with PyPy
|
|
Requires: %{name}%{?_isa} = %{version}-%{release}
|
|
Provides: %{ver_name}-devel = %{version}-%{release}
|
|
Provides: %{ver_name}-devel%{_isa} = %{version}-%{release}
|
|
Provides: pypy%{pyversion}-devel = %{version}-%{release}
|
|
Provides: pypy%{pyversion}-devel%{_isa} = %{version}-%{release}
|
|
|
|
%description devel
|
|
Header files for building C extension modules against PyPy
|
|
|
|
|
|
%if 0%{with_stackless}
|
|
%package stackless
|
|
Summary: Stackless Python interpreter built using PyPy
|
|
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
|
Provides: %{ver_name}-stackless = %{version}-%{release}
|
|
Provides: %{ver_name}-stackless%{_isa} = %{version}-%{release}
|
|
Provides: pypy%{pyversion}-stackless = %{version}-%{release}
|
|
Provides: pypy%{pyversion}-stackless%{_isa} = %{version}-%{release}
|
|
%description stackless
|
|
Build of PyPy with support for micro-threads for massive concurrency
|
|
%endif
|
|
|
|
|
|
%prep
|
|
%autosetup -n pypy%{pyversion}-v%{version}-src -p1 -S git
|
|
|
|
# Temporary workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1954999
|
|
%{?!apply_patch:%define apply_patch(qp:m:) {%__apply_patch %**}}
|
|
|
|
%if %{with rpmwheels}
|
|
%apply_patch -m %(basename %{SOURCE189}) %{SOURCE189}
|
|
rm lib-python/2.7/ensurepip/_bundled/*.whl
|
|
rmdir lib-python/2.7/ensurepip/_bundled
|
|
%endif
|
|
|
|
# Patch the bundled pip wheel for CVE-2023-5752
|
|
%if %{without rpmwheels}
|
|
unzip -qq lib-python/2.7/ensurepip/_bundled/pip-20.0.2-py2.py3-none-any.whl
|
|
patch -p1 < %{SOURCE3}
|
|
zip -rq lib-python/2.7/ensurepip/_bundled/pip-20.0.2-py2.py3-none-any.whl pip pip-20.0.2.dist-info
|
|
rm -rf pip/ pip-20.0.2.dist-info/
|
|
%endif
|
|
|
|
|
|
# Replace /usr/local/bin/python or /usr/bin/env python shebangs with /usr/bin/python2 or pypy2:
|
|
find \( -name "*.py" -o -name "py.cleanup" \) -exec \
|
|
sed \
|
|
-i -r -e "s@/usr/(local/)?bin/(env )?python(2|3)?@/usr/bin/%{bootstrap_python_interp}@" \
|
|
"{}" \
|
|
\;
|
|
|
|
for f in rpython/translator/goal/bpnn.py ; do
|
|
# Detect shebang lines && remove them:
|
|
sed -e '/^#!/Q 0' -e 'Q 1' $f \
|
|
&& sed -i '1d' $f
|
|
chmod a-x $f
|
|
done
|
|
|
|
rm -rf lib-python/3
|
|
|
|
# Replace all lib-python python shebangs with pypy
|
|
find lib-python/%{pylibver} -name "*.py" -exec \
|
|
sed -r -i '1s|^#!\s*/usr/bin.*python.*|#!/usr/bin/%{name}|' \
|
|
"{}" \
|
|
\;
|
|
|
|
%if ! 0%{use_self_when_building}
|
|
# use the pycparser from PyPy even on CPython
|
|
ln -s lib_pypy/cffi/_pycparser pycparser
|
|
%endif
|
|
|
|
# Remove windows executable binaries
|
|
rm lib-python/2.7/distutils/command/*.exe
|
|
|
|
%build
|
|
%ifarch s390x
|
|
# pypy3 requires z10 at least
|
|
%global optflags %(echo %{optflags} | sed 's/-march=z9-109 /-march=z10 /')
|
|
%endif
|
|
|
|
%ifarch riscv64
|
|
export PYPY_MULTIARCH=riscv64-linux-gnu
|
|
%endif
|
|
|
|
BuildPyPy() {
|
|
ExeName=$1
|
|
Options=$2
|
|
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "STARTING BUILD OF: $ExeName"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
|
|
pushd %{goal_dir}
|
|
|
|
# The build involves invoking a python script, passing in particular
|
|
# arguments, environment variables, etc.
|
|
# Some notes on those follow:
|
|
|
|
# The generated binary embeds copies of the values of all environment
|
|
# variables. We need to unset "RPM_BUILD_ROOT" to avoid a fatal error from
|
|
# /usr/lib/rpm/check-buildroot
|
|
# during the postprocessing of the rpmbuild, complaining about this
|
|
# reference to the buildroot
|
|
|
|
|
|
# By default, pypy's autogenerated C code is placed in
|
|
# /tmp/usession-N
|
|
#
|
|
# and it appears that this stops rpm from extracting the source code to the
|
|
# debuginfo package
|
|
#
|
|
# The logic in pypy-1.4/pypy/tool/udir.py indicates that it is generated in:
|
|
# $PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-N
|
|
# and so we set PYPY_USESSION_DIR so that this tempdir is within the build
|
|
# location, and set $PYPY_USESSION_BASENAME so that the tempdir is unique
|
|
# for each invocation of BuildPyPy
|
|
|
|
# Compilation flags for C code:
|
|
# pypy-1.4/pypy/translator/c/genc.py:gen_makefile
|
|
# assembles a Makefile within
|
|
# THE_UDIR/testing_1/Makefile
|
|
# calling out to platform.gen_makefile
|
|
# For us, that's
|
|
# pypy-1.4/pypy/translator/platform/linux.py: class BaseLinux(BasePosix):
|
|
# which by default has:
|
|
# CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer',
|
|
# '-Wall', '-Wno-unused']
|
|
# plus all substrings from CFLAGS in the environment.
|
|
# This is used to generate a value for CFLAGS that's written into the Makefile
|
|
|
|
# How will we track garbage-collection roots in the generated code?
|
|
# http://pypy.readthedocs.org/en/latest/config/translation.gcrootfinder.html
|
|
|
|
# This is the most portable option, and avoids a reliance on non-guaranteed
|
|
# behaviors within GCC's code generator: use an explicitly-maintained stack
|
|
# of root pointers:
|
|
%global gcrootfinder_options --gcrootfinder=shadowstack
|
|
|
|
export CFLAGS=$(echo "$RPM_OPT_FLAGS" | sed -e 's/-g//')
|
|
|
|
# The generated C code leads to many thousands of warnings of the form:
|
|
# warning: variable 'l_v26003' set but not used [-Wunused-but-set-variable]
|
|
# Suppress them:
|
|
export CFLAGS=$(echo "$CFLAGS" -Wno-unused -fPIC)
|
|
|
|
# If we're already built the JIT-enabled "pypy", then use it for subsequent
|
|
# builds (of other configurations):
|
|
if test -x './pypy' ; then
|
|
INTERP='./pypy'
|
|
%ifarch %{arm}
|
|
# Reduce memory usage on arm during installation
|
|
PYPY_GC_MAX_DELTA=200MB $INTERP --jit loop_longevity=300 ../../rpython/bin/rpython -Ojit targetpypystandalone
|
|
%endif
|
|
else
|
|
# First pypy build within this rpm build?
|
|
# Fall back to using the bootstrap python interpreter, which might be a
|
|
# system copy of pypy from an earlier rpm, or be cpython's /usr/bin/python:
|
|
INTERP='%{bootstrap_python_interp}'
|
|
fi
|
|
|
|
# Here's where we actually invoke the build:
|
|
RPM_BUILD_ROOT= \
|
|
PYPY_USESSION_DIR=$(pwd) \
|
|
PYPY_USESSION_BASENAME=$ExeName \
|
|
$INTERP ../../rpython/bin/rpython \
|
|
%{gcrootfinder_options} \
|
|
$Options \
|
|
%ifarch riscv64
|
|
targetpypystandalone \
|
|
--withoutmod-_continuation
|
|
%else
|
|
targetpypystandalone
|
|
%endif
|
|
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "FINISHED BUILDING: $ExeName"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
|
|
popd
|
|
}
|
|
|
|
BuildPyPy \
|
|
%{name} \
|
|
%if 0%{with_jit}
|
|
"-Ojit" \
|
|
%else
|
|
"-O2" \
|
|
%endif
|
|
%{nil}
|
|
|
|
%if 0%{with_stackless}
|
|
BuildPyPy \
|
|
%{name}-stackless \
|
|
"--stackless"
|
|
%endif
|
|
|
|
%if %{with_emacs}
|
|
%{_emacs_bytecompile} rpython/jit/tool/pypytrace-mode.el
|
|
%endif
|
|
|
|
|
|
%install
|
|
|
|
mkdir -p %{buildroot}/%{_bindir}
|
|
mkdir -p %{buildroot}/%{pypyprefix}
|
|
|
|
#%if 0%{with_stackless}
|
|
#InstallPyPy %{name}-stackless
|
|
#%endif
|
|
|
|
|
|
# Run installing script, archive-name %{name}-%{basever} in %{buildroot}/%{_libdir} == %{pypyprefix}
|
|
%{bootstrap_python_interp} pypy/tool/release/package.py --archive-name %{name}-%{basever} --builddir %{buildroot}/%{_libdir} --no-embedded-dependencies
|
|
|
|
# Remove shebang lines from .py files that aren't executable, and
|
|
# remove executability from .py files that don't have a shebang line:
|
|
find \
|
|
%{buildroot} \
|
|
-name "*.py" \
|
|
\( \
|
|
\( \! -perm /u+x,g+x,o+x -exec sed -e '/^#!/Q 0' -e 'Q 1' {} \; \
|
|
-print -exec sed -i '1d' {} \; \
|
|
\) \
|
|
-o \
|
|
\( \
|
|
-perm /u+x,g+x,o+x ! -exec grep -m 1 -q '^#!' {} \; \
|
|
-exec chmod a-x {} \; \
|
|
\) \
|
|
\)
|
|
|
|
|
|
execstack --clear-execstack %{buildroot}/%{pypyprefix}/bin/pypy
|
|
|
|
# Bytecompile all of the .py files we ship, using our pypy binary, giving us
|
|
# .pyc files for pypy.
|
|
#
|
|
# Note that some of the test files deliberately contain syntax errors, so
|
|
# we are running it in subshell, to be able to ignore the failures and not to terminate the build.
|
|
(%{py_byte_compile %{buildroot}%{pypyprefix}/bin/pypy %{buildroot}%{pypyprefix}}) || :
|
|
|
|
|
|
%{buildroot}%{pypyprefix}/bin/%{name} -c 'import _tkinter'
|
|
%{buildroot}%{pypyprefix}/bin/%{name} -c 'import Tkinter'
|
|
%{buildroot}%{pypyprefix}/bin/%{name} -c 'import _sqlite3'
|
|
%{buildroot}%{pypyprefix}/bin/%{name} -c 'import _curses'
|
|
%{buildroot}%{pypyprefix}/bin/%{name} -c 'import curses'
|
|
%{buildroot}%{pypyprefix}/bin/%{name} -c 'import syslog'
|
|
%{buildroot}%{pypyprefix}/bin/%{name} -c 'from _sqlite3 import *'
|
|
|
|
|
|
# Header files for C extension modules.
|
|
# Upstream's packaging process (pypy/tool/release/package.py)
|
|
# creates an "include" subdir and copies all *.h/*.inl from "include" there
|
|
# (it also has an apparently out-of-date comment about copying them from
|
|
# pypy/_interfaces, but this directory doesn't seem to exist, and it doesn't
|
|
# seem to do this as of 2011-01-13)
|
|
|
|
# Capture the RPython source code files from the build within the debuginfo
|
|
# package (rhbz#666975)
|
|
%global pypy_debuginfo_dir /usr/src/debug/pypy-%{version}-src
|
|
mkdir -p %{buildroot}%{pypy_debuginfo_dir}
|
|
|
|
# copy over everything:
|
|
cp -a pypy %{buildroot}%{pypy_debuginfo_dir}
|
|
|
|
# ...then delete files that aren't:
|
|
# - *.py files
|
|
# - the Makefile
|
|
# - typeids.txt
|
|
# - dynamic-symbols-*
|
|
#find \
|
|
# %{buildroot}%{pypy_debuginfo_dir} \
|
|
# \( -type f \
|
|
# -a \
|
|
# \! \( -name "*.py" \
|
|
# -o \
|
|
# -name "Makefile" \
|
|
# -o \
|
|
# -name "typeids.txt" \
|
|
# -o \
|
|
# -name "dynamic-symbols-*" \
|
|
# \) \
|
|
# \) \
|
|
# -delete
|
|
|
|
# Alternatively, we could simply keep everything. This leads to a ~350MB
|
|
# debuginfo package, but it makes it easy to hack on the Makefile and C build
|
|
# flags by rebuilding/linking the sources.
|
|
# To do so, remove the above "find" command.
|
|
|
|
# We don't need bytecode for these files; they are being included for reference
|
|
# purposes.
|
|
# There are some rpmlint warnings from these files:
|
|
# non-executable-script
|
|
# wrong-script-interpreter
|
|
# zero-length
|
|
# script-without-shebang
|
|
# dangling-symlink
|
|
# but given that the objective is to preserve a copy of the source code, those
|
|
# are acceptable.
|
|
|
|
# Install the JIT trace mode for Emacs:
|
|
%if %{with_emacs}
|
|
mkdir -p %{buildroot}/%{_emacs_sitelispdir}
|
|
cp -a rpython/jit/tool/pypytrace-mode.el %{buildroot}/%{_emacs_sitelispdir}/%{name}trace-mode.el
|
|
cp -a rpython/jit/tool/pypytrace-mode.elc %{buildroot}/%{_emacs_sitelispdir}/%{name}trace-mode.elc
|
|
%endif
|
|
|
|
# Create executables pypy, pypy2 and pypy2.7
|
|
ln -sf %{pypyprefix}/bin/%{name} %{buildroot}%{_bindir}/%{name}%{pylibver}
|
|
ln -sf %{_bindir}/%{name}%{pylibver} %{buildroot}%{_bindir}/%{name}%{pymajorlibver}
|
|
ln -sf %{_bindir}/%{name}%{pymajorlibver} %{buildroot}%{_bindir}/%{name}
|
|
|
|
# Move files to the right places and remove unnecessary files
|
|
mv %{buildroot}/%{pypyprefix}/bin/libpypy-c.so %{buildroot}/%{_libdir}
|
|
rm -rf %{buildroot}/%{_libdir}/%{name}-%{basever}.tar.bz2
|
|
rm -rf %{buildroot}/%{pypyprefix}/README.rst
|
|
rm -rf %{buildroot}/%{pypyprefix}/README.rst
|
|
rm -rf %{buildroot}/%{pypy_include_dir}/README
|
|
chrpath --delete %{buildroot}/%{pypyprefix}/bin/%{name}
|
|
|
|
# Install macros for rpm:
|
|
mkdir -p %{buildroot}/%{_rpmconfigdir}/macros.d
|
|
install -m 644 %{SOURCE1} %{buildroot}/%{_rpmconfigdir}/macros.d
|
|
install -m 644 %{SOURCE2} %{buildroot}/%{_rpmconfigdir}/macros.d
|
|
|
|
# Remove build script from the package
|
|
#rm %{buildroot}/%{pypyprefix}/lib_pypy/ctypes_config_cache/rebuild.py
|
|
|
|
# since 5.10.0, the debug binaries are built and shipped, making the
|
|
# pypy package ~350 MiB. let's remove them here for now and TODO figure out why
|
|
rm -f %{buildroot}%{pypyprefix}/bin/pypy.debug
|
|
rm -f %{buildroot}%{pypyprefix}/bin/libpypy-c.so.debug
|
|
|
|
%check
|
|
topdir=$(pwd)
|
|
|
|
SkipTest() {
|
|
TEST_NAME=$1
|
|
sed -i -e"s|^$TEST_NAME$||g" testnames.txt
|
|
}
|
|
|
|
CheckPyPy() {
|
|
# We'll be exercising one of the freshly-built binaries using the
|
|
# test suite from the standard library (overridden in places by pypy's
|
|
# modified version)
|
|
ExeName=$1
|
|
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "STARTING TEST OF: $ExeName"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
|
|
pushd %{goal_dir}
|
|
|
|
# I'm seeing numerous cases where tests seem to hang, or fail unpredictably
|
|
# So we'll run each test in its own process, with a timeout
|
|
|
|
# Use regrtest to explicitly list all tests:
|
|
( ./$ExeName -c \
|
|
"from test.regrtest import findtests; print('\n'.join(findtests()))"
|
|
) > testnames.txt
|
|
|
|
# Skip some tests:
|
|
# "audioop" doesn't exist for pypy yet:
|
|
SkipTest test_audioop
|
|
|
|
# The gdb CPython hooks haven't been ported to cpyext:
|
|
SkipTest test_gdb
|
|
|
|
# hotshot relies heavily on _hotshot, which doesn't exist:
|
|
SkipTest test_hotshot
|
|
|
|
# "strop" module doesn't exist for pypy yet:
|
|
SkipTest test_strop
|
|
|
|
# I'm seeing Koji builds hanging e.g.:
|
|
# http://koji.fedoraproject.org/koji/getfile?taskID=3386821&name=build.log
|
|
# The only test that seems to have timed out in that log is
|
|
# test_multiprocessing, so skip it for now:
|
|
SkipTest test_multiprocessing
|
|
|
|
echo "== Test names =="
|
|
cat testnames.txt
|
|
echo "================="
|
|
|
|
echo "" > failed-tests.txt
|
|
|
|
for TestName in $(cat testnames.txt) ; do
|
|
|
|
echo "===================" $TestName "===================="
|
|
|
|
# Use /usr/bin/time (rather than the shell "time" builtin) to gather
|
|
# info on the process (time/CPU/memory). This passes on the exit
|
|
# status of the underlying command
|
|
#
|
|
# Use perl's alarm command to impose a timeout
|
|
# 900 seconds is 15 minutes per test.
|
|
# If a test hangs, that test should get terminated, allowing the build
|
|
# to continue.
|
|
#
|
|
# Invoke pypy on test.regrtest to run the specific test suite
|
|
# verbosely
|
|
#
|
|
# For now, || true, so that any failures don't halt the build:
|
|
( /usr/bin/time \
|
|
perl -e 'alarm shift @ARGV; exec @ARGV' 900 \
|
|
./$ExeName -m test.regrtest -v $TestName ) \
|
|
|| (echo $TestName >> failed-tests.txt) \
|
|
|| true
|
|
done
|
|
|
|
echo "== Failed tests =="
|
|
cat failed-tests.txt
|
|
echo "================="
|
|
|
|
popd
|
|
|
|
# Doublecheck pypy's own test suite, using the built pypy binary:
|
|
|
|
# Disabled for now:
|
|
# x86_64 shows various failures inside:
|
|
# jit/backend/x86/test
|
|
# followed by a segfault inside
|
|
# jit/backend/x86/test/test_runner.py
|
|
#
|
|
# i686 shows various failures inside:
|
|
# jit/backend/x86/test
|
|
# with the x86_64 failure leading to cancellation of the i686 build
|
|
|
|
# Here's the disabled code:
|
|
# pushd pypy
|
|
# time translator/goal/$ExeName test_all.py
|
|
# popd
|
|
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "FINISHED TESTING: $ExeName"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
echo "--------------------------------------------------------------"
|
|
}
|
|
|
|
#python testrunner/runner.py --logfile=pytest-A.log --config=pypy/pytest-A.cfg --config=pypy/pytest-A.py --root=pypy --timeout=3600
|
|
#python pypy/test_all.py --pypy=pypy/goal/pypy --timeout=3600 --resultlog=cpython.log lib-python
|
|
#python pypy/test_all.py --pypy=pypy/goal/pypy --resultlog=pypyjit.log pypy/module/pypyjit/test
|
|
#pypy/goal/pypy pypy/test_all.py --resultlog=pypyjit_new.log
|
|
|
|
%if %{run_selftests}
|
|
CheckPyPy %{name}-c
|
|
|
|
%if 0%{with_stackless}
|
|
CheckPyPy %{name}-c-stackless
|
|
%endif
|
|
|
|
%endif # run_selftests
|
|
|
|
# Because there's a bunch of binary subpackages and creating
|
|
# /usr/share/doc/pypy3-this and /usr/share/doc/pypy3-that
|
|
# is just confusing for the user.
|
|
%global _docdir_fmt %{name}
|
|
|
|
%files libs
|
|
%doc README.rst
|
|
|
|
%dir %{pypyprefix}
|
|
%dir %{pypyprefix}/lib-python
|
|
%license %{pypyprefix}/LICENSE
|
|
%{_libdir}/libpypy-c.so
|
|
%{pypyprefix}/lib-python/%{pylibver}/
|
|
%{pypyprefix}/lib_pypy/
|
|
%{pypyprefix}/site-packages/
|
|
%if %{with_emacs}
|
|
%{_emacs_sitelispdir}/%{name}trace-mode.el
|
|
%{_emacs_sitelispdir}/%{name}trace-mode.elc
|
|
%endif
|
|
|
|
%files
|
|
%doc README.rst
|
|
%{_bindir}/%{name}
|
|
%{_bindir}/%{name}%{pylibver}
|
|
%{_bindir}/%{name}%{pymajorlibver}
|
|
%{pypyprefix}/bin/
|
|
|
|
%files devel
|
|
%dir %{pypy_include_dir}
|
|
%{pypy_include_dir}/*.h
|
|
%{pypy_include_dir}/_numpypy
|
|
%{_rpmconfigdir}/macros.d/macros.%{name}
|
|
%{_rpmconfigdir}/macros.d/macros.%{name}%{pymajorlibver}
|
|
|
|
%if 0%{with_stackless}
|
|
%files stackless
|
|
%doc README.rst
|
|
%{_bindir}/%{name}-stackless
|
|
%endif
|
|
|
|
|
|
%changelog
|
|
%autochangelog
|