March 21, 2023

CentOS 7でPython 3.10と3.11のrpmを作る

前回、CentOS 7.9にPython 3.10と3.11をソースからインストールできたので、ついでにrpmも作ってみた。

用意したもの

前回と同じくCentOS 7.9を最小構成でセットアップしたVM

手順

パッケージ追加

rpmbuildに必要なパッケージをインストール

$ sudo yum install rpmdevtools rpm-build gcc -y

Pythonのビルドに必要なパッケージをインストール

$ sudo yum install zlib-devel libffi-devel -y

※ 前回と同じく、not foundだと言われるモジュールで必要なものがあれば適宜パッケージを追加してほしい

OpenSSL 1.1.1追加

今回もOpenSSL 1.1.1tのrpmを自作してインストールする。
リンク先のspecファイルの Version: 1.1.1m1.1.1t に変えれば作成できる。

$ sudo yum localinstall openssl-opt-1.1.1t-1.el7.x86_64.rpm -y

rpmビルド

前回を参考にpython3-opt.specファイルを書いた。
パッケージ名はOpenSSLの時と同じように/optにインストールすることと、3.10と3.11を共存できるようにpython310-optとした。
3.11.2を作る時はName:Version:を変える。

Name: python310-opt
Version: 3.10.10
↓
Name: python311-opt
Version: 3.11.2

以下を~/に置く

Name: python310-opt
Version: 3.10.10
Release: 1%{?dist}
Group: Development/Languages
Summary: Interpreter of the Python programming language

License: Python
URL: https://www.python.org/
Source0: https://www.python.org/ftp/python/%{version}/Python-%{version}.tgz

BuildRequires: make gcc zlib-devel libffi-devel openssl-opt
BuildRoot: %{_tmppath}/%{name}-%{version}-root
Prefix: /opt/python3
AutoReqProv: no

%description

%prep
rm -rf $RPM_BUILD_ROOT

%setup -q -n Python-%{version}

%build
./configure \
--prefix=%{buildroot}%{prefix} \
--with-openssl=/opt/openssl/ \
--with-openssl-rpath=auto \
--enable-optimizations \
--with-lto 
make -j4

%install
export QA_SKIP_BUILD_ROOT=1
make altinstall
%define __python %{buildroot}%{prefix}/bin/python%{version}

%clean
rm -rf $RPM_BUILD_ROOT

%files
%{prefix}

%post
VERSION=%{version}
alternatives --install /usr/local/bin/python3 python3 /opt/python3/bin/python${VERSION%.*} 1

%postun
VERSION=%{version}
alternatives --remove python3 /opt/python3/bin/python${VERSION%.*}

%changelog
* Sun Mar 5 2023 nissy <nissy@example.com> %{version}-1
- Initial RPM release

make -j4 はCPUの数に応じて調整してほしい
※ Python 3.11でビルドエラーが発生する場合、前回と同じようにmake -j4を以下に変えてループさせる
いつか成功するはずだけど、諦めて--enable-optimizationsを外すという手もある

i=0; while true; do ((++i)) && make clean && make -j4 && echo "count=$i" && break; done

rpmbuildディレクトリ作成

$ rpmdev-setuptree

ソースをダウンロードして配置

$ spectool -g -R ~/python3-opt.spec

rpm作成

$ rpmbuild -bb ~/python3-opt.spec

rpmファイルは以下に作られる

~/rpmbuild/RPMS/x86_64/

インストールしたいホストへscpなり何らかの方法で転送して、yum localinstallでインストールする

alternativesでバージョンを切り替えられるようにしてあるので確認

$ alternatives --display python3
python3 -ステータスは自動です。
リンクは現在 /opt/python3/bin/python3.10 を指しています。
/opt/python3/bin/python3.10 - 優先度 1
/opt/python3/bin/python3.11 - 優先度 1
現在の「最適」バージョンは /opt/python3/bin/python3.10 です。
$ python3 -V
Python 3.10.10
$ sudo alternatives --config python3

2 プログラムがあり 'python3' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /opt/python3/bin/python3.10
   2           /opt/python3/bin/python3.11

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
$ python3 -V
Python 3.11.2

OpenSSLバージョン確認

$ /opt/python3/bin/python3.10 -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.1.1t  7 Feb 2023
$ /opt/python3/bin/python3.11 -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.1.1t  7 Feb 2023

試行錯誤の経緯

上の手順ができるまでの試行錯誤のメモを書いておく

AutoReqProv: no

rpmbuildの最後、Requiresで不穏な文字が…

