File pypy.spec of Package pypy3

#
# Copyright (c) 2013, Sascha Peilicke <saschpe@gmx.de>
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
#
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#

# 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 We will build
# a "pypy" binary. Unfortunately, the JIT support is only available on some
# architectures (see pypy-1.4/pypy/jit/backend/detect_cpu.py:getcpuclassname).
%ifarch %{ix86} x86_64 %arm
%define with_jit        1
%else
%define with_jit        0
%endif

# Forcibly use the shadow-stack option for detecting GC roots, rather than
# relying on hacking up generated assembler with regexps:
%global shadow_stack 1

# Should be require "pypy" instead of "python-devel" for translation?
%bcond_with self_hosting

# Tests should not be run in normal builds - it takes hours w/o tests
%bcond_with tests

# Turn off the brp-python-bytecompile postprocessing script. We manually invoke it later on, using the freshly built pypy binary:
%define __os_install_post %(echo '%{__os_install_post}' | sed -e 's!/usr/lib[^[:space:]]*/brp-python-bytecompile[[:space:]].*$!!g')

%global py_ver 2.7

Name:           pypy
Version:        5.1.0
%define pypyprefix      %{_libdir}/pypy-%{version}
Release:        0
Url:            http://pypy.org/
Summary:        A very fast and compliant implementation of the Python language
License:        MIT
Group:          Development/Languages/Python
Source0:        https://bitbucket.org/pypy/pypy/downloads/%{name}-%{version}-src.tar.bz2
Source1:        macros.pypy
Source100:      rpmlintrc
Patch0:         pypy-1.2-suppress-mandelbrot-set-during-tty-build.patch
Patch1:         006-always-log-stdout.patch
#PATCH-FIX-OPENSUSE: fix library includes dirs and link library names
Patch2:         pypy-cffi-suse.patch
BuildRoot:      %{_tmppath}/%{name}-%{version}-build
BuildRequires:  libffi-devel
BuildRequires:  openssl-devel
BuildRequires:  pkg-config
BuildRequires:  gdbm-devel
BuildRequires:  pkgconfig(bzip2)
BuildRequires:  pkgconfig(expat)
BuildRequires:  pkgconfig(ncurses)
BuildRequires:  pkgconfig(sqlite3)
BuildRequires:  pkgconfig(zlib)
BuildRequires:  pkgconfig(tcl)
BuildRequires:  pkgconfig(tk)
%if %{with self_hosting}
BuildRequires:  pypy-devel
%else
BuildRequires:  pkgconfig(python)
BuildRequires:  python-curses
%endif
%ifarch %{ix86} x86_64 ppc ppc64 ppc64le s390x
BuildRequires:  pkgconfig(valgrind)
%endif
BuildRequires:  execstack
#XXX: mvyskocil: I'd not fix implicit-fortify-decl or implicit-pointer-decl issues in **generated** C code
BuildRequires:  -post-build-checks
BuildRequires:  fdupes
# Documentation requirements:
#BuildRequires:  python-Sphinx
# Metadata for the core package (the JIT build):
Requires:       pypy-libs = %{version}

%description
PyPy is a fast, compliant alternative implementation of the Python language.
It has several advantages and distinct features:

  * Speed: Thanks to its Just-in-Time compiler, Python programs often run
    faster on PyPy
  * Memory usage: large, memory-hungry Python programs might end up taking less
    space than they do in CPython
  * Compatibility: PyPy is highly compatible with existing python code. It
    supports ctypes and can run popular python libraries like Twisted and Django
  * Sandboxing: PyPy provides the ability to run untrusted code in a fully secure way
  * Stackless: PyPy can be configured to run in stackless mode, providing
    micro-threads for massive concurrency

%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
Group:          Development/Languages/Python
Summary:        Run-time libraries used by PyPy implementations of Python

%description libs
PyPy is a fast, compliant alternative implementation of the Python language.

Libraries required by the various PyPy implementations of Python.

%package devel
Group:          Development/Languages/Python
Summary:        Development tools for working with PyPy
Requires:       %{name} = %{version}

%description devel
PyPy is a fast, compliant alternative implementation of the Python language.

Header files for building C extension modules against PyPy

%package testsuite
Group:          Development/Languages/Python
Summary:        Development tools for working with PyPy
Requires:       %{name} = %{version}

