M1 Mac での環境構築の最適解

#本記事の執筆に当たって
M1チップ搭載のMacが発売されましたが、アーキテクチャの違いで環境構築に戸惑いを感じた方も多くいるのではないでしょうか。私もその一人でした。本記事では**2020年2月20日**現在の状況下で最も優れていると思われる環境構築方法を紹介したいと思います。
#環境構築の上での方針
- できるだけ**ネイティブ環境**(**arm64**)で構築する。
- ネイティブ環境で動作が不安定になる場合はRosetta2を使用して**Intel環境**(**x86_64**)で構築する。
- アーキテクチャ間の切り替えはスムーズにできるようにする。

#本記事で環境構築する開発ツール・プログラミング言語
- Homebrew(**arm64/x86_64**)
- gcc(**arm64**)
- Nodebrew(**x86_64**)
    - Node.js(**x86_64**) 
    - npm(**x86_64**)

**Homebrewに関してはパッケージ管理システムとしてネイティブ環境とIntel環境のどちらにも採用することとする。**

#前提
- Rosetta2をインストール済み。
- ターミナルはデフォルト(zsh)を使用している。

#1.Homebrew
Homebrewに関しては前述の通り、ネイティブ環境とIntel環境のどちらにも採用することにするので2回、インストールが必要です。また、この際にターミナルのアーキテクチャ間の切り替えをスムーズに行えるように設定します。
##ネイティブ版
通常のターミナルを開いて以下のコマンドを実行します。

```
arch -arm64e /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

##Intel版
今度はFinderからアプリケーションの**”ターミナルの情報を見る”**から
**”Rosettaを使用して開く”**のチェックマークにチェックを入れてからターミナルを起動して以下のコマンドを実行します。

```
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

##アーキテクチャ間の切り替え
これまででネイティブ環境とIntel環境のどちらにもHomebrewを導入したわけですが、このままだとアーキテクチャの切り替えはいちいち**”Rosettaを使用する”**から切り替えることになります。これでは実用的ではないのでターミナル上でコマンドを実行するだけでアーキテクチャ間の切り替えをできるようにします。
ターミナルの設定ファイルである**.zshrc**ファイルに以下を記述します。

```ruby:~/.zshrc&#x2
typeset -U path PATH
path=(
	/opt/homebrew/bin(N-/)
	/usr/local/bin(N-/)
	$path
)

if (( $+commands[sw_vers] )) && (( $+commands[arch] )); then
	[[ -x /usr/local/bin/brew ]] && alias brew="arch -arch x86_64 /usr/local/bin/brew"
	alias x64='exec arch -x86_64 /bin/zsh'
	alias a64='exec arch -arm64e /bin/zsh'
	switch-arch() {
		if  [[ "$(uname -m)" == arm64 ]]; then
			arch=x86_64
		elif [[ "$(uname -m)" == x86_64 ]]; then
			arch=arm64e
		fi
		exec arch -arch $arch /bin/zsh
	}
fi

setopt magic_equal_subst
```

この記述によって

- デフォルトではネイティブ環境のターミナルを使用
- ターミナル内でターミナルのアーキテクチャの切り替えを行う

ことが可能になります。

ターミナルでアーキテクチャの切り替えを行うには以下のコマンドで実行できます。

```
switch-arch
```

また、現在使用しているアーキテクチャを確認するためには以下のコマンドを実行して

```
uname -m
```
実行結果が

```
arm-64
```
ならば、ネイティブ環境で

```
x86_64
```
ならIntel環境(Rosetta2)で実行されていることがわかります。

#2.gcc
gccはHomebrewからダウンロードするとIntel版とネイティブ版の２つがセットで付いてきます。また、もう既にネイティブ環境の動作がIntel版と遜色がないのでネイティブ版で環境を構築していきたいと思います。

gccを以下のコマンドでダウンロードします。

```
=brew install gcc
```

brewコマンドの先頭に"**=**"が付いていますがこれはネイティブ版のbrewコマンドを呼び出すコマンドでIntel版のbrewコマンドと区別することができます。
gccをダウンロードしてもMacには標準でApple Clangが搭載されていますのでgccを実行することができません。そこで、以下のコードをターミナルの設定ファイルである**.zprofile**に記述します。

```
export PATH=/usr/local/bin:$PATH
```

これでclangではなく、gccが呼び出されるようになります。
ターミナルに以下のコマンドを入力すると現在呼び出されているC言語のコンパイラが確認できます。

```
gcc -v
```

