CentOS 7.9で標準リポジトリからyum installできるPython3パッケージは3.6.8
$ sudo yum install python3 -y
$ which python3
/usr/bin/python3
$ python3 -V
Python 3.6.8
SCLからインストールできるものでも3.8.13
$ sudo yum install centos-release-scl -y
$ sudo yum install rh-python38 -y
$ /opt/rh/rh-python38/root/usr/bin/python -V
Python 3.8.13
Python 3.8と3.9はステータスがsecurityに入っているので、3.10と3.11をソースからインストールしてみる。
※ Python 3.10と3.11のrpmを作るならこちら
用意したもの
CentOS 7.9を最小構成でセットアップしたVM
手順
パッケージ追加
ビルドに必要なパッケージインストール
$ sudo yum install gcc zlib-devel libffi-devel -y
このまま進むと以下のモジュールがnot foundだと言われるので、必要なものがあればパッケージ追加しておく。
The necessary bits to build these optional modules were not found:
_bz2 _curses _curses_panel
_dbm _gdbm _lzma
_sqlite3 _tkinter _uuid
readline
To find the necessary bits, look in setup.py in detect_modules() for the module's name.
module | rpm |
---|---|
_bz2 | bzip2-devel |
_cures | ncurses-devel |
_cures_panel | 〃 |
_dbm | gdbm-devel |
_gdbm | 〃 |
_lzma | xz-devel |
_sqlite3 | sqlite-devel |
_tkinter | tk-devel ※1 |
_uuid | libuuid-devel |
readline | readline-devel |
※1 Python 3.11.2では解消しなかった
自分はJupyterLabを使いたいのでsqlite-develを入れた。
$ sudo yum install sqlite-devel -y
OpenSSL 1.1.1追加
Python 3.10からOpenSSLは1.1.1が必須になったので、標準リポジトリのOpenSSL 1.0.2kだと以下が出て終わってしまう。
Could not build the ssl module!
Python requires a OpenSSL 1.1.1 or newer
EPELからインストールするか、rpmを自作してインストールする。
EPELのOpenSSLは1.1.1kなので、ここではrpmを自作してOpenSSL 1.1.1tを使うことにする。
$ sudo yum localinstall openssl-opt-1.1.1t-1.el7.x86_64.rpm -y
ダウンロード
$ cd ~
$ curl -OL https://www.python.org/ftp/python/3.10.10/Python-3.10.10.tgz
$ curl -OL https://www.python.org/ftp/python/3.11.2/Python-3.11.2.tgz
展開
$ find ./ -name "Python-3.*.tgz" -exec tar xzf {} \;
configure
公式ドキュメントのrecommended↓に従ってオプション追加
Configuring Python using
--enable-optimizations --with-lto
(PGO + LTO) is recommended for best performance.
$ cd ~/Python-3.10.10
$ ./configure \
--with-openssl=/opt/openssl/ \
--with-openssl-rpath=auto \
--prefix=/opt/python3 \
--enable-optimizations \
--with-lto
$ cd ~/Python-3.11.2
$ ./configure \
--with-openssl=/opt/openssl/ \
--with-openssl-rpath=auto \
--prefix=/opt/python3 \
--enable-optimizations \
--with-lto
build
- -jオプションはCPUの数に応じて調整する
- Python 3.11.2で
--enable-optimizations
を付けるとビルドに失敗することがあるので、whileで成功するまでループさせた --enable-optimizations
を諦めて普通にmake
するという手もある
$ cd ~/Python-3.10.10
$ make -j4
$ cd ~/Python-3.11.2
$ i=0; while true; do ((++i)) && make clean && make -j4 && echo "count=$i" && break; done
install
公式ドキュメントの警告に従ってaltinstall
警告
make install
はpython3
バイナリを上書きまたはリンクを破壊してしまうかもしれません。そのため、make install
の代わりに_exec_prefix_/bin/python_version_
のみインストールするmake altinstall
が推奨されています。
$ cd ~/Python-3.10.10
$ sudo make altinstall
$ cd ~/Python-3.11.2
$ sudo make altinstall
alternatives
alternativesで3.10と3.11を切り替えられるように登録する
$ sudo alternatives --install /usr/local/bin/python3 python3 /opt/python3/bin/python3.10 1
$ sudo alternatives --install /usr/local/bin/python3 python3 /opt/python3/bin/python3.11 2
$ sudo alternatives --list | grep python3
python3 auto /opt/python3/bin/python3.11
切り替えは以下のコマンドで番号を選択する
$ sudo alternatives --config python3
確認
$ which python3
/usr/local/bin/python3
$ ls -l /usr/local/bin/python3
lrwxrwxrwx. 1 root root 25 3月 4 17:42 /usr/local/bin/python3 -> /etc/alternatives/python3
$ python3 -V
Python 3.11.2 # alternativesで3.10.10を選んだ時は3.10.10になる
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
試行錯誤の経緯
上の手順ができるまでの試行錯誤のメモを書いておく
パッケージ追加
zlib-devel(zlibパッケージではなくzlib-devel)を入れないと、make altinstall
で以下が出てエラー終了した
Python 3.10.10
Traceback (most recent call last):
File "<frozen zipimport>", line 570, in _get_decompress_func
ModuleNotFoundError: No module named 'zlib'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<frozen zipimport>", line 618, in _get_data
File "<frozen zipimport>", line 573, in _get_decompress_func
zipimport.ZipImportError: can't decompress data; zlib not available
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 6, in <module>
File "/home/nissy/Python-3.10.10/Lib/runpy.py", line 220, in run_module
mod_name, mod_spec, code = _get_module_details(mod_name)
File "/home/nissy/Python-3.10.10/Lib/runpy.py", line 146, in _get_module_details
return _get_module_details(pkg_main_name, error)
File "/home/nissy/Python-3.10.10/Lib/runpy.py", line 110, in _get_module_details
__import__(pkg_name)
File "<frozen zipimport>", line 196, in get_code
File "<frozen zipimport>", line 752, in _get_module_code
File "<frozen zipimport>", line 620, in _get_data
zipimport.ZipImportError: can't decompress data; zlib not available
Traceback (most recent call last):
File "/home/nissy/Python-3.10.10/Lib/runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/home/nissy/Python-3.10.10/Lib/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/nissy/Python-3.10.10/Lib/ensurepip/__main__.py", line 5, in <module>
sys.exit(ensurepip._main())
File "/home/nissy/Python-3.10.10/Lib/ensurepip/__init__.py", line 287, in _main
return _bootstrap(
File "/home/nissy/Python-3.10.10/Lib/ensurepip/__init__.py", line 203, in _bootstrap
return _run_pip([*args, *_PACKAGE_NAMES], additional_paths)
File "/home/nissy/Python-3.10.10/Lib/ensurepip/__init__.py", line 104, in _run_pip
return subprocess.run(cmd, check=True).returncode
File "/home/nissy/Python-3.10.10/Lib/subprocess.py", line 526, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/home/nissy/Python-3.10.10/python', '-W', 'ignore::DeprecationWarning', '-c', '\nimport runpy\nimport sys\nsys.path = [\'/tmp/tmprraifvlv/setuptools-65.5.0-py3-none-any.whl\', \'/tmp/tmprraifvlv/pip-22.3.1-py3-none-any.whl\'] + sys.path\nsys.argv[1:] = [\'install\', \'--no-cache-dir\', \'--no-index\', \'--find-links\', \'/tmp/tmprraifvlv\', \'--root\', \'/\', \'--upgrade\', \'setuptools\', \'pip\']\nrunpy.run_module("pip", run_name="__main__", alter_sys=True)\n']' returned non-zero exit status 1.
make: *** [altinstall] エラー 1
Python 3.11.2
Traceback (most recent call last):
File "<frozen zipimport>", line 576, in _get_decompress_func
ModuleNotFoundError: No module named 'zlib'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<frozen zipimport>", line 624, in _get_data
File "<frozen zipimport>", line 579, in _get_decompress_func
zipimport.ZipImportError: can't decompress data; zlib not available
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<string>", line 6, in <module>
File "<frozen runpy>", line 222, in run_module
File "<frozen runpy>", line 148, in _get_module_details
File "<frozen runpy>", line 112, in _get_module_details
File "<frozen zipimport>", line 195, in get_code
File "<frozen zipimport>", line 758, in _get_module_code
File "<frozen zipimport>", line 626, in _get_data
zipimport.ZipImportError: can't decompress data; zlib not available
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/home/nissy/Python-3.11.2/Lib/ensurepip/__main__.py", line 5, in <module>
sys.exit(ensurepip._main())
^^^^^^^^^^^^^^^^^
File "/home/nissy/Python-3.11.2/Lib/ensurepip/__init__.py", line 286, in _main
return _bootstrap(
^^^^^^^^^^^
File "/home/nissy/Python-3.11.2/Lib/ensurepip/__init__.py", line 202, in _bootstrap
return _run_pip([*args, *_PACKAGE_NAMES], additional_paths)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/nissy/Python-3.11.2/Lib/ensurepip/__init__.py", line 103, in _run_pip
return subprocess.run(cmd, check=True).returncode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/nissy/Python-3.11.2/Lib/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/home/nissy/Python-3.11.2/python', '-W', 'ignore::DeprecationWarning', '-c', '\nimport runpy\nimport sys\nsys.path = [\'/tmp/tmpz7f_vc6_/setuptools-65.5.0-py3-none-any.whl\', \'/tmp/tmpz7f_vc6_/pip-22.3.1-py3-none-any.whl\'] + sys.path\nsys.argv[1:] = [\'install\', \'--no-cache-dir\', \'--no-index\', \'--find-links\', \'/tmp/tmpz7f_vc6_\', \'--root\', \'/\', \'--upgrade\', \'setuptools\', \'pip\']\nrunpy.run_module("pip", run_name="__main__", alter_sys=True)\n']' returned non-zero exit status 1.
make: *** [altinstall] エラー 1
libffi-develはビルド時の↓の解消に必要だった
Python 3.10.10
building '_ctypes' extension
gcc -pthread -fPIC -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/nissy/Python-3.10.10/Include -I/home/nissy/Python-3.10.10 -c /home/nissy/Python-3.10.10/Modules/_ctypes/_ctypes.c -o build/temp.linux-x86_64-3.10/home/nissy/Python-3.10.10/Modules/_ctypes/_ctypes.o -DPy_BUILD_CORE_MODULE
/home/nissy/Python-3.10.10/Modules/_ctypes/_ctypes.c:107:17: 致命的エラー: ffi.h: そのようなファイルやディレクトリはありません
#include <ffi.h>
^
コンパイルを停止しました。
略
Failed to build these modules:
_ctypes
Python 3.11.2
building '_ctypes' extension
gcc -pthread -fPIC -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -std=c11 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Werror=implicit-function-declaration -fvisibility=hidden -I./Include/internal -I./Include -I. -I/usr/local/include -I/home/nissy/Python-3.11.2/Include -I/home/nissy/Python-3.11.2 -c /home/nissy/Python-3.11.2/Modules/_ctypes/_ctypes.c -o build/temp.linux-x86_64-3.11/home/nissy/Python-3.11.2/Modules/_ctypes/_ctypes.o
/home/nissy/Python-3.11.2/Modules/_ctypes/_ctypes.c:118:17: 致命的エラー: ffi.h: そのようなファイルやディレクトリはあり ません
#include <ffi.h>
^
コンパイルを停止しました。
略
Failed to build these modules:
_ctypes
configure
Python-3.10.10では--enable-optimizations
を付けても問題なくビルドできるけど、Python-3.11.2ではビルド中に↓のエラーに遭遇する確率が結構高いので外した。
Fatal Python error: init_import_site: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
File "/home/nissy/Python-3.11.2/Lib/site.py", line 73, in <module>
import os
File "/home/nissy/Python-3.11.2/Lib/os.py", line 29, in <module>
from _collections_abc import _check_methods
SystemError: <built-in function compile> returned NULL without setting an exception
↓--enable-optimizations
を付けても、何度か make clean && make -j4
を繰り返すとたまにビルドに成功することがあってよく分からない。
↓
OS再起動してmake clean && make -j4
すると、Python 3.11.2で--enable-optimizations
を付けてもビルド成功率が割と高い気がする 。
↓--enable-optimizations
付きでconfigure後、↓を実行して放置しておけば、いつかはビルドに成功する。
何度か試したけど、多くても4回くらいで成功した。
$ cd ~/Python-3.11.2; i=0; while true; do ((++i)) && make clean && make -j4 && echo "count=$i" && break; done