wsl2 で homebrew ベースで python 実行環境 (by pyenv) を揃える最小手順

## こんにちは

WindowsでのPython環境導入は[多数ありすぎて](https://qiita.com/hkzm/items/1f00caf199ea059ee800)迷いませんか。私は迷いました。そこでタイトル通り、wsl2 内の homebrew ベースで python, R 環境 を揃える最小手順のメモを残すこととしました。手順が再現しない等の場合はコメントにてやりとりできれば嬉しい限りです。

## この記事を書いた背景

- Windows環境でPythonを動かすためには、さまざまな方法がある（参考: [Windows 10 での Python 汚染に気を付けよう](https://qiita.com/hkzm/items/1f00caf199ea059ee800) )
- 自分メインの開発環境は pyenv & poetry with docker on Mac なので、これに追随するためには WSL2 環境一択
- 趣味として Ubuntu 上で homebrew をフル活用していきたい

## 実行環境

1. WSL2のインストール、およびそのイメージの Ubuntuのインストール、 wsl conf などの設定は [microsoft のページ](https://docs.microsoft.com/ja-jp/windows/wsl/setup/environment)を参照し、設定済みとする
    - なお `Ubuntu 20.04` の前提です。Windows 11 ビルド 22000 以上 での [GUI (vGPU) の設定](https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/gui-apps)こちら。
2. 以下は Windows Terminal 上の Ubuntu-20.04 で実行

## 30秒で結論

ハマりポイントは、デフォルトでは `gcc` を ubuntu 側のものを認識してしまうので、明示的に brew側の `gcc-11` を指定することが必要だった。

### Homebrew (Linuxbrew) の準備

- [公式インストール通り](https://docs.brew.sh/Homebrew-on-Linux)
- Ubuntu & bash なので .profile を使用する

```sh
sudo apt update && sudo apt upgrade
# 公式では `sudo apt-get install build-essential procps curl file git` だったが、 `build-essential` だけで問題なかった
sudo apt-get install build-essential
```

```sh
# install homebrew, taking a few minutes
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# add to profile
echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.profile
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
```


## python install

- brewで導入したpyenvを経由してpythonをインストールする

### pyenv install by linuxbrew

```sh
brew install gcc # for gcc-11
brew install sqlite
```

N.B. [Linuxbrew で build](https://github.com/pyenv/pyenv/wiki#:~:text=devel%20tk%2Ddevel-,Linuxbrew%3A,-brew%20install%20bzip2) に必要なライブラリーは sqlite 以外はインストール済みだった

>Linuxbrew:
>brew install bzip2 libffi libxml2 libxmlsec1 openssl readline sqlite xz zlib


```sh
brew install pyenv
```

次に pyenv の環境変数の設定だが、  [WSL2 の Ubuntu bash の設定](https://github.com/pyenv/pyenv/#basic-github-checkout)
に従い次を実行する。

```sh
# For Bash:
# If your ~/.profile sources ~/.bashrc (Debian, Ubuntu, Mint):

# the sed invocation inserts the lines at the start of the file
# after any initial comment lines
sed -Ei -e '/^([^#]|$)/ {a \
export PYENV_ROOT="$HOME/.pyenv"
a \
export PATH="$PYENV_ROOT/bin:$PATH"
a \
' -e ':a' -e '$!{n;ba};}' ~/.profile
echo 'eval "$(pyenv init --path)"' >>~/.profile
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
```

`brew doctor` での warning を避けるため次を設定する

```sh
cat <<EOF >> ~/.bash_alias

# avoid brew doctor's warning
alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'
EOF
```


## install python by pyenv

```sh
# brew 側の gcc, g++ を指定する必要がある
CC=gcc-11 CXX=g++-11 pyenv install 3.9.11
```

```sh
# 主要な前処理系 package のインストール
pip install ipython pandas polars duckdb vaex
```

## install R by brew

```sh
mkdir -p ~/.R
cat <<EOF > ~/.R/Makevars
CC=gcc-11 
CXX=g++-11 
CXX98=g++-11
CXX11=g++-11 
CXX14=g++-11
EOF

brew install r
```

r 立ち上げ後に package 導入

```r
install.packages("tidyverse")
# 以下は事前に `brew install apache-arrow` が必要
install.packages("arrow")
install.packages("duckdb")
```

なお、Rのいくつかのpackageは systemd が PID1 である前提なことに注意。対応するには
 [genie](https://github.com/arkane-systems/genie) ではなく [distrod](https://github.com/nullpo-head/wsl-distrod)  がおススメ（が、この2か月間くらいupdateないのでちょい将来性不明）。

r のデフォルトREPLは使いづらいので radian を入れる

```sh
pip install radian
```

## その他

```sh
brew install source-highlight

cat <<EOF >> ~/.bashrc
# source-highlight by linuxbrew for less
export LESSOPEN="|/usr/bin/lesspipe | /home/linuxbrew/.linuxbrew/bin/src-hilite-lesspipe.sh %s"
export LESS="-X -R"
EOF
```

## まとめ

とりあえずインストール（コンパイル）では brew の gcc-11, g++-11 を使う指定を忘れずに。

以上