Closed2

M1 Mac Python incompatible エラー、pyenv install でコケる

koshilifekoshilife

M1 Macを使ってPythonアプリを開発している。
以下のエラーで、XCode再インストール3往復したり、複数Pythonバージョンを試したり、3,4時間溶かしたので備忘。

環境

Mac

$ pyenv -v
pyenv 2.2.5-50-gbc13a87b

エラー1: incompatible architecture エラー

インストールした依存ライブラリのM1 MacのCPUアーキテクチャ互換性がない系のエラー。

$ python
Python 3.9.10 (main, Apr  8 2022, 17:34:18) 
[Clang 13.1.6 (clang-1316.0.21.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import lxml.etree
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dlopen(/YOUR_PATH/venv/lib/python3.9/site-packages/lxml/etree.cpython-39-darwin.so, 0x0002): tried: '/YOUR_PATH/venv/lib/python3.9/site-packages/lxml/etree.cpython-39-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))

ライブラリをuninstall/installをしても解消せず。

$ pip uninstall lxml
$ pip install lxml
Collecting lxml
  Using cached lxml-4.9.0-cp39-cp39-macosx_12_0_arm64.whl
Installing collected packages: lxml
Successfully installed lxml-4.9.0

よく見てみると、

Using cached lxml-4.9.0-cp39-cp39-macosx_12_0_arm64.whl

Using cached キャッシュが使われているようだ。

https://qiita.com/MasanoriMT/items/57a6e6d5ffbeabacf518

を参考に --no-cache-dir オプションを使ったら、lxml-4.9.0.tar.gz をダウンロードしてビルドが走り、エラーが出ない状態でインストールされた。
(憶測だが、ローカルのビルド環境不備だった時に作った成果物が使われていたのかな?)

$ pip --no-cache-dir install lxml
Collecting lxml
  Downloading lxml-4.9.0.tar.gz (3.4 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.4/3.4 MB 28.8 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Using legacy 'setup.py install' for lxml, since package 'wheel' is not installed.
Installing collected packages: lxml
  Running setup.py install for lxml ... done
Successfully installed lxml-4.9.0

$ python 
Python 3.9.13 (main, Jun  6 2022, 18:47:36) 
[Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import lxml.etree
>>> 

エラー2: pyenv Python指定バージョンのインストールでこける

$ pyenv install 3.10.4
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.10.4.tar.xz...
-> https://www.python.org/ftp/python/3.10.4/Python-3.10.4.tar.xz
Installing Python-3.10.4...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk

BUILD FAILED (OS X 12.4 using python-build 2.2.5-50-gbc13a87b)

Inspect or clean up the working tree at /var/folders/pm/303vzkdd2m91nf6y525y7ddc0000gn/T/python-build.20220606210307.53171
Results logged to /var/folders/pm/303vzkdd2m91nf6y525y7ddc0000gn/T/python-build.20220606210307.53171.log

Last 10 log lines:
  "_libintl_textdomain", referenced from:
      __locale_textdomain in libpython3.10.a(_localemodule.o)
      __locale_textdomain in libpython3.10.a(_localemodule.o)
ld: symbol(s) not found for architecture x86_64
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Programs/_testembed] Error 1
make: *** Waiting for unfinished jobs....
make: *** [python.exe] Error 1

Inspect or clean up the working tree at /var/folders/pm/303vzkdd2m91nf6y525y7ddc0000gn/T/python-build.20220606100642.79120
Results logged to /var/folders/pm/303vzkdd2m91nf6y525y7ddc0000gn/T/python-build.20220606100642.79120.log

$ less /var/folders/pm/303vzkdd2m91nf6y525y7ddc0000gn/T/python-build.20220606100642.79120.log
 (抜粋)
ld: warning: ld: warning: directory not found for option '-L/<YOUR_HOME>/.pyenv/versions/3.10.4/lib'
directory not found for option '-L/<YOUR_HOME>/.pyenv/versions/3.10.4/lib'
ld: warning: directory not found for option '-L/<YOUR_HOME>/.pyenv/versions/3.10.4/lib'
ld: warning: directory not found for option '-L/<YOUR_HOME>/.pyenv/versions/3.10.4/lib'
Undefined symbols for architecture x86_64:
  "_libintl_bindtextdomain", referenced from:
Undefined symbols for architecture x86_64:
  "_libintl_bindtextdomain", referenced from:
      __locale_bindtextdomain in libpython3.10.a(_localemodule.o)
      __locale_bindtextdomain in libpython3.10.a(_localemodule.o)
  "_libintl_dcgettext", referenced from:
  "_libintl_dcgettext", referenced from:
      __locale_dcgettext in libpython3.10.a(_localemodule.o)
      __locale_dcgettext in libpython3.10.a(_localemodule.o)
  "_libintl_dgettext", referenced from:
  "_libintl_dgettext", referenced from:
      __locale_dgettext in libpython3.10.a(_localemodule.o)
      __locale_dgettext in libpython3.10.a(_localemodule.o)
  "_libintl_gettext", referenced from:
  "_libintl_gettext", referenced from:
      __locale_gettext in libpython3.10.a(_localemodule.o)
      __locale_gettext in libpython3.10.a(_localemodule.o)
  "_libintl_setlocale", referenced from:
  "_libintl_setlocale", referenced from:
      __locale_setlocale in libpython3.10.a(_localemodule.o)
      __locale_localeconv in libpython3.10.a(_localemodule.o)
      __locale_setlocale in libpython3.10.a(_localemodule.o)
      __locale_localeconv in libpython3.10.a(_localemodule.o)
  "_libintl_textdomain", referenced from:
  "_libintl_textdomain", referenced from:
      __locale_textdomain in libpython3.10.a(_localemodule.o)
      __locale_textdomain in libpython3.10.a(_localemodule.o)
ld: symbol(s) not found for architecture x86_64
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Programs/_testembed] Error 1
make: *** Waiting for unfinished jobs....
make: *** [python.exe] Error 1

インストールが失敗した時の uname -m の出力が x86_64になっていた。(VSCode内のterminal)

$ uname -m
x86_64

Terminal.app で立ち上げたシェルを用いた時は pyenv install が成功した。その時の uname -m の結果は arm64 であった。

$ uname -m
arm64

Terminal.app を Open using Rosetta を有効にして起動すると uname -m 結果が x86_64 になる。
その時は pyenv install がコケた。Rosetta 利用有無が成否に関わっているっぽい。(これ以上、深追いはしていない)

uname -m コマンドは以下を参考にした

https://zenn.dev/hisasann/articles/m1-macbook-pro-setup

エラー3: python 2.7.18 入れるときに openssl1.0 じゃないのとエラーになる

2.7をセットアップする必要があり、pyenv install 2.7.18 でこけた。
元々入っていた openssl@3 openssl@1.1 を消してから pyenv install 2.7.18 で自動でopenssl@1.0 がインストールされ、2.7.18 をインストールできた。その後 openssl@3, openssl@1.1 は再度インストールしとく。

参考: https://qiita.com/hogesuke_1/items/2cdb069dbe99a2f1bd79

私の環境でこのエラーが発生していた原因は、homebrewでインストールされているOpenSSLのバージョンが1.0系でないことが原因でした。Python 2系のインストールにはOpenSSL 1.0系が必要になります。

koshilifekoshilife

おまけ: 新規Python環境作る時の汎用コマンド

Pythonアプリをcloneして指定Pythonバージョンで依存ライブラリを取得するまでのコマンド。

# 動かしたいアプリを持ってくる
$ git clone XXX/python-foobar.git
$ cd python-foobar

# Python 3.10.4 で動かすことに。
$ pyenv local 3.10.4
$ python --version

# 仮想環境作る
$ python -m venv venv
$ source venv/bin/activate

# 依存ライブラリインストール前にpip自身を更新 & wheel インストール
$ pip install --upgrade pip
$ pip install wheel

# 依存ライブラリインストール時はキャッシュ使わない
$ pip --no-cache-dir install -r requirements.txt

# 用が済んだら仮想環境から出る
$ deactivate
このスクラップは2022/06/06にクローズされました