初夏の都に佇む遺物をAIツールで掘り返す 〜 古いOSで新しめのPythonを使いたかった

こんにちは。株式会社ユーザベース スピーダ事業の酒井です。

2年前、こんな概要のブログ記事を下書き保存して、公開を忘れて寝かせ続けていました。(1年前思い出して、バージョン更新した記事を修正して再度寝かせていた)

サーバを整理していたところ、その中からCentOS 6が掘り出されたため、Cloud Storage(GCS)へファイルをアップロードして終了させました。
その際Google Cloud CLIを使うために新しめのPythonを用意する必要があり、出来るだけ手間を掛けずゴニョゴニョしようという記事になります。

当時、GeminiやPerplexityなどのAIツールで調査を行ってもうまく対処する方法が見当たらなかった記憶があり、記事内容としてはPythonの公式ドキュメントを読めば解決、最高!という事と、昔こんな対処したかもみたいな経験則からの知見で補足した内容となっていました。

2年たった今AIツールで上記の課題は一発解決してくれるようになったのか、下書きのまま腐らせていた記事をお焚き上げしようというのが今回の内容となります。

2年前の記事の要約

寝かせていた記事ではPython3.10を使おうとしており、それらに関連するパッケージ類をソースコードビルドするための注意をまとめていました。
(以下、基本的にはPythonの公式ドキュメントをよく読んでいくと書かれている内容と、OpenSSLのlibパスの所だけ以前こんな対応が必要なケースがあったなあという経験から記載していました)

最終的なPython 3.10のビルドオプション(2年前の内容)

CPPFLAGS="-I/usr/local/sqlite-3.49.2/include" LDFLAGS="-L/usr/local/sqlite-3.49.2/lib" ./configure --enable-optimizations --with-openssl=/usr/local/openssl-3.5.0 --with-openssl-rpath=auto --enable-loadable-sqlite-extensions

LD_RUN_PATH="/usr/local/sqlite-3.49.2/lib" make

make altinstall

OpenSSLの独自ビルド(2年前の内容)

次に「バージョン 3.10 で変更: OpenSSL 1.1.1 is now required.」との記載があるため、LTSになっていたOpenSSL 3.5.0をソースビルドして独自のパスにインストールをしています。

./config --prefix=/usr/local/openssl-3.5.0

ちょうどPython 3.10で独自パスに展開したopensslを参照するをサポートするためのオプションが加わっているので指定。

--with-openssl=/usr/local/openssl-3.5.0 --with-openssl-rpath=auto

https://docs.python.org/ja/3.10/using/configure.html#cmdoption-with-openssl-rpath

インストールパス先を覗くと、lib64は存在しているが、libが存在していない。
ライブラリを探す際にlibを優先して見るようなので、シンボリックリンクを貼っておく。

# ls /usr/local/openssl-3.5.0
bin  include  lib64  share  ssl
# cd /usr/local/openssl-3.5.0
# ln -s lib64 lib

SQLiteの独自ビルド(2年前の内容)

またgcloudコマンドを呼び出す際に、Pythonのsqliteモジュールが組み込まれていることもチェックされるので必要なオプションを指定。

--enable-loadable-sqlite-extensions

CentOS6に入っているsqliteは3.6.20となっていて、Pythonが求めるバージョンを満たさないのでこちらも独自にソースビルドしてインストールしています。

./configure --prefix=/usr/local/sqlite-3.49.2

https://docs.python.org/ja/3.10/library/sqlite3.html#module-sqlite3

PEP 249 に記述された DB-API 2.0 仕様に準拠した SQL インターフェースを提供し、SQLite 3.7.15 以降が必要です。

Pythonのビルドフラグ(2年前の内容)

またPythonのドキュメントには独自パスにライブラリなどを展開した場合には、CPPFLAGSとLDFLAGSを付けるという説明があります。

Both CPPFLAGS and LDFLAGS need to contain the shell's value to be able to build extension modules using the directories specified in the environment variables.

https://docs.python.org/ja/3.10/using/configure.html#envvar-CPPFLAGS https://docs.python.org/ja/3.10/using/configure.html#envvar-LDFLAGS

こんな感じ。

CPPFLAGS="-I/usr/local/sqlite-3.49.2/include" LDFLAGS="-L/usr/local/sqlite-3.49.2/lib"

