Zenn
🐍

【M2 Mac】pyenv環境構築でハマった話 (BUILD FAILED)

2024/12/25に公開

【M2 Mac】pyenv環境構築でハマった話 (BUILD FAILED)

こんにちは!今回は、私がM2 MacBook Proでpyenvの環境構築をしようとした際にどハマりした話を、同じように苦しむ未来の誰かのために記事としてまとめてみました!

この記事のベースは,環境構築時に書いたメモをもとにchatGPTに書かせたものです.


目次

  1. TL;DR
  2. はじめに
  3. M2 Macにおけるpyenvでのハマりポイント
  4. 発生したエラー
  5. 試したこと(そして失敗したこと)
  6. 成功した解決方法
  7. まとめ
  8. Tips

0. TL;DR

  1. 必要なツールのインストール
brew install readline openssl zlib xz
brew install pyenv pyenv-virtualenv
  1. pythonのインストール
PYTHON_CONFIGURE_OPTS="--host=arm-apple-darwin --build=arm-apple-darwin" \
CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include -I$(brew --prefix zlib)/include -I$(brew --prefix xz)/include -arch arm64" \
LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix xz)/lib -arch arm64" \
pyenv install -v 3.8.10

1. はじめに

最近では大体のものはM1,M2,M3でも問題なく動くようになってきていますが,今回python(pyenv)の環境構築で盛大にハマってしまいました。この記事では、その過程と最終的な解決方法を紹介します!


2. M2 Macにおけるpyenvでのハマりポイント

最初に、今回苦労した要因を整理してみます。

  • M2チップのアーキテクチャ(arm64) と、一部のツールが前提としているx86_64アーキテクチャの不一致。
  • 必要なライブラリやコンパイルオプションが適切に設定されていないとエラーが発生。
  • エラーログが難解(長すぎる)で、原因の特定が難しい。

3. 発生したエラー

以下のコマンドでpyenvをインストール

brew install pyenv pyenv-install

以下のコマンドでpythonをインストールしようとしました.

pyenv install 3.8.10

結果は大体こんな感じ↓(実際は結構長い)

python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.8.10.tar.xz...
-> https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tar.xz
Installing Python-3.8.10...
patching file 'Misc/NEWS.d/next/Build/2021-10-11-16-27-38.bpo-45405.iSfdW5.rst'
patching file configure
patching file configure.ac
python-build: use tcl-tk from homebrew
python-build: use readline from homebrew
python-build: use zlib from xcode sdk

BUILD FAILED (OS X 15.2 using pythonInspect or clean up the working tree at 
-build 20180424)
/var/folders/6q/7ttwkyjn64j31_6b3880458w0000gn/T/python-build.20241225001841.21992
Results logged to /var/folders/6q/7ttwkyjn64j31_6b3880458w0000gn/T/python-build.20241225001841.21992.log
.....

4. 試したこと(そして失敗したこと)

問題解決のために行った試行錯誤をいくつか紹介します。

(1) インターネットでの情報収集

まずはネットの海を泳ぎました。
同じようなエラーの方はたくさん見つかり,手当たり次第に試してみたが自分に効くものがなかなか見つからず,,

(2) XcodeとComand Line Toolsの再インストール

参考にした記事はこちら: Xcode Command Line Tools の再インストール
https://qiita.com/ikura_ooo/items/c003096abe4abcf5f209

結果としては上手くいかず.しかし,最終的に成功したコマンドをこれを行う前の環境で行なっていないので意味がなかったかは分からない.

(3) Homebrewの再インストールと必要なツールのインストール

参考にした記事はこちら: 【IT】M1 MacBookでのpyenvの再導入
https://note.com/t_ak66/n/nc251eaef6523

まずはHomebrewを再インストール.その後以下のツールをインストール

brew install openssl readline sqlite3 xz zlib tcl-tk libjpeg
brew install coreutils
brew install pyenv

結果は失敗…。

(4) SDKROOTを指定

参考にした記事はこちら: PyEnv BUILD FAILED installing Python on MacOS
https://stackoverflow.com/questions/51551557/pyenv-build-failed-installing-python-on-macos

パスを直して以下のコマンドを実行

SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk MACOSX_DEPLOYMENT_TARGET=15.2 pyenv install 3.8.10

これも上手くいかず,,,

(5) ログファイルをしっかり見る.

なぜ今までやらなかったのかという話だが,エラーログに以下のメッセージがあることにお気づきだろうか.

Results logged to /var/folders/6q/7ttwkyjn64j31_6b3880458w0000gn/T/python-build.20241225001841.21992.log

以下の記事を見てログファイルをちゃんと見ようと思った.

pyenvでpythonのインストールに失敗する
https://zenn.dev/r_tamura/scraps/1668ac8ad203d0

この方は自分とは状況が少し違うが,ログをちゃんと見ていたので参考にした.

(6) ChatGPTと壁打ち無限ループ

ログファイルは1万行以上あったが,エラーが出てるのは大体最後の方なので最後までジャンプ.(Vimmerにとっては簡単ですね)

