M1 MacBookでの開発環境構築

- Apple Siliconのネイティブ環境を構築メモ。
- QEMUの記述が増えてきたので[別ページ](https://qiita.com/hjmr/items/abeb9a4567d08ddcc3b9)に移動（2019/01/09）
- PyTorchが1.9.0でそのままインストールできるようになった（2021/06/17更新）
- SciPyが1.7.3でまたちゃんとインストールできるようになってた（2021/12/06更新）
- tensorflow-macos 2.7.0 のインストールについて追記（2021/12/07更新）
- tensorflow-macos 2.8.0 に合わせて記述を変更（2022/02/15更新）

# Homebrew周り

- gcc や OpenBLAS，go や Rust などほとんどがARM対応になっていて，/opt/homebrew をベースディレクトリにしている場合は bottle（バイナリ）がインストールされるようになっている（2021/01/02追記）

## Homebrew本体

- intel版は /opt/brew_x86 に，ARM版は /opt/homebrew に入れている。（2021/01/09変更）
- シェルのバージョンに合わせてパスを変更するように，`.zshenv` に以下のように記述。これにより，ARMで動いている場合は，まずARM版の実行ファイルを探し，無ければx86_64版を実行，x86_64で動いている場合はARM版は探さないようにする。

```:.zshenv
 ARCH=$(uname -m)
 if [ "$ARCH" = "arm64" ]; then
   export BREWx86_BASE=/opt/brew_x86
   export BREW_BASE=/opt/homebrew
   export PATH=${BREWx86_BASE}/bin:${BREWx86_BASE}/sbin${PATH:+:${PATH}}
   export PATH=${BREW_BASE}/bin:${BREW_BASE}/sbin${PATH:+:${PATH}}
 fi
 if [ "$ARCH" = "x86_64" ]; then
   export BREW_BASE=/opt/brew_x86
   # export PATH=${BREW_BASE}/bin:${BREW_BASE}/sbin${PATH:+:${PATH}}
   export PATH=${PATH//¥/homebrew¥//¥/brew_x86¥/}
 fi
```

## zsh
- zshrc でアーキテクチャによってプロンプトを変更して今どっちで動いているかわかるように，プロンプトを以下のように設定。
- 下記 `_my_venv_prompt_msg` は Python の virtualenv の情報を書き出す関数。
- 同 `_my_short_pwd` はカレントパスを短縮して表示する自前関数。

    ```:.zshrc
     ARCH=$(uname -m)
     if [ "$ARCH" = "arm64" ]; then
       PR_ARCH="ARM"
     else
       PR_ARCH="x86"
     fi

     PROMPT='%B$(_my_venv_prompt_msg)%F{black}%K{white} $(_my_short_pwd)$(_my_vcs_prompt_msg)%f%k%b
     %F{008}${PR_ARCH}%F{green}%k❯%f%b '
     RPROMPT="%F{008}[%D{%m/%d} %T]%f"
    ```
- `alias x86 = "arch -x86_64 zsh"` のようにしておいて，`x86`と叩けば intel版のシェルを起動できるように。
- `alise xbrew = /opt/brew_x86/opt/bin/brew` って書いてるけどパスとかも色々変えないといかんのでARMシェルからintel版brewを動かすのはちょっと大変そう。

## ffmpeg
- Homebrew で普通にインストールできる。
- `options` が設定できた方がいいんで，自分では開発元の fomula を tap している。

    ```:shell
     $ brew tap homebrew-ffmpeg/ffmpeg
     $ brew install homebrew-ffmpeg/ffmpeg/ffmpeg
    ```

## Emacs
- mitsuharu版Emacsをインストール。速い。

    ```:shell
     $ brew tap railwaycat/emacsmacport
     $ brew install emacs-mac
    ```
- 懸念してた vterm モジュールも問題なく動いている。すごい。

# Python周り

  - M1 Mac だと miniconda が多そうですが，うちの Python の開発環境は Pyenv + Poetry です。
  - インストールに少し工夫が必要なものだけ記載（書いてないってことはそのまま `poetry add` できるか，まだ試してないかのどちらか）

## Pyenv

- Homebrew版は対応が遅いので，GitHubから直接持ってきている。

    ```:shell
     $ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
    ```
- そのあとは `.zshrc` と `.zshenv` に以下の記述

    ```:.zshenv
     # Pyenv
     export PYENV_ROOT="${HOME}/.pyenv"
     if [ -x "${PYENV_ROOT}/bin" ]; then
       export PATH=${PYENV_ROOT}/bin:${PATH}
     fi
    ```

    ```:.zshrc
     # pyenv
     if [ -x "$(which pyenv)" ]; then
       eval "$(pyenv init - zsh)"
     fi
    ```

## Python本体

### 3.9系

- 3.9.1がリリースされて pyenv でも問題なくインストールできるようになった（2020/12/11)

### 3.8系

