目次
概要
- ConoHa WingでpythonのWebアプリ(flask)を公開しようと思いました。2024年1月現在、ConoHa Wingにインストールされているpythonは3.6.11となっており、古くなっているので最新の3.11をインストールしようと思います。
- ConoHa Wingの利用者に管理者権限は割り当てられておらず、yum等のパッケージマネージャを使用できません。そのため、ここでは、ソースコードからpythonをビルド(コンパイル)する前提の手順を紹介します。
- 当初、開発環境(Windows10)のpythonバージョンを3.6に合わせて開発しようと思いました。しかしながら、最新のVSCode(Python 拡張機能)でのデバッグでは、3.7以上が必要なので、3.6を使用するのは諦めました。(Python 拡張機能のバージョンを下げれば問題ないようです。)
前提
- ConoHa Wingの既存の実行環境は次の通りです。
(OSはCloud Linuxを使用しています。)12345678910111213$ uname -aLinux xxx.sh.tyo13.10.0-962.3.2.lve1.5.44.3.el7.x86_64 #1 SMPMon Feb 22 04:35:33 EST 2021 x86_64 x86_64 x8$ /usr/local/bin/python --versionPython 3.6.11$ openssl versionOpenSSL 1.0.2k-fips 26 Jan 2017$ gcc --versiongcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)Copyright (C) 2015 Free Software Foundation, Inc.This is free software; see the source for copying conditions. There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - 次のパッケージを使用します。
- python3.11で使用するlibffi, opensslに関して、既存環境のものは古いので、pythonと併せて最新のものをインストールします。
- なお、これらがなくても機能を制限してpythonをインストールすることもできます。しかしながら、ここでは後でflaskの使用を考えているので、必須の手順としています。
No. パッケージ 理由 1 Python(3.11.7) python本体です。 2 openssl(3.2.0) ハッシュや暗号化処理のために使用します。
(python3.10からOpenSSL1.1.1以上が必要。)3 libffi(3.4.4) OpenSSL等のC言語のライブラリを呼び出すために使用します。 - 管理者権限がなく、パッケージマネージャの利用も困難なので、次の前提の手順にしています。
- 各パッケージは、ソースコード(.tgz)からビルド・インストールします。
- ビルドのためのパッケージの展開先は、ホームディレクトリ直下のwork(~/work)とします。
- パッケージのインストール先は、ホームディレクトリ直下のlocalディレクトリ($HOME/local)とします。
インストール手順
使用するディレクトリ、パッケージのバージョンなどは、ご所望の環境に応じて適宜変更してください。
$HOMEは~/と同じパスを示しています。
libffiのインストール
インストール先として$HOME/localを指定し、ビルド・インストールします。
1 2 3 4 5 6 7 8 9 10 | $ cd ~/ $ mkdir work $ cd work/ $ wget https://github.com/libffi/libffi/releases/download/v3.4.4/libffi-3.4.4.tar.gz $ tar xvfz libffi-3.4.4.tar.gz $ cd libffi-3.4.4 $ ./configure --prefix=$HOME/local $ make $ make install |
opensslのインストール
インストール先として$HOME/localを指定し、ビルド・インストールします。
1 2 3 4 5 6 7 8 9 | $ cd ~/work $ wget --no-check-certificate https://www.openssl.org/source/openssl-3.2.0.tar.gz $ tar xvfz openssl-3.2.0.tar.gz $ cd openssl-3.2.0 $ ./Configure --prefix=$HOME/local $ make $ make install |
pythonのインストール
インストール先として$HOME/localを指定し、ビルド・インストールします。
python3, pip3という名称でインストールされるので、python, pipで実行できるようシンボリックリンクを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $ cd ~/work $ wget https://www.python.org/ftp/python/3.11.7/Python-3.11.7.tgz $ tar xvfz Python-3.11.7.tgz $ cd Python-3.11.7 $ ./configure --prefix=$HOME/local LDFLAGS="-L $HOME/local/lib64" CPPFLAGS="-I $HOME/local/include" $ export LD_LIBRARY_PATH="$HOME/local/lib64" $ make $ make install $ cd ~/local/bin $ ln -s python3.11 python $ ln -s pip3.11 pip |
- configureでは、pythonのインストール先を指定します。(--prefix $HOME/local)
- 前述の手順でインストールしたlibffi, opensslのライブラリやインクルードファイルを参照できるよう、リンカーオプション(LDFLAGS)、コンパイラオプション(CPPFLAGS)を指定します。
- make実行時に”Following modules built successfully but were removed because they could not be imported”という警告が出力されます。これを回避するために、環境変数LD_LIBRARY_PATH(コマンド実行時にライブラリを探索するパス)を宣言しています。詳細は参考をご覧ください。
- configureにて--with-openssl等のSSLオプションを指定していません。リンカーオプション(LDFLAGS)で適切なOpenSSLライブラリを参照できれば、自動的にSSL(pythonのssl系モジュール)が有効になるようです。
- configureで有効になったpythonモジュールは、config.logで確認できます。123456789101112$ grep -1 _ssl config.logconfigure:25458: result: yesconfigure:25463: checking for stdlib extension module _sslconfigure:25493: result: yes--ac_cv_working_openssl_hashlib=yesac_cv_working_openssl_ssl=yesac_cv_working_signed_char_c=yes--py_cv_module__sqlite3=disabledpy_cv_module__ssl=yespy_cv_module__statistics=yes
動作確認
pythonコマンドが実行可能なこと、バージョンが3.11になっていることを確認します。
利用可能なモジュールとして、_ctypes, _sslが表示されることを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | $ ~/local/bin/python3 --version Python 3.11.7 $ ~/local/bin/pip3 list Package Version ---------- ------- pip 23.2.1 setuptools 65.5.0 $ ~/local/bin/python3 -c "help('modules')" __future__ _testimportmultiple getpass sched __hello__ _testinternalcapi gettext secrets __phello__ _testmultiphase glob select ... _ctypes base64 logging struct ... _ssl faulthandler pydoc_data xml ... |
その他の設定
pythonコマンドが正しいライブラリを参照できるようLD_LIBRARY_PATHを追加します。
また、インストールしたpython, pipコマンドを使用できるようパスを変更します。
1 2 3 4 5 6 7 8 9 10 11 12 | $ cd ~/ $ vi .bashrc (最後に次の2行を追加) export LD_LIBRARY_PATH="$HOME/local/lib64" export PATH="~/local/bin:$PATH" $ . .bashrc $ python --version Python 3.11.7 $ pip --version pip 23.2.1 from /home/xxx/local/lib/python3.11/site-packages/pip (python 3.11) |
参考
ネットに情報がほとんどなかったので独自に解決しました。
ffi.hが見つからないエラー
- pythonのmake実行時に次の警告が出力されます。123456789101112131415161718192021$ ./configure --prefix=$HOME/local$ make/home/xxx/work/Python-3.11.7/Modules/_ctypes/_ctypes.c:118:17: fatal error: ffi.h: No such file or directory#include <ffi.h>^compilation terminated.*** WARNING: renaming "_ssl" since importing it failed: libssl.so.3: cannot open shared object file: No such file or directory*** WARNING: renaming "_hashlib" since importing it failed: libcrypto.so.3: cannot open shared object file: No such file or directory...Failed to build these modules:_ctypesFollowing modules built successfully but were removed because they could not be imported:_hashlib _sslCould not build the ssl module!Python requires a OpenSSL 1.1.1 or newerCustom linker flags may require --with-openssl-rpath=auto
- C言語ライブラリを呼び出すためのライブラリctypesをビルドする際に、libffiが提供するこのヘッダファイルが必要になるようです。
- 既存環境では見つけられなかったので、libffiをインストールします。(ここでは~/localにインストールする想定なので、当該ヘッダファイルは~/local/includeに配置されます。)
- コンパイル時にこのヘッダファイルを見つけられるよう、configureオプションにCPPFLAGS="-I $HOME/local/include"を指定します。
- なお、_hashlib, _sslモジュールのエラーも併せて出力されますが、ctypesの問題解後に解消されました。(_hashlib, _sslはctypesを使用してOpenSSLのC言語ライブラリを参照しており、ctypesのエラーでOpeneSSLを参照できずにエラーになっていると思われます。)
共有ライブラリが見つからないエラー
- pythonのmake実行時に次の警告が出力されます。12345678910111213141516$ ./configure --prefix=$HOME/local LDFLAGS="-L $HOME/local/lib64" CPPFLAGS="-I $HOME/local/include"$ make...*** WARNING: renaming "_ssl" since importing it failed: libssl.so.3: cannot open shared object file: No such file or directory*** WARNING: renaming "_hashlib" since importing it failed: libcrypto.so.3: cannot open shared object file: No such file or directory*** WARNING: renaming "_ctypes" since importing it failed: libffi.so.8: cannot open shared object file: No such file or directory...Following modules built successfully but were removed because they could not be imported:_ctypes _hashlib _sslCould not build the ssl module!Python requires a OpenSSL 1.1.1 or newerCustom linker flags may require --with-openssl-rpath=auto
- “built successfully”と出力されているのでビルドは成功しているようですが、ビルドしたpythonコマンドの実行に失敗していると考えました。(コンパイル時は、LDFLAGSオプションを指定することでlibffi, opensselライブラリを参照できているが、ビルドしたpythonを単体で実行するとそれらのライブラリを参照できず、”cannot open shared object”になっている。)
- pythonコマンド実行時に新しいlibffi, opensslライブラリを見つけられるよう、環境変数LD_LIBRARY_PATHを宣言します。(LD_LIBRARY_PATH="$HOME/local/lib64")