この症状で検索すると Qiita にもいくつか記事が見つかるのですが、なぜかうまく行かず、いろいろと試行錯誤したのでメモ。
TL;DR
-
tcl-tk
がなければbrew install tcl-tk
で入れる -
PYTHON_CONFIGURE_OPTS
を書いてるのに改善しない場合は、tcl-tk のバージョン確認して適切なバージョンが書かれているか確認する - ↑でもだめだったら、末尾に
--enable-shared
足してみる
環境
Mac Book Pro
macOS Catalina 10.15.7
anyenv anyenv 1.1.2-1-g67d402f
pyenv 1.2.21
なにがおきていたのか。
他の記事でも見かける tkinter が動かない。
さくっと解決できると思ってたため、ターミナルのログをメモってませんでしたが、他の記事で見かけるようなのとだいたい同じやつでした。
ためしたこと
Homebrew で tcl-tk
をインストール
brew install tcl-tk
で、環境変数に色々追加。
export PATH="/usr/local/opt/tcl-tk/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
更に、python をビルドするときのオプションPYTHON_CONFIGURE_OPTS
を .zshrc に追加しますが、
このとき、 tcl-tk のバージョンは、Homebrew で入れたやつのバージョンに合わせる必要があるので、確認しておきます。
Homebrew で入れたパッケージは brew info
でバージョンとか見られるみたいです(今日知った)
brew info tcl-tk
tcl-tk: stable 8.6.10 (bottled) [keg-only]
Tool Command Language
https://www.tcl-lang.org
/usr/local/Cellar/tcl-tk/8.6.10 (3,036 files, 51MB)
Poured from bottle on 2020-11-09 at 10:51:55
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/tcl-tk.rb
License: TCL
==> Dependencies
Required: openssl@1.1 ✔
==> Caveats
tcl-tk is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have tcl-tk first in your PATH run:
echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' >> ~/.zshrc
For compilers to find tcl-tk you may need to set:
export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
For pkg-config to find tcl-tk you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
==> Analytics
install: 8,020 (30 days), 24,799 (90 days), 101,382 (365 days)
install-on-request: 4,416 (30 days), 13,662 (90 days), 53,123 (365 days)
build-error: 0 (30 days)
8.6.10 らしいので、この場合、 tcl8.6
と tk8.6
を指定すればよさそうですね。
(一応見てみた)
ls /usr/local/opt/tcl-tk/lib
Tk.icns libtk8.6.dylib tclConfig.sh tdbcmysql1.1.1
Tk.tiff libtkstub8.6.a tcllib1.20 tdbcodbc1.1.1
itcl4.2.0 pkgconfig tcllibc tdbcpostgres1.1.1
itk4.1.0 sqlite3.30.1.2 tclooConfig.sh thread2.8.5
libtcl8.6.dylib tcl8 tcltls1.7.20 tk8.6
libtclstub8.6.a tcl8.6 tdbc1.1.1 tkConfig.sh
ってことで、.zshrc
に追記します。
export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'"
で、設定を読み直させます。 . ~/.zshrc
でも、 source ~/.zshrc
でも、ターミナル開き直し
でも、お好きな方法で。
それが済んだら、python 再インストールをします。
…ただまぁ、ずっと放置してたので入ってるハージョンが 3.7.4 と古めのものだったので、ここは 3.8.5 を新規でインストールしようとおもいます。
(うまくいったら入れ直す感じで)
pyenv install 3.8.5
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.8.5.tar.xz...
-> https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tar.xz
Installing Python-3.8.5...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.8.5
んで、グローバルバージョンを切り替え
pyenv global 3.8.5
python -V
Python 3.8.5
ではいざ。
python -m tkinter -c "tkinter._test()"
(中略)
RuntimeError: tk.h version (8.6) doesn't match libtk.a version (8.5)
あっれー?
みんなこれでうまく行ったって言ってるのに。
更に検索する
Google で更に検索してみると、どうも、PYTHON_CONFIGURE_OPTS
を設定する際に、 --enable-shared
も足してあげるとうまくいったという意見があった ので、それをためしてみます。
- export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'"
+ export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6' --enable-shared"
で、あらためて、 .zshrc
をリロードして、python 再インストール
pyenv uninstall 3.8.5
pyenv: remove /Users/*****/.anyenv/envs/pyenv/versions/3.8.5? [y|N]y
pyenv: 3.8.5 uninstalled
pyenv install 3.8.5
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.8.5.tar.xz...
-> https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tar.xz
Installing Python-3.8.5...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.8.5
なにやら、 idle
打ってエラーがないことも見たほうが良いというので、それもやってみる。
idle
大丈夫そう。
では、あらためて。
python -m tkinter -c "tkinter._test()"
ようやく成功です。やったー!
まとめ
よく知られている方法でも tkinter が使えない場合は、ビルドのオプションに --enable-shared
を足してみると良いかもしれません。