$ rpmbuild -bb python3-opt.spec
略
Requires(post): /bin/sh
Requires(postun): /bin/sh
Requires: /bin/bash /bin/sh /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/bin/python3.10 /usr/bin/env /usr/local/bin/python libc.so.6()(64bit) libc.so.6(GLIBC_2.10)(64bit) libc.so.6(GLIBC_2.13)(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.15)(64bit) libc.so.6(GLIBC_2.17)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libc.so.6(GLIBC_2.3.2)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.5)(64bit) libc.so.6(GLIBC_2.6)(64bit) libc.so.6(GLIBC_2.7)(64bit) libc.so.6(GLIBC_2.9)(64bit) libcrypt.so.1()(64bit) libcrypt.so.1(GLIBC_2.2.5)(64bit) libcrypto.so.1.1()(64bit) libcrypto.so.1.1(OPENSSL_1_1_0)(64bit) libcrypto.so.1.1(OPENSSL_1_1_1)(64bit) libdl.so.2()(64bit) libdl.so.2(GLIBC_2.2.5)(64bit) libffi.so.6()(64bit) libm.so.6()(64bit) libm.so.6(GLIBC_2.2.5)(64bit) libnsl.so.1()(64bit) libnsl.so.1(GLIBC_2.2.5)(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libpthread.so.0(GLIBC_2.3.2)(64bit) libpthread.so.0(GLIBC_2.3.3)(64bit) librt.so.1()(64bit) librt.so.1(GLIBC_2.2.5)(64bit) libssl.so.1.1()(64bit) libssl.so.1.1(OPENSSL_1_1_0)(64bit) libssl.so.1.1(OPENSSL_1_1_1)(64bit) libutil.so.1()(64bit) libutil.so.1(GLIBC_2.2.5)(64bit) libz.so.1()(64bit) libz.so.1(ZLIB_1.2.0)(64bit) rtld(GNU_HASH)
ファイルの処理中: python310-opt-debuginfo-3.10.10-1.el7.x86_64
Provides: python310-opt-debuginfo = 3.10.10-1.el7 python310-opt-debuginfo(x86-64) = 3.10.10-1.el7
Requires(rpmlib): rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(CompressedFileNames) <= 3.0.4-1
パッケージに含まれないファイルの検査中: /usr/lib/rpm/check-files /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64
書き込み完了: /home/nissy/rpmbuild/RPMS/x86_64/python310-opt-3.10.10-1.el7.x86_64.rpm
書き込み完了: /home/nissy/rpmbuild/RPMS/x86_64/python310-opt-debuginfo-3.10.10-1.el7.x86_64.rpm
実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.kT5tz4
+ umask 022
+ cd /home/nissy/rpmbuild/BUILD
+ cd Python-3.10.10
+ rm -rf /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64
+ exit 0

出来上がったrpmが依存するパッケージを-Rオプションで問い合わせても、やはり~/rpmbuild/BUILDROOT/以下のPythonバイナリや、インストール後に作られる/usr/local/bin/pythonをインストール前に求めてくる…

$ rpm -qpR rpmbuild/RPMS/x86_64/python310-opt-3.10.10-1.el7.x86_64.rpm
/bin/bash
/bin/sh
/bin/sh
/bin/sh
/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/bin/python3.10
/usr/bin/env
/usr/local/bin/python
libc.so.6()(64bit)
libc.so.6(GLIBC_2.10)(64bit)
libc.so.6(GLIBC_2.13)(64bit)
libc.so.6(GLIBC_2.14)(64bit)
libc.so.6(GLIBC_2.15)(64bit)
libc.so.6(GLIBC_2.17)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.3.2)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libc.so.6(GLIBC_2.5)(64bit)
libc.so.6(GLIBC_2.6)(64bit)
libc.so.6(GLIBC_2.7)(64bit)
libc.so.6(GLIBC_2.9)(64bit)
libcrypt.so.1()(64bit)
libcrypt.so.1(GLIBC_2.2.5)(64bit)
libcrypto.so.1.1()(64bit)
libcrypto.so.1.1(OPENSSL_1_1_0)(64bit)
libcrypto.so.1.1(OPENSSL_1_1_1)(64bit)
libdl.so.2()(64bit)
libdl.so.2(GLIBC_2.2.5)(64bit)
libffi.so.6()(64bit)
libm.so.6()(64bit)
libm.so.6(GLIBC_2.2.5)(64bit)
libnsl.so.1()(64bit)
libnsl.so.1(GLIBC_2.2.5)(64bit)
libpthread.so.0()(64bit)
libpthread.so.0(GLIBC_2.2.5)(64bit)
libpthread.so.0(GLIBC_2.3.2)(64bit)
libpthread.so.0(GLIBC_2.3.3)(64bit)
librt.so.1()(64bit)
librt.so.1(GLIBC_2.2.5)(64bit)
libssl.so.1.1()(64bit)
libssl.so.1.1(OPENSSL_1_1_0)(64bit)
libssl.so.1.1(OPENSSL_1_1_1)(64bit)
libutil.so.1()(64bit)
libutil.so.1(GLIBC_2.2.5)(64bit)
libz.so.1()(64bit)
libz.so.1(ZLIB_1.2.0)(64bit)
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rtld(GNU_HASH)
rpmlib(PayloadIsXz) <= 5.2-1