- TensorFlow_macOS を利用する場合に3.8系のPythonが必要。そもそもはシステムに最初からインストールされている 3.8.3 の利用を想定している。
- しかし，Homebrew の依存関係で Python（3.9） が入っていると pyenv で `system` を指定しても Homebrew のPython が指定され，macOS の Python 3.8.3 が利用できない。
- そこで pyenv で Python 3.8系を入れておく。
- Python 3.8.10がそのままインストールできた（2021/05/07追記）
- TensorFlow v2.5になってPython3.9で動くようになった（2021/06/17追記）

```:shell
  $ PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install 3.8.10
```

- Python 3.8.9以前をインストールする際は，以下のように pyenv の方でパッチを当ててインストールする。

```:shell
  $ PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install --patch 3.8.7 <<(curl -sSL "https://raw.githubusercontent.com/Homebrew/formula-patches/9811be33170a8f31a684fae6955542e31eb4e61e/python/3.8.7.patch")
```


## matplotlib

- 3.4.1がインストールできなくなってた！3.3系ならインストールできるのでこれをインストールする。（2021/04/22追記）
- 3.4.2からちゃんとインストールできるようになってる。（2021/08/25追記）

```:shell
  $ poetry add matplotlib
```

## opencv-python

- opencv-python が以下の手順で普通にインストールできるようになった（2021/07/29追記）

```:shell
  $ poetry add opencv-python
```

## SciPy

- pip の PEP517 対応のせい（というか SciPy の中に入ってる pyproject.toml のせい）で，Poetry で 1.7.1 がそのままインストールできなくなってたので対応（2021/11/02更新）
- SciPy 1.7.3 になって，`poetry add scipy` 一発でインストール可能になってるので以下の手順は不要（2021/12/06更新）

1. gfortran がインストールされていることを確認

    ```:shell
     $ gfortran --version
     GNU Fortran (Homebrew GCC 11.2.0) 11.1.0
     Copyright (C) 2021 Free Software Foundation, Inc.
     This is free software; see the source for copying conditions.  There is NO
     warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    ```

1. Homebrew で OpenBLAS をインストール後，`~/.numpy-site.cfg` にこれを指定。

    ```:.numpy-site.cfg
     [openblas]
     libraries = openblas
     library_dirs = /opt/brew/opt/openblas/lib
     include_dirs = /opt/brew/opt/openblas/include 
    ```

1. SciPyのインストールに必要なライブラリを予めインストール（devオプションはなくても大丈夫）

    ```:shell
     $ poetry add --dev Cython pybind11 pythran
    ```

1. その後 PEP517 を無視するようにオプションをつけて scipy をインストールする。

    ```:shell
     $ PIP_USE_PEP517=no poetry add scipy
    ``` 

### Python 3.8系でインストールする場合

Python 3.8系 で使う場合は上記の手順でインストールではインストールできない。最後の手順を以下のように変更する。

```:shell
 $ NPY_DISTUTILS_APPEND_FLAGS=1 poetry add scipy
```

## PyTorch

- 1.9.0 がそのままインストールできるようになってた。（2021/06/17更新）

```:shell
 $ poetry add torch
```

## TorchText

- 0.10.0 がそのままインストールできるようになってた（2021/06/17更新）

```:shell
 $ poetry add torchtext
```

## TorchVision

- 0.10.0 がそのままインストールできるようになってた。（2021/06/17追記）

```:shell
 $ poetry add torchvision
```

## [TensorFlow for macOS](https://github.com/apple/tensorflow_macos)

- 詳細は下記参照（Minicondaを使うインストール方法はこちら）
    - [Getting Started with tensorflow-metal PluggableDevice] (https://developer.apple.com/metal/tensorflow-plugin/)
- Poetryでは依存関係の解消が上手くいかなくて（というか依存関係の解析がうまくいってない＝バグのような気がするが...） tensorflow-macos 2.7.0 を素直にインストール出来ないので， PyPIから直接インストールする（2021/12/07更新）
- 2.8.0 になって Poetry でちゃんとインストールできるようになった（2022/02/15更新）

1. Homebrew で openssl，zlib，hdf5 を入れておく。

    ```:shell
      $ brew install openssl zlib hdf5
    ```

    その際，brew が注意してくれてるように，以下を実行またはシェルの設定ファイル（.zshrcなど）に書いておく。

    ```:shell
      export LDFLAGS="-L/opt/homebrew/opt/zlib/lib"
      export CPPFLAGS="-I/opt/homebrew/opt/zlib/include"
    ```

1. grpcioとh5pyのインストール時にエラーにならないように環境変数を設定。

    ```:shell
      $ export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
      $ export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1
      $ export HDF5_DIR=/opt/homebrew/opt/hdf5
    ```

1. そのあと tensorflow-macos のインストール。必要なパッケージは全部インストールされる。それなりに時間がかかる。

    ```:shell
      $ poetry add tensorflow-macos
    ```

1. tensorflow-metal のインストール。これは一瞬。

    ```:shell
      $ poetry add tensorflow-metal
    ```