%global version 3.9.17 %global pybasever 3.9 %global pyshortver 39 %global pyb 3.9 %global pkgname python%{pybasever} %global _libdir64 %{_libdir}64 %global pylibdir %{_libdir}/python%{pybasever} %global pylibdir64 %{_libdir64}/python%{pybasever} %global dynload_dir %{pylibdir}/lib-dynload %global dynload_dir64 %{pylibdir64}/lib-dynload %global SOABI cpython-%{pyshortver} Summary: Version %{pybasever} of the Python interpreter Name: %{pkgname} Version: %{version} Release: 1 License: Modified CNRI Open Source License Group: Development/Languages URL: https://www.python.org/ Source0: https://www.python.org/ftp/python/%{version}/Python-%{version}.tar.xz Source1: pyconfig.h # _LARGE_FILES should not be defined for 64bit build Patch0: python3.9-no-largefiles-64bit.patch # Pass "-C" to nm to suppress demangling of C++ names Patch1: python3.9-demangling-aix.patch # Use 64bit version of major, minor & makedev for 64bit AIX build Patch2: python3.9-makedev-64bit.patch # nextafter patch for AIX, See https://bugs.python.org/issue42323 Patch3: python3.9-nextafter-aix.patch # build with ncurses instead of AIX curses Patch4: python3.9-enable-ncurses-aix.patch # Link C extensions with libpython Patch5: python3.9-C-ext-link-libpython.patch # Create archive for libpython Patch6: python3.9-archive-libpython.patch # Remove Impfile as modules are now linked with libpython Patch7: python3.9-use-libpython-in-export-file.patch # lslpp throws "error: incorrect format: unknown tag: "INSTALLPREFIX" " in AIX 7.1 releases before TL4 Patch8: python3.9-ignore-lslpp-error.patch # add -lpython3.9 in the libs of .pc file Patch9: python3.9-pkgconfig.patch # configure passes -O3 when it uses GCC compiler Patch10: python3.9-avoid-O3.patch Provides: python-abi = %{pybasever} Provides: python(abi) = %{pybasever} BuildRequires: make, sed BuildRequires: pkg-config BuildRequires: bzip2-devel >= 1.0.8 BuildRequires: expat-devel >= 2.5.0 BuildRequires: gdbm-devel >= 1.23 BuildRequires: gettext-devel >= 0.21 BuildRequires: libffi-devel >= 3.4.2 BuildRequires: ncurses-devel >= 6.3 BuildRequires: readline-devel >= 8.1 BuildRequires: sqlite-devel >= 3.39.3 BuildRequires: tcl-devel >= 8.6.11 BuildRequires: tk-devel >= 8.6.11 BuildRequires: xz-devel >= 5.2.5 BuildRequires: zlib-devel >= 1.2.13 Requires: bzip2 >= 1.0.8 Requires: expat >= 2.5.0 Requires: gdbm >= 1.23 Requires: gettext >= 0.21 Requires: libffi >= 3.4.2 Requires: libgcc >= 8.3.0 Requires: ncurses >= 6.3 Requires: readline >= 8.1 Requires: sqlite >= 3.39.3 Requires: xz-libs >= 5.2.5 Requires: zlib >= 1.2.13 %description Python %{pybasever} is an accessible, high-level, dynamically typed, interpreted programming language, designed with an emphasis on code readability. It includes an extensive standard library, and has a vast ecosystem of third-party libraries. The %{pkgname} package provides the python%{pybasever} executable: the reference interpreter for the Python language, version 3 and majority of its standard library. The remaining parts of the Python standard library are broken out into the %{pkgname}-tkinter and %{pkgname}-test packages, which may need to be installed separately. IDLE for Python %{pybasever} is provided in the %{pkgname}-idle package and development files are provided through %{pkgname}-devel package %package devel Summary: Libraries and header files needed for Python development Requires: %{name} = %{version}-%{release} %description devel This package contains the header files and configuration needed to compile Python extension modules (typically written in C or C++), to embed Python into other programs, and to make binary distributions for Python libraries. It also contains 2to3 tool, an automatic source converter from Python 2.X. %package idle Summary: A basic graphical development environment for Python Requires: %{name} = %{version}-%{release} Requires: %{name}-tkinter = %{version}-%{release} %description idle IDLE is Python's Integrated Development and Learning Environment. IDLE has the following features: Python shell window (interactive interpreter) with colorizing of code input, output, and error messages; multi-window text editor with multiple undo, Python colorizing, smart indent, call tips, auto completion, and other features; search within any window, replace within editor windows, and search through multiple files (grep); debugger with persistent breakpoints, stepping, and viewing of global and local namespaces; configuration, browsers, and other dialogs. %package tkinter Summary: A GUI toolkit for Python Requires: %{name} = %{version}-%{release} Requires: tcl >= 8.6.11 Requires: tk >= 8.6.11 %description tkinter The Tkinter (Tk interface) library is a graphical user interface toolkit for the Python programming language. %package test Summary: The self-test suite for the main python3 package Requires: %{name} = %{version}-%{release} %description test The self-test suite for the Python interpreter. This is only useful to test Python itself. For testing general Python code, you should use the unittest module from %{pkgname}, or a library such as pytest. ################################# # Prep ################################# %prep # need tar from /opt/freeware to extract tar.xz archives export PATH=/opt/freeware/bin:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:. # Extract python %setup -q -n Python-%{version} %patch1 -p1 -b .demangling %patch3 -p1 -b .nextafter %patch4 -p1 -b .ncurses %patch5 -p1 %patch6 -p1 %patch7 -p1 %patch8 -p1 %patch9 -p1 %patch10 -p1 # Duplicate source for 32 & 64 bits rm -rf /tmp/%{name}-%{version}-32bit cp -rp . /tmp/%{name}-%{version}-32bit rm -rf * mv /tmp/%{name}-%{version}-32bit 32bit cp -rp 32bit 64bit # Specific patch for 64 bit cd 64bit %patch0 -p1 -b .large_file %patch2 -p1 -b .makedev ################################# # Build ################################# %build # setup common configuration for 32-bit and 64-bit builds export CONFIG_SHELL=/opt/freeware/bin/bash export CONFIGURE_ENV_ARGS=/opt/freeware/bin/bash export AR="/usr/bin/ar -X32_64" export CFLAGS="-I/opt/freeware/include -I/usr/include -DAIX_GENUINE_CPLUSCPLUS -D_ALL_SOURCE -D_LINUX_SOURCE_COMPAT" export CPPFLAGS="$CFLAGS" export CXXFLAGS="$CFLAGS" # build 64-bit version cd 64bit /opt/freeware/bin/sed -i "s|#! /usr/local/bin/python|#! /opt/freeware/bin/python%{pybasever}|g" Lib/cgi.py export OBJECT_MODE=64 export CC="gcc -maix64 -fPIC -pthread -O2" export CXX="g++ -maix64 -fPIC -pthread -O2" export LDFLAGS="-L/opt/freeware/lib/pthread -L/opt/freeware/lib64 -L/opt/freeware/lib -L/usr/lib -Wl,-blibpath:/opt/freeware/lib/pthread:/opt/freeware/lib64:/opt/freeware/lib:/usr/lib" export PKG_CONFIG_PATH=/opt/freeware/lib64/pkgconfig:/opt/freeware/lib/pkgconfig ./configure \ --prefix=%{_prefix} \ --libdir=%{_libdir64} \ --with-platlibdir=lib64 \ --mandir=%{_mandir} \ --enable-shared \ --enable-ipv6 \ --with-system-ffi \ --with-system-expat \ --with-tcltk-includes="-I/opt/freeware/include" \ --with-tcltk-libs="-L/opt/freeware/lib -ltcl -ltk" \ --with-computed-gotos \ --without-ensurepip gmake -j8 # build 32-bit version cd ../32bit /opt/freeware/bin/sed -i "s|#! /usr/local/bin/python|#! /opt/freeware/libexec/python%{pybasever}_32|g" Lib/cgi.py export OBJECT_MODE=32 export CC="gcc -fPIC -pthread -O2 -D_LARGE_FILES" export CXX="g++ -fPIC -pthread -O2 -D_LARGE_FILES" export LDFLAGS="-L/opt/freeware/lib/pthread -L/opt/freeware/lib -L/usr/lib -Wl,-blibpath:/opt/freeware/lib/pthread:/opt/freeware/lib:/usr/lib -Wl,-bmaxdata:0x80000000" export PKG_CONFIG_PATH=/opt/freeware/lib/pkgconfig ./configure \ --prefix=%{_prefix} \ --bindir=%{_libexecdir} \ --mandir=%{_mandir} \ --enable-shared \ --enable-ipv6 \ --with-system-ffi \ --with-system-expat \ --with-tcltk-includes="-I/opt/freeware/include" \ --with-tcltk-libs="-L/opt/freeware/lib -ltcl -ltk" \ --with-computed-gotos \ --without-ensurepip gmake -j8 ################################# # Install ################################# %install [ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT install_python(){ cd ${OBJECT_MODE}bit gmake DESTDIR=${RPM_BUILD_ROOT} install # pyconfig.h header file is arch specific (32bit vs 64bit) cp ${RPM_BUILD_ROOT}%{_includedir}/python%{pybasever}/pyconfig.h ${RPM_BUILD_ROOT}%{_includedir}/python%{pybasever}/pyconfig-ppc${OBJECT_MODE}.h ( if [ ${OBJECT_MODE} -eq 64 ] then cd ${RPM_BUILD_ROOT}%{_bindir} else cd ${RPM_BUILD_ROOT}%{_libexecdir} fi rm 2to3 idle3 pydoc3 python3 python3-config ) cd .. } #install 32bit version export OBJECT_MODE=32 install_python #install 64bit version export OBJECT_MODE=64 install_python # Add "_32" prefix to 32bit binaries ( cd ${RPM_BUILD_ROOT}%{_libexecdir} for f in 2to3-%{pyb} idle%{pyb} pydoc%{pyb} python%{pyb} python%{pyb}-config ; do mv ${f} ${f}_32 done for f in 2to3-%{pyb} idle%{pyb} pydoc%{pyb} ; do /opt/freeware/bin/sed -i "s|/opt/freeware/libexec/python%{pybasever}|/opt/freeware/libexec/python%{pybasever}_32|g" ${f}_32 done ) # Replace the pyconfig.h with the Source1 "pyconfig.h" file cp %{SOURCE1} ${RPM_BUILD_ROOT}%{_includedir}/python%{pybasever}/pyconfig.h /opt/freeware/bin/sed -i "s|/opt/freeware/libexec/python%{pybasever}|/opt/freeware/libexec/python%{pybasever}_32|g" ${RPM_BUILD_ROOT}%{pylibdir}/config-%{pybasever}/python-config.py # Put 64bit .so inside /opt/freeware/lib archive file of libpython ( cd ${RPM_BUILD_ROOT}%{_libdir64} ar -X64 -x libpython%{pybasever}.a ar -X64 -q ${RPM_BUILD_ROOT}%{_libdir}/libpython%{pybasever}.a libpython%{pybasever}.so ) # Create config directory from version specific config directory ( cd ${RPM_BUILD_ROOT}%{pylibdir64} ln -s config-%{pybasever} config cd ${RPM_BUILD_ROOT}%{pylibdir} ln -s config-%{pybasever} config ) # Create files list for main & sub rpms # main package find ${RPM_BUILD_ROOT}%{pylibdir} -type d | sed "s|${RPM_BUILD_ROOT}|%dir |" > main-pkg-files.tmp find ${RPM_BUILD_ROOT}%{pylibdir64} -type d | sed "s|${RPM_BUILD_ROOT}|%dir |" >> main-pkg-files.tmp find ${RPM_BUILD_ROOT}%{pylibdir} -type f >> main-pkg-files.tmp find ${RPM_BUILD_ROOT}%{pylibdir64} -type f >> main-pkg-files.tmp cat main-pkg-files.tmp | \ grep -v "_ctypes_test.%{SOABI}.so" | \ grep -v "_testbuffer.%{SOABI}.so" | \ grep -v "_testcapi.%{SOABI}.so" | \ grep -v "_testimportmultiple.%{SOABI}.so" | \ grep -v "_testinternalcapi.%{SOABI}.so" | \ grep -v "_testmultiphase.%{SOABI}.so" | \ grep -v "_xxtestfuzz.%{SOABI}.so" | \ grep -v "/test/" | \ grep -v "ctypes/test" |\ grep -v "distutils/test" |\ grep -v "lib2to3/test" | \ grep -v "sqlite3/test" |\ grep -v "unittest/test" | \ grep -v "idlelib" | \ grep -v "tkinter" | \ grep -v "turtle" | \ grep -v "config-%{pybasever}" | \ sed -e "s|${RPM_BUILD_ROOT}||" | \ sed -e "s|\ |*|" | \ sed -e "s|%dir\*|%dir |" >> main-pkg-files cat main-pkg-files.tmp | grep "_ctypes_test.%{SOABI}.so" > test-pkg-files.tmp cat main-pkg-files.tmp | grep "_testbuffer.%{SOABI}.so" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "_testcapi.%{SOABI}.so" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "_testimportmultiple.%{SOABI}.so" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "_testinternalcapi.%{SOABI}.so" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "_testmultiphase.%{SOABI}.so" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "_xxtestfuzz.%{SOABI}.so" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "/test/" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "ctypes/test" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "distutils/test" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "lib2to3/test" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "sqlite3/test" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "tkinter/test" >> test-pkg-files.tmp cat main-pkg-files.tmp | grep "unittest/test" >> test-pkg-files.tmp cat test-pkg-files.tmp | \ sed -e "s|${RPM_BUILD_ROOT}||" | \ sed -e "s|\ |*|" | \ sed -e "s|%dir\*|%dir |" | sort -u > test-pkg-files # devel package find ${RPM_BUILD_ROOT}%{pylibdir}/config-%{pybasever} -type f | grep -v "Makefile" > devel-pkg-files.tmp find ${RPM_BUILD_ROOT}%{pylibdir64}/config-%{pybasever} -type f | grep -v "Makefile" >> devel-pkg-files.tmp find ${RPM_BUILD_ROOT}%{_includedir}/python%{pybasever}/* -type d | sed "s|${RPM_BUILD_ROOT}|%dir |" >> devel-pkg-files.tmp find ${RPM_BUILD_ROOT}%{_includedir}/python%{pybasever} -type f | grep "\.h$" >> devel-pkg-files.tmp cat devel-pkg-files.tmp | \ sed -e "s|${RPM_BUILD_ROOT}||" | \ sed -e "s|\ |*|" | \ sed -e "s|%dir\*|%dir |" >> devel-pkg-files ################################# # Check ################################# %check ulimit -f unlimited ulimit -d unlimited ulimit -m unlimited ulimit -n 20000 cd 64bit export OBJECT_MODE=64 (gmake -k test || true) slibclean cd ../32bit export OBJECT_MODE=32 (gmake -k test || true) slibclean ################################# # File ################################# %files -f main-pkg-files %defattr(-,root,system,-) %doc 32bit/README.rst %{_bindir}/python%{pybasever} %{_bindir}/pydoc%{pybasever} %{_libexecdir}/python%{pybasever}_32 %{_libexecdir}/pydoc%{pybasever}_32 %{_mandir}/man1/python%{pybasever}.1 # "Makefile" and the config-32/64.h file are needed by # distutils/sysconfig.py:_init_posix(), so we include them in the core # package, along with their parent directories (bug 531901): %dir %{pylibdir}/config-%{pybasever}/ %{pylibdir}/config-%{pybasever}/Makefile %dir %{pylibdir64}/config-%{pybasever}/ %{pylibdir64}/config-%{pybasever}/Makefile %{pylibdir}/config %{pylibdir64}/config %dir %{_includedir}/python%{pybasever}/ %{_includedir}/python%{pybasever}/pyconfig.h %{_includedir}/python%{pybasever}/pyconfig-ppc32.h %{_includedir}/python%{pybasever}/pyconfig-ppc64.h %{_libdir}/libpython%{pybasever}.a %{_libdir64}/libpython%{pybasever}.a %files devel -f devel-pkg-files %defattr(-,root,system,-) %doc 32bit/Misc/README.valgrind 32bit/Misc/valgrind-python.supp %doc 32bit/Misc/gdbinit %{_bindir}/2to3-%{pybasever} %{_bindir}/python%{pybasever}-config %{_libexecdir}/2to3-%{pybasever}_32 %{_libexecdir}/python%{pybasever}-config_32 %{_libdir}/pkgconfig/python-%{pybasever}*.pc %{_libdir64}/pkgconfig/python-%{pybasever}*.pc # Exclude the header files already shipped with main rpm %exclude %{_includedir}/python%{pybasever}/pyconfig.h %exclude %{_includedir}/python%{pybasever}/pyconfig-ppc32.h %exclude %{_includedir}/python%{pybasever}/pyconfig-ppc64.h %files idle %defattr(-,root,system,-) %{_bindir}/idle%{pybasever} %{_libexecdir}/idle%{pybasever}_32 %{pylibdir}/idlelib %{pylibdir64}/idlelib %files tkinter %defattr(-,root,system,-) %{pylibdir}/tkinter %exclude %{pylibdir}/tkinter/test %{pylibdir64}/tkinter %exclude %{pylibdir64}/tkinter/test %{dynload_dir}/_tkinter.%{SOABI}.so %{dynload_dir64}/_tkinter.%{SOABI}.so %{pylibdir}/turtle.py %{pylibdir64}/turtle.py %{pylibdir}/__pycache__/turtle* %{pylibdir64}/__pycache__/turtle* %{pylibdir}/turtledemo %{pylibdir64}/turtledemo %files test -f test-pkg-files %defattr(-,root,system,-) %changelog * Wed Jul 05 2023 Ayappan P - 3.9.17-1 - Update to 3.9.17 version * Thu Mar 30 2023 Ayappan P - 3.9.16-2 - Add -lpython3.9 in libs variable of python pkgconfig file - Pass -O2 instead of -O3 * Fri Feb 03 2023 Ayappan P - 3.9.16-1 - Update to 3.9.16 version * Tue Dec 06 2022 Ayappan P - 3.9.15-1 - Update to 3.9.15 version - Remove "-brtl" flag - Link shared libraries of C extensions with libpython - libpython is properly archived now * Mon Sep 27 2021 Ayappan P - 3.9.6-1 - python 3.9.6 build for AIX Toolbox