AIツールで掘り返す

前置きが長くなりましたが、この2年間のAIツールの進化を試してみたいと思います。 ツールとしては手元の Claude Code 2.1.185 (Opus 4.8 / "autoMemoryEnabled": false) を使って調査を行いました。

プロンプトは凝らずに普通に問い合わせています。

CentOS 6 x86_64 で Google Cloud CLI 523.0.1 のバージョンを動かしたい。
Python 3.10.7 をソースコードからビルドし、 同じくソースコードからビルドした OpenSSL 3.5.0 と SQLite 3.49.2 のライブラリ(gcloudコマンドを呼び出す際に、Pythonのsqliteモジュールが組み込まれていることもチェックされる)を参照するようにしたい。
この Python 3.10.7 をビルドするためのコマンドを調査。

観点としては「PythonビルドでOpenSSLとSQLiteがモジュール組込されているか」という目的で以下のような感じで見ています。
「OpenSSLのビルド時のlib64の扱い」
「SQLiteをPythonビルド時にリンクする扱い」

結果は2勝1敗(ほぼ3勝)

3回調査プロンプトを実行した所、「OpenSSLのビルド時のlib64の扱い」 で1回だけlib64とlib周りの扱いが考慮されずに提示されたためOpenSSLのモジュールが参照できないエラーとなりましたが、これもエラーメッセージを提示して再調査させた所、libパスの扱いに言及した修正案を提示してくれました。

❯ pythonをビルドしていた所、以下のエラーが出ました、解決方法を調査

  Following modules built successfully but were removed because they could not be imported:
  _hashlib              _ssl


  最有力原因: lib と lib64 の食い違い

  OpenSSL 3.x を ./Configure linux-x86_64 で素直にビルドすると、ライブラリが lib ではなく lib64 にインストールされることがよくあります。一方
  --with-openssl-rpath=auto が埋め込む rpath は .../lib を向くため、実行時に libssl.so.3: cannot open shared object file となって今回の症状が出ます。

  一番きれいなのは OpenSSL を lib 固定で入れ直すことです。

AIツールが提示してくれた模範解答の抜粋

「OpenSSLのビルド時のlib64の扱い」 について、lib64部分をきちんと説明して対処しているコメントが付いている。

--libdir=lib を明示(指定しないと lib64 に入り、Python 側の探索とずれる原因になる)

  ./Configure linux-x86_64 \
      --prefix=/opt/openssl-3.5.0 \
      --openssldir=/opt/openssl-3.5.0/ssl \
      --libdir=lib \
      shared zlib

「SQLiteをPythonビルド時にリンクする扱い」 について、 2年前の自分の対応だと LD_RUN_PATH="/usr/local/sqlite-3.49.2/lib" make としている部分を、 -Wl,-rpath,/opt/sqlite-3.49.2/lib で吸収している。

  ./configure \
    --prefix=/opt/python-3.10 \
    --enable-optimizations \
    --with-ensurepip=install \
    --with-openssl=/opt/openssl-3.5.0 \
    --with-openssl-rpath=auto \
    CPPFLAGS="-I/opt/sqlite-3.49.2/include" \
    LDFLAGS="-L/opt/sqlite-3.49.2/lib -Wl,-rpath,/opt/sqlite-3.49.2/lib -Wl,-rpath,/opt/openssl-3.5.0/lib"

まとめ

2年弱の年月は、きちんとAIツールの進化を感じさせてくれて、ニッチな知見に答えてくれる状態を実現してくれました。
この寝かせて腐っていた記事も感謝の祈りを込めて供養されてくれたと思います。

🎓 学生の方へ | 1day インターンイベント開催!

Speeda ソフトウェアエンジニア職 のインターンイベントを開催します!

Speedaプロダクトチームではアジャイル開発手法の一種であるXP(エクストリームプログラミング)を実践しており、今回のインターンではプラクティスの中でも特徴的なペアプログラミングをみなさんに体験していただきます!

チーム開発を更に深めることができるペアプログラミングの経験は我々の文化を体験することや、今後のエンジニアとしての活動の幅を広げるきっかけになると思います。

少しでもご興味をお持ちいただけた方は、ぜひお気軽にエントリーください。

エントリーはこちら!

Page top