rpmをインストールしようとすると当然、依存性解決に失敗してインストールできない。

$ sudo yum localinstall rpmbuild/RPMS/x86_64/python310-opt-3.10.10-1.el7.x86_64.rpm
略
--> 依存性の処理をしています: /usr/local/bin/python のパッケージ: python310-opt-3.10.10-1.el7.x86_64
--> 依存性の処理をしています: /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/bin/python3.10 のパッケージ: python310-opt-3.10.10-1.el7.x86_64
--> 依存性の処理をしています: /usr/local/bin/python のパッケージ: python310-opt-3.10.10-1.el7.x86_64
--> 依存性解決を終了しました。
エラー: パッケージ: python310-opt-3.10.10-1.el7.x86_64 (/python310-opt-3.10.10-1.el7.x86_64)
             要求: /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/bin/python3.10
エラー: パッケージ: python310-opt-3.10.10-1.el7.x86_64 (/python310-opt-3.10.10-1.el7.x86_64)
             要求: /usr/local/bin/python
 問題を回避するために --skip-broken を用いることができます。
 これらを試行できます: rpm -Va --nofiles --nodigest

ということで、specファイルにAutoReqProv: noを書いて自動依存性解決をやめさせた。

QA_SKIP_BUILD_ROOT=1

~/.rpmmacros%__arch_install_post に書かれた/usr/lib/rpm/check-buildrootでビルドのエラーが出て終わってしまう。

$ rpmbuild -bb python3-opt.spec
略
+ /usr/lib/rpm/check-buildroot
略
Binary file /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/python3.10/config-3.10-x86_64-linux-gnu/libpython3.10.a matches
/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/python3.10/config-3.10-x86_64-linux-gnu/Makefile:prefix=            /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3
/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/python3.10/config-3.10-x86_64-linux-gnu/Makefile:CONFIG_ARGS=        '--prefix=/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3' '--with-openssl=/opt/openssl/' '--with-openssl-rpath=auto' 'PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig'
/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/python3.10/config-3.10-x86_64-linux-gnu/python-config.py:#!/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/bin/python3.10
/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/pkgconfig/python-3.10.pc:prefix=/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3
/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/pkgconfig/python-3.10-embed.pc:prefix=/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3
Found '/home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64' in installed files; aborting
エラー: /var/tmp/rpm-tmp.hotzZd の不正な終了ステータス (%install)


RPM ビルドのエラー:
    /var/tmp/rpm-tmp.hotzZd の不正な終了ステータス (%install)

OpenSSLのrpmを作った時と同じようにQA_SKIP_BUILD_ROOT=1を書いた。

%define __python %{buildroot}%{prefix}/bin/python%{version}

/usr/lib/rpm/brp-python-bytecompileで大量にSyntaxErrorを吐いてエラー終了してしまう。

$ rpmbuild -bb python3-opt.spec
略
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-compress
+ /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
Compiling /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/python3.10/_aix_support.py ...
  File "/opt/python3/lib/python3.10/_aix_support.py", line 87
    raise ValueError(f"AIX_BUILDDATE is not defined or invalid: "
                                                                ^
SyntaxError: invalid syntax

Compiling /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/python3.10/_bootsubprocess.py ...
  File "/opt/python3/lib/python3.10/_bootsubprocess.py", line 71
    raise ValueError(f"unsupported command: {cmd!r}")
                                                   ^
SyntaxError: invalid syntax

略

Compiling /home/nissy/rpmbuild/BUILDROOT/python310-opt-3.10.10-1.el7.x86_64/opt/python3/lib/python3.10/zoneinfo/_zoneinfo.py ...
  File "/opt/python3/lib/python3.10/zoneinfo/_zoneinfo.py", line 78
    def from_file(cls, fobj, /, key=None):
                             ^
SyntaxError: invalid syntax

エラー: /var/tmp/rpm-tmp.jzcNEy の不正な終了ステータス (%install)


RPM ビルドのエラー:
    /var/tmp/rpm-tmp.jzcNEy の不正な終了ステータス (%install)

出力を見ると/usr/bin/pythonを使っている。
CentOS 7の/usr/bin/pythonはPython 2.7なので、ビルドしたPython 3を使ってほしい。

作成したpython3バイナリで__pythonを上書きした。

© 2020 nissy-lab.com