anyenv の pyenv でインストールした python で tkinter が使えなかった

この症状で検索すると 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` をインストール

```zsh
brew install tcl-tk
```

で、環境変数に色々追加。

```zsh:.zshrc
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` でバージョンとか見られるみたいです（今日知った）

```zsh
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` を指定すればよさそうですね。

（一応見てみた）

```zsh
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` に追記します。

```zsh:.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 を新規でインストールしようとおもいます。
（うまくいったら入れ直す感じで）

```zsh
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
```

んで、グローバルバージョンを切り替え

```zsh
pyenv global 3.8.5
python -V
Python 3.8.5
```

ではいざ。

```zsh
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` も足してあげるとうまくいったという[意見があった](https://stackoverflow.com/questions/60469202/unable-to-install-tkinter-with-pyenv-pythons-on-macos#comment112082121_61879759) ので、それをためしてみます。

```diff
- 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 再インストール

```zsh
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` 打ってエラーがないことも見たほうが良いというので、それもやってみる。

```zsh
idle
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25724/e467faf4-865d-03f8-1116-bca95ef29bdb.png)

大丈夫そう。

では、あらためて。

```zsh
python -m tkinter -c "tkinter._test()"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25724/a991b2a9-8996-998f-b117-02a450334d64.png)

ようやく成功です。やったー！

## まとめ

よく知られている方法でも tkinter が使えない場合は、ビルドのオプションに `--enable-shared` を足してみると良いかもしれません。

## 参考

- https://stackoverflow.com/questions/60469202/unable-to-install-tkinter-with-pyenv-pythons-on-macos#comment112082121_61879759