一応ターミナルでログファイルを見るのに慣れていない人のために

vi <ログファイルのパス>

viではG と入力すれば一番最後の行へ飛べます.終了するときは

:q

で出れます.(知らないと一生出られません.)

これ以降はエラーをChatGPTに渡し,その答えと検索で出たものを混ぜながら試行錯誤.

5. 成功した解決方法

最終的に成功したのは、環境変数とコンパイルオプションを適切に設定することでした. ログファイルの先頭の方に以下の2行がありました.(エラーメッセージばかり見てて盲点)

checking build system type... x86_64-apple-darwin24.2.0
checking host system type... x86_64-apple-darwin24.2.0

なぜかx86_64向けにビルドしようとしていて,ホストもx86_64になってますね.

自分の状況とは少し違うが, 以下のissueを見てx86_64が対象になっている可能性とその証拠となるログの場所を知ることができた.

Problem when installing Python on m1 processor: "dyld: missing symbol called"
https://github.com/pyenv/pyenv/issues/2705#issuecomment-1567400897

ChatGPTともたくさん相談して,最終的に以下のコマンドを実行して、無事にPythonをインストールできました.

PYTHON_CONFIGURE_OPTS="--host=arm-apple-darwin --build=arm-apple-darwin" \
CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include -I$(brew --prefix zlib)/include -I$(brew --prefix xz)/include -arch arm64" \
LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix xz)/lib -arch arm64" \
pyenv install -v 3.8.10

ポイント

  1. PYTHON_CONFIGURE_OPTS: ホストとビルドシステムをarm-apple-darwin に明示。
  2. CFLAGSLDFLAGS : 必要なライブラリのパスを正確に指定し、-arch arm64 を追加。

自分の環境だとこれらを省略するとエラーが発生するため、全てが必要でした.

6. まとめ

まとめると, おそらく以下の手順で出来そうです.

  1. 必要なツールのインストール
brew install readline openssl zlib xz
brew install pyenv pyenv-virtualenv
  1. pythonのインストール
PYTHON_CONFIGURE_OPTS="--host=arm-apple-darwin --build=arm-apple-darwin" \
CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include -I$(brew --prefix zlib)/include -I$(brew --prefix xz)/include -arch arm64" \
LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix xz)/lib -arch arm64" \
pyenv install -v 3.8.10

ハマりポイントは多いですが、この記事が参考になれば幸いです!

Tips

1. 環境変数について

色々な記事で環境変数を

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/shims:$PATH"

こんな感じで設定しているのですが,

自分はzshなので.zprofile

eval "$(pyenv init --path)"

.zshrc

eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

と書けば不要なのではないかと思う.試しにシェルで以下を実行する.

pyenv init -

実行結果:

PATH="$(bash --norc -ec 'IFS=:; paths=($PATH);
for i in ${!paths[@]}; do
if [[ ${paths[i]} == "''/Users/username/.pyenv/shims''" ]]; then unset '\''paths[i]'\'';
fi; done;
echo "${paths[*]}"')"
export PATH="/Users/username/.pyenv/shims:${PATH}"
export PYENV_SHELL=zsh
source '/opt/homebrew/Cellar/pyenv/2.5.0/completions/pyenv.zsh'
command pyenv rehash 2>/dev/null
pyenv() {
  local command=${1:-}
  [ "$#" -gt 0 ] && shift
  case "$command" in
  activate|deactivate|rehash|shell)
    eval "$(pyenv "sh-$command" "$@")"
    ;;
  *)
    command pyenv "$command" "$@"
    ;;
  esac
}

以下も実行してみる.

pyenv init --path

実行結果:

PATH="$(bash --norc -ec 'IFS=:; paths=($PATH);
for i in ${!paths[@]}; do
if [[ ${paths[i]} == "''/Users/username/.pyenv/shims''" ]]; then unset '\''paths[i]'\'';
fi; done;
echo "${paths[*]}"')"
export PATH="/Users/username/.pyenv/shims:${PATH}"
command pyenv rehash 2>/dev/null

このように環境変数が埋め込まれているので手動でやらずともパスは通っている.(実際自分の環境では手動で書いていないがパスは通ってる)

2. pyenv virtualenv-init - を実行するとシェルがめちゃくちゃ重くなる現象への対処

pyenv virtualenv-init - を実行したらシェルがとんでもないくらい重くなり困っていましたが,以下の記事で解決

pyenv-virtualenv initでプロンプト表示速度が低下する問題
https://nsakki55.hatenablog.com/entry/2024/02/06/093756

結論から言えば以下のシェルで緩和されます.

eval "$(pyenv virtualenv-init - | sed s/precmd/chpwd/g)"

これで普段のプロンプト表示は早くなりますが,cd をした時のみかなり遅いです.これはvirtualenvがカレントディレクトリを見て仮想環境をactivateする処理が走っているからです.

長くなりましたが,最後まで読んでいただきありがとうございました!もしこの記事が役に立ったら、ぜひ「いいね」や「シェア」をお願いします😊

Discussion

ログインするとコメントできます