%description testsuite
PyPy is a fast, compliant alternative implementation of the Python language.

Tests for PyPy and its standard library.

%package idle
Summary:        An Integrated Development Environment for Python
Group:          Development/Languages/Python
Requires:       %{name} = %{version}
Requires:       %{name}-tk

%description idle
IDLE is a Tkinter based integrated development environment for Python.
It features a multi-window text editor with multiple undo, Python
colorizing, and many other things, as well as a Python shell window and
a debugger.

%package tk
Summary:        TkInter - Python Tk Interface
Group:          Development/Libraries/Python
Requires:       %{name} = %{version}

%description tk
PyPy interface to Tk. Tk is the GUI toolkit that comes with Tcl. The
"xrpm" package uses this PyPy interface.

%package emacs
Summary:        Emacs mode for the PyPy JIT viewer
Group:          Productivity/Text/Editors
Requires:       %{name} = %{version}

%description emacs
PyPy is a fast, compliant alternative implementation of the Python language.

Emacs mode for the PyPy JIT viewer.

%package vim
Summary:        Vim syntax files for the PyPy JIT viewer
Group:          Productivity/Text/Editors
Requires:       %{name} = %{version}

%description vim
PyPy is a fast, compliant alternative implementation of the Python language.

Vim syntax files for the PyPy JIT viewer.

%prep
%setup -q -n %{name}-%{version}-src
%patch0 -p1
%patch1 -p1
%patch2 -p1

# Replace /usr/local/bin/python shebangs with /usr/bin/python:
find -name "*.py" -exec sed -i -e "s|/usr/local/bin/python|/usr/bin/python|" {} \;
# Remove DOS batch files:
find -name "*.bat" -exec rm {} \;
find -name '*.jar' -exec rm {} \;

# remove spurious .orig files
find -name "*.orig" -delete

%build

pushd pypy/goal

%if 0%{shadow_stack}
# 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:
%define gcrootfinder_options --gcrootfinder=shadowstack

export CFLAGS=$(echo "$RPM_OPT_FLAGS")

%else
# Go with the default, which is "asmgcc"

%define gcrootfinder_options %{nil}

# https://bugzilla.redhat.com/show_bug.cgi?id=588941#c18
# The generated Makefile compiles the .c files into assembler (.s), rather
# than direct to .o  It then post-processes this assembler to locate
# garbage-collection roots (building .lbl.s and .gcmap files, and a
# "gcmaptable.s").  (The modified .lbl.s files have extra code injected
# within them).
# Unfortunately, the code to do this:
#   pypy-1.4/pypy/translator/c/gcc/trackgcroot.py
# doesn't interract well with the results of using our standard build flags.
# For now, filter our CFLAGS of everything that could be conflicting with
# pypy.  Need to check these and reenable ones that are okay later.
# Filed as https://bugzilla.redhat.com/show_bug.cgi?id=666966
export CFLAGS=$(echo "$RPM_OPT_FLAGS" | sed -e 's/-Wp,-D_FORTIFY_SOURCE=2//' -e 's/-fexceptions//' -e 's/-fstack-protector//' -e 's/--param=ssp-buffer-size=4//' -e 's/-O2//' -e 's/-fasynchronous-unwind-tables//' -e 's/-march=i686//' -e 's/-mtune=atom//')

%endif

# 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 '/usr/bin/pypy' ; then
  INTERP='pypy'
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='python'
fi
touch __TSTAMP__

# mvyskocil: memory requirements of pypy build process are huge. I saw OOM killer on i586 with just two processes
#            preffer build success than a speed
JOBS=1

RPM_BUILD_ROOT= $INTERP ../../rpython/bin/rpython --log --shared --make-jobs="${JOBS}" \
                     --batch %{gcrootfinder_options} \
%if 0%{?with_jit}
  --opt=jit \
%else
  --opt=2 \
%endif
    targetpypystandalone.py

# generate appropriate __pycache__ dirs
# advice from: http://mail.python.org/pipermail/pypy-dev/2013-August/011636.html
./pypy-c -c 'import _sqlite3, _curses, syslog, _tkinter' || :
# remove bogus __pycache__/home/abuild subdirs, idea taken from FreeBSD ports
find . -name '__pycache__' | xargs -n 1 -I {} find {} -mindepth 1 -maxdepth 1 -type d | xargs rm -vrf

popd #pypy/goal

