Raspberry Pi5に最新のPythonをインストールする。

## 概略　
Raspberry Pi5にPython3の最新verをインストールする際にPython本体のみのビルド・インストールではモジュールが不足して使えない機能があります。事前にそれらをインストールしてからPython本体をビルドする方法の備忘録です。特に下記２点が大きな問題です。
1. python-ctypesがインストールされないためデバッグエラーして実行できない（VScode）
1. opensslがPythonにリンクされないためpipが使えない
### ビルドの際の不足モジュールについてのワーニング
```
The necessary bits to build these optional modules were not found:
_bz2                  _ctypes               _ctypes_test
_curses               _curses_panel         _dbm
_gdbm                 _hashlib              _lzma
_ssl                  _tkinter              _uuid
readline
To find the necessary bits, look in configure.ac and config.log.

Could not build the ssl module!
Python requires a OpenSSL 1.1.1 or newer

Checked 111 modules (31 built-in, 65 shared, 1 n/a on linux-aarch64, 1 disabled, 13 missing, 0 failed on import)
```

## 環境
- Raspberry Pi 5 8GB RAM
- PCIe3 NVMeでSSD接続
OS: 
```
Distributor ID: Debian
Description:    Debian GNU/Linux 12 (bookworm)
Release:        12
Codename:       bookworm
```
## 手順
1. 事前準備　必要なモジュールのインストール
1. Pythonのインストール
    1. ワークフォルダの作成
    1. Pythonソースのダウンロード～展開
    1. Pythonビルド前の事前準備、opensslのリンク設定変更
    1. Pythonのビルド～インストール
1. インストール結果確認
    1. PythonのVersion確認
    1. pipの確認を兼ねてpipのアップグレード
    1. VScodeでのデバッグの動作確認


## Pythonのダウンロードとビルド
### 事前準備、必要なモジュールのインストール
#### パッケージのアップデートとアップグレード
```
sudo apt update
sudo apt upgrade
```
#### python-ctypeインストール
```
sudo apt-get install libffi-dev
```

#### OpenSSL Development Packegeをインストールする。
opensslは最初からインストールされていますが、開発パッケージがありません。これをインストールする。
```
sudo apt-get install libssl-dev
```
#### そのほかのモジュールのインストール
```
sudo apt-get install libbz2-dev
sudo apt-get install libreadline-dev
sudo apt-get install libsqlite3-dev
sudo apt-get install libncurses5-dev
sudo apt-get install libncursesw5-dev
sudo apt-get install tk-dev
sudo apt-get install liblzma-dev
sudo apt-get install libgdbm-dev
sudo apt-get install libdb-dev
```
（参考）https://blog.amedama.jp/entry/2018/08/25/134642

### Pythonのインストール
#### ソースBuild用のワークフォルダを作成する。
大量のファイルが展開されるのでワークフォルダを作成してそこで作業します。ここではユーザーフォルダの下にdevフォルダを作成してそこへ移動します。
```
mkdir ~/dev
cd dev
```
#### pythonのソースのダウンロード～展開
Pythonのソースはここにあります。最新Verのリンクへ飛んで"Gipped source tarball"のリンクをコピーしてください。記載時点の最新Verは3.12.4です。
https://www.python.org/downloads/source/
下のコマンドでファイルを取得してください。https:~が上記でコピーしたリンクです。
```
wget https://www.python.org/ftp/python/3.12.4/Python-3.12.4.tgz
```
ファイルを展開して、そのフォルダへ移動
```
tar xvzf Python-3.12.4.tgz
cd Python-3.12.4
```
#### Pythonのビルド前の事前準備
Buildをする前にopensslのリンク設定をします。Setupファイルを編集します。
```
nano Module/Setup
```
以下を#を削除してアンコメントします。
【変更前】
```
#_socket socketmodule.c

# To statically link OpenSSL:
# _ssl _ssl.c $(OPENSSL_INCLUDES) $(OPENSSL_LDFLAGS) \
#    -l:libssl.a -Wl,--exclude-libs,libssl.a \
#    -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a
# _hashlib _hashopenssl.c $(OPENSSL_INCLUDES) $(OPENSSL_LDFLAGS) \
#    -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a
```
【変更後】
```
_socket socketmodule.c

# To statically link OpenSSL:
 _ssl _ssl.c $(OPENSSL_INCLUDES) $(OPENSSL_LDFLAGS) \
    -l:libssl.a -Wl,--exclude-libs,libssl.a \
    -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a
 _hashlib _hashopenssl.c $(OPENSSL_INCLUDES) $(OPENSSL_LDFLAGS) \
    -l:libcrypto.a -Wl,--exclude-libs,libcrypto.a
```
編集したらctrl+xで保存終了してください。
（参考）
https://techglimpse.com/install-python-openssl-support-tutorial/
https://qiita.com/KBT777/items/2ae15faa4b8c7101d6f1

#### Pythonのビルド～インストール
ビルド用のMakeFile作成、オプティマイズはします。
```
./configure --enable-optimizations
```
ビルドの実行。sudoは不要で行けるはずです（sudoは付けない方が良い気がします。付けた時にOSが不安定になった気がした。単なる感触で確証無し、根拠無し）。ビルドの際にログを残します。

```
make 2>&1 | tee make.log
```
ビルド完了時のモジュールのワーニング、あるけどダメみたいのは残ってしまいます。この影響や解決法がわかる方はコメントお願いします。
```
[ERROR] -l:libcrypto.a failed to import: '-l:libcrypto.a' is not a built-in module
[ERROR] Cannot mark builtin module '-l:libcrypto.a' as failed!
[ERROR] -l:libssl.a failed to import: '-l:libssl.a' is not a built-in module
[ERROR] Cannot mark builtin module '-l:libssl.a' as failed!
Following modules built successfully but were removed because they could not be imported:
-l:libcrypto.a        -l:libssl.a

Checked 113 modules (31 built-in, 79 shared, 1 n/a on linux-aarch64, 0 disabled, 0 missing, 2 failed on import)
```
インストールの実行
```
sudo make install
```
インストール完了時の最後のワーニング。pipでモジュールをインストールする際rootではなく仮想環境を作りそこにインストールすることが推奨。さもなくばシステムとコンフリクトして不具合を起こすかも。といった感じかな
```
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
```

## インストール結果確認
### PythonのVersion確認
```
python3 -V
#Python 3.12.4
```
Version 3.12.4がインストールされています。
### pipの確認を兼ねてpipのアップグレード
```
pip3 install --upgrade pip
#Successfully installed pip-24.2
```
pipが無事動作して24.0 -> 24.2へアップグレードされました。

### デバッグ動作確認(VScode)
Windows PCのVScodeからリモートでRaspberry Piへ入り適当な.pyファイルを作成。インタープリターをインストールしたPython Versionへ変更することを忘れずに！。その後簡単なコードを記入してデバッグ。
```
print("Hello World!")
# Hello World!
```
無事動作することを確認

## まとめ
Python3の最新VerをRaspberry Piへインストールする際に
- 事前に不足モジュールのインストールが必要
- 不足モジュールのインストール後のビルドで完全にエラーを取り除けていないが、不足モジュールのワーニングは解消
- pipとVScodeでのデバッグまでは動作確認済

もっと良い方法やビルドで解消していないエラーの解決方法があればコメントお願いします。私の方での調べてみて何か分かれば更新していきます。