#3.Nodebrew
現在、Nodebrew自体はネイティブ環境に対応しているのですがNode.jsはネイティブ環境での挙動が不安定であり、次のNode.js 16で完全に対応すると思われます。そこで、現段階では不具合を避けるためIntel版での環境構築をおすすめします。

ターミナルで以下のコマンドを実行し、Intel版のHomebrewからNodebrewをダウンロードします。

```
brew install nodebrew
```
これでIntel版のNodebrewがダウンロードされます。

次に、Node.jsをダウンロードします。
以下のコマンドを実行して現在ダウンロード可能なバージョンを確認します。

```
nodebrew ls-remote
```

これで以下のようにインストール可能なNode.jsのバージョンが一覧で表示されます。

```
...

v10.0.0   v10.1.0   v10.2.0   v10.2.1   v10.3.0   v10.4.0   v10.4.1   v10.5.0
v10.6.0   v10.7.0   v10.8.0   v10.9.0   v10.10.0  v10.11.0  v10.12.0  v10.13.0
v10.14.0  v10.14.1  v10.14.2  v10.15.0  v10.15.1  v10.15.2  v10.15.3  v10.16.0
v10.16.1  v10.16.2  v10.16.3  v10.17.0  v10.18.0  v10.18.1  v10.19.0  v10.20.0
v10.20.1  v10.21.0  v10.22.0  v10.22.1  v10.23.0  v10.23.1  v10.23.2  v10.23.3


v11.0.0   v11.1.0   v11.2.0   v11.3.0   v11.4.0   v11.5.0   v11.6.0   v11.7.0
v11.8.0   v11.9.0   v11.10.0  v11.10.1  v11.11.0  v11.12.0  v11.13.0  v11.14.0
v11.15.0  

v12.0.0   v12.1.0   v12.2.0   v12.3.0   v12.3.1   v12.4.0   v12.5.0   v12.6.0
v12.7.0   v12.8.0   v12.8.1   v12.9.0   v12.9.1   v12.10.0  v12.11.0  v12.11.1
v12.12.0  v12.13.0  v12.13.1  v12.14.0  v12.14.1  v12.15.0  v12.16.0  v12.16.1
v12.16.2  v12.16.3  v12.17.0  v12.18.0  v12.18.1  v12.18.2  v12.18.3  v12.18.4
v12.19.0  v12.19.1  v12.20.0  v12.20.1  v12.20.2  

v13.0.0   v13.0.1   v13.1.0   v13.2.0   v13.3.0   v13.4.0   v13.5.0   v13.6.0
v13.7.0   v13.8.0   v13.9.0   v13.10.0  v13.10.1  v13.11.0  v13.12.0  v13.13.0
v13.14.0  

v14.0.0   v14.1.0   v14.2.0   v14.3.0   v14.4.0   v14.5.0   v14.6.0   v14.7.0
v14.8.0   v14.9.0   v14.10.0  v14.10.1  v14.11.0  v14.12.0  v14.13.0  v14.13.1
v14.14.0  v14.15.0  v14.15.1  v14.15.2  v14.15.3  v14.15.4  v14.15.5  

v15.0.0   v15.0.1   v15.1.0   v15.2.0   v15.2.1   v15.3.0   v15.4.0   v15.5.0
v15.5.1   v15.6.0   v15.7.0   v15.8.0   v15.9.0   
...

```

この中から以下のコマンドのようにバージョンを指定してダウンロードします。

```
nodebrew install v15.6.0
```

これでIntel版のNode.jsが無事にダウンロードできます。

#おわりに
Apple Silicon搭載のMacはまだ、開発環境も十分に整っていなく開発には不向きだと思います。ただし、Appleはこれから2年間で全てのMacをApple Silicon製にすると発表していますので、これからのもっと開発環境が充実してくるとは思われますが現移行段階ではIntel版も交えた開発環境の整備が最も安定的だと思われます。全ての開発ツールがネイティブ環境に対応して早く快適に開発ができることを願います。今回の記事はアーキテクチャ間を何度も横断していてとてもややこしい説明となっていますが、皆さんの開発環境構築の助けになれば幸いです。

####引用:
[みんなの M1 Mac における Homebrew のベストプラクティス は間違っている](https://zenn.dev/ress/articles/069baf1c305523dfca3d)
[MacでGCCを"正しく"環境構築しよう！]
(https://qiita.com/DaikiSuyama/items/09f5aa399aad37783146#3gcc%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%ABgcc%E3%81%B8%E3%81%AE%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88)
[NodebrewでNodeをインストールする]
(https://qiita.com/mame_daifuku/items/373daf5f49ee585ea498)