# remove c files from __pycache__ dirs to avoid
# pypy-libs.x86_64: E: devel-file-in-non-devel-package (Badness: 50) /usr/lib/pypy-2.2/lib_pypy/__pycache__/_cffi__ga01735dbxad93c709.c
find . -name '__pycache__' | xargs -n 1 -I {} find {} -type f -name '*.c' | xargs rm -vrf

%install

mkdir -p %{buildroot}/%{_bindir}

install -Dm 755 pypy/goal/pypy-c %{buildroot}/%{pypyprefix}/pypy
ln -s %{pypyprefix}/pypy %{buildroot}/%{_bindir}
execstack --clear-execstack %{buildroot}/%{pypyprefix}/pypy

install -Dm 755 pypy/goal/libpypy-c.so %{buildroot}/%{_libdir}/

cp -a lib-python %{buildroot}/%{pypyprefix}
cp -a lib_pypy %{buildroot}/%{pypyprefix}

# Remove a text file that documents which selftests fail on Win32:
rm %{buildroot}/%{pypyprefix}/lib-python/win32-failures.txt
# Remove a text file containing upstream's recipe for syncing stdlib in
# their hg repository with cpython's:
rm %{buildroot}/%{pypyprefix}/lib-python/stdlib-upgrade.txt

# Remove all other platform files that plat-linux2 and plat-generic
# XXX: do we need plat-generic?
find %{buildroot}/%{pypyprefix}/lib* -type d -name 'plat-*' -and \( -not -name 'plat-linux2' -or -not -name 'plat-generic' \) | xargs rm -vrf

# 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 '^#!' {} \;         \
          -print -exec chmod a-x {} \; \) \)

mkdir -p %{buildroot}/%{pypyprefix}/site-packages

# pypy uses .pyc files by default (--objspace-usepycfiles), but has a slightly
# different bytecode format to CPython.  It doesn't use .pyo files: the -O flag
# is treated as a "dummy optimization flag for compatibility with C Python"
# Bytecompile all of the .py files we ship, using our pypy binary, giving us
# .pyc files for pypy.  The script actually does the work twice (passing in -O
# the second time) but it's simplest to reuse that script.
#
# The script has special-casing for .py files below /usr/lib{64}/python[0-9].[0-9]
# but given that we're installing into a different path, the supplied "default"
# implementation gets used instead.
#
# Note that some of the test files deliberately contain syntax errors, so
# we pass 0 for the second argument ("errors_terminate"):
#
export LD_LIBRARY_PATH=%{buildroot}/%{_libdir}/
# mv: don't use symlinks as script calls test -x, which fails on symlinks
/usr/lib/rpm/brp-python-bytecompile %{buildroot}/%{pypyprefix}/pypy 0

#TODO: we can write a test in Python, but check at least few modules from stdlib
for module in os pdb antigravity bisect; do
    if [ ! -f %{buildroot}/%{pypyprefix}/lib-python/%{py_ver}/${module}.pyc ]; then
        echo "ERROR: %{buildroot}/%{pypyprefix}/lib-python/%{py_ver}/${module}.pyc is missing" >&2
        echo "       brp-python-bytecode have probably failed"
        exit 1
    fi
done

# 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)

# FIXME: arguably these should be instead put into a subdir below /usr/include,
# it's not yet clear to me how upstream plan to deal with the C extension
# interface going forward, so let's just mimic upstream for now.
install -d %{buildroot}/%{pypyprefix}/include
cp include/*.h %{buildroot}/%{pypyprefix}/include

# Capture the RPython source code files from the build within the debuginfo
# package (rhbz#666975)
#%%define 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:
#find %%{buildroot}%%{pypy_debuginfo_dir} -type f -a \! \( -name "*.py" \
#                         -o -name "Makefile" \
#                         -o -name "typeids.txt" \
#                         -o -name "dynamic-symbols-*" \) -delete

# Install JIT trace mode for Emacs:
install -Dm644 rpython/jit/tool/pypytrace-mode.el %{buildroot}%{_datadir}/emacs/site-lisp/pypytrace-mode.el
# Install JIT trace VIM syntax file:
install -Dm644 rpython/jit/tool/pypytrace.vim %{buildroot}%{_datadir}/vim/site/syntax/jinja.vim
# Install RPM macros:
install -Dm644 %{SOURCE1} %{buildroot}/%{_sysconfdir}/rpm/macros.pypy

%fdupes -s %{buildroot}/%{pypyprefix}/lib-python/%{py_ver}/
%fdupes -s %{buildroot}/%{pypyprefix}/lib_pypy

%check
%if %{with tests}
time %{buildroot}/%{pypyprefix}/pypy pytest.py pypy/ || :
%endif

%files
%defattr(-,root,root,-)
%doc LICENSE README.rst
%{_bindir}/pypy
%{pypyprefix}/pypy
%{_libdir}/libpypy-c.so

%files libs
%defattr(-,root,root,-)
%doc LICENSE
%dir %{pypyprefix}
%{pypyprefix}/lib-python/
%{pypyprefix}/lib_pypy/
%exclude %{pypyprefix}/lib_pypy/testcapi_long.h
%exclude %{pypyprefix}/lib_pypy/_testcapimodule.c
%exclude %{pypyprefix}/lib_pypy/_ctypes_test.c
%{pypyprefix}/site-packages/
#testsuite
%exclude %{pypyprefix}/lib-python/%{py_ver}/ctypes/test/
%exclude %{pypyprefix}/lib-python/%{py_ver}/distutils/tests/
%exclude %{pypyprefix}/lib-python/%{py_ver}/json/tests/
%exclude %{pypyprefix}/lib-python/%{py_ver}/lib-tk/test/
%exclude %{pypyprefix}/lib-python/%{py_ver}/lib2to3/tests/
%exclude %{pypyprefix}/lib-python/%{py_ver}/sqlite3/test/
%exclude %{pypyprefix}/lib-python/%{py_ver}/test/
#tk
%exclude %{pypyprefix}/lib-python/%{py_ver}/lib-tk/
%exclude %{pypyprefix}/lib_pypy/_tkinter/
#idle
%exclude %{pypyprefix}/lib-python/%{py_ver}/idlelib/
# more required exclude related to "E: devel-file-in-non-devel-package"
%exclude %{pypyprefix}/lib_pypy/_audioop_cffi.c
%exclude %{pypyprefix}/lib_pypy/_curses_cffi.c
%exclude %{pypyprefix}/lib_pypy/_gdbm_cffi.c
%exclude %{pypyprefix}/lib_pypy/_pwdgrp_cffi.c
%exclude %{pypyprefix}/lib_pypy/_sqlite3_cffi.c
%exclude %{pypyprefix}/lib_pypy/_syslog_cffi.c
%exclude %{pypyprefix}/lib_pypy/cffi/_cffi_include.h
%exclude %{pypyprefix}/lib_pypy/cffi/parse_c_type.h

%files devel
%defattr(-,root,root,-)
%{pypyprefix}/include/
%{pypyprefix}/lib_pypy/testcapi_long.h
%{pypyprefix}/lib_pypy/_testcapimodule.c
%{pypyprefix}/lib_pypy/_ctypes_test.c
%{_sysconfdir}/rpm/macros.pypy

%files testsuite
%defattr(0644,root,root,0755)
%{pypyprefix}/lib-python/%{py_ver}/ctypes/test/
%{pypyprefix}/lib-python/%{py_ver}/distutils/tests/
%{pypyprefix}/lib-python/%{py_ver}/json/tests/
%{pypyprefix}/lib-python/%{py_ver}/lib-tk/test/
%{pypyprefix}/lib-python/%{py_ver}/lib2to3/tests/
%{pypyprefix}/lib-python/%{py_ver}/sqlite3/test/
%{pypyprefix}/lib-python/%{py_ver}/test/
%{pypyprefix}/lib-python/%{py_ver}/email/test/
%{pypyprefix}/lib-python/%{py_ver}/lib2to3/fixes/__init__.py
# last one only to avoid dangling-symlink warning related to fdupes call

%files idle
%defattr(644, root, root, 755)
%{pypyprefix}/lib-python/%{py_ver}/idlelib/

%files tk
%defattr(644, root, root, 755)
%{pypyprefix}/lib-python/%{py_ver}/lib-tk/
%{pypyprefix}/lib_pypy/_tkinter/

%files emacs
%defattr(-,root,root,-)
%{_datadir}/emacs/site-lisp/pypytrace-mode.el*

%files vim
%defattr(-,root,root,-)
%{_datadir}/vim

%changelog
openSUSE Build Service is sponsored by