みんなの M1 Mac における Homebrew のベストプラクティス は間違っている
- 追記(2020/12/14): Qiita の Advent Calendar 2020 に空きがあったので登録しました
- 追記(2020/12/30): Homebrew のインストーラーがM1 Macをサポートされました!
- 追記(2021/02/07): Homebrew 3.0.0 がリリースされ正式に対応されました
Apple Silicon (M1 チップ) を採用した Mac に Homebrew をインストールするときのみんなの設定に対してもっと楽な方法があるのにと思い投稿しました。
上記の記事ではわざわざRosettaを選択してー
やシェルを切り替えてー
みたいなことが書いてありますがはっきり言って面倒です!
前提
- Rosettaをインストールしている
- これがないと話が始まりません
-
ARMで動作するターミナル現状公式のターミナルアプリのみです- ->
exec arch -arm64e /bin/zsh
で対応していないターミナルからでもarm64動作できました
- zshを使用している
- デフォルトのログインシェルを変更していなければ大丈夫です
Homebrew をインストール
やることは簡単で、今回主役のarch
コマンドを使います。
通常版
x86_64で動作する方ですね
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
(今後変更される場合があるので/bin/bash
以降の部分は公式サイトを見て置き換えてください)
ARM版
ARM64で動作する方です
arch -arm64e /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
私の環境だと/opt
はrootが所有しているのでsudo
をつけます
ワンライナーが対応してくれました!
設定
Rosettaを入れるとarch
コマンドが追加されます。
そしてできるだけarmを使いたいので
typeset -U path PATH
path=(
/opt/homebrew/bin(N-/)
/usr/local/bin(N-/)
$path
)
のようにARM版(/opt/homebrew/bin
)を優先的に設定します。
(ちなみに(N-/)
はフォルダが存在するとパスを追加するという意味です。)
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
上記の設定を追加することによってmacでarch
コマンドが使えるときのみ設定されます。
他にも
setopt magic_equal_subst
を設定するとこのあと説明しますが便利に使用できます。
ほかにも switch-arch
で切り替えをできたり
x64
やa64
で強制的に変更できます
使い方
同じように設定したのであればbrew
はarch -arch x86_64 /usr/local/bin/brew
へとエイリアスになっていると思います
また $PATH
上で優先される brew
コマンドは /opt/homebrew/bin/brew
のはずです
そして magic_equal_subst
を設定しているので先頭に =
をつけてコマンドを実行するとそのコマンドの絶対パスが帰ってくるので /opt/homebrew/bin/brew
が使われるはずです。
# -> Rosettaを使ってXXXをインストール
brew install XXX
# -> ARMでXXXをインストール
=brew install XXX
まとめ
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
を~/.zshrc
に追加する!
(~/.zshenv
だと$PATH
の書き換えが発生するので)
brew
はRosettaを使う、ARM版は =brew
のように =
をつける!
Discussion
この通りやったら、めっちゃ簡単にできるようになりました!
ありがとうございます!
一点だけ、
setopt magic_equal_subs
と書かれている箇所がありますが、正しくは
setopt magic_equal_subst
ですかね?
Typo 報告ありがとうございます。編集しておきました!
~/.zshrc
typeset -U path PATH
path=(
/opt/homebrew/bin(N-/)
/usr/local/bin(N-/)
$path
)
これはどこで開けるのですか?
ターミナルに打つのでしょうか?
~/.zshrc
はユーザーディレクトリ直下に存在します。~/
はユーザーディレクトリのことを表し、.zshrc
というファイルに書き込めばいいと思います。詳しくは他の人がまとめてくださっているので調べてください。また好きなエディタで操作して頂いて構いません。標準のテキストエディタで書く場合はターミナルで
open ~/.zshrc
と打つとできますよ知見をありがとうございます。
浅学で申し訳ないのですが、いつかRosettaが不要になったとき、どう対処したらよいのかも教えていただきたいです。
このzshrcの内容を削除するだけで、
brew
はARMで動作するようになるのでしょうか?現状言えることはHomeBrewがどのような方針にするのかを待つしかありません。
またコードを挿入していない場合は
brew
コマンドはターミナルとログインシェルに依存します。Apple Silicon搭載のmacOSで標準の
ターミナル.App
と/usr/bin/zsh
を使用しているのであればARMで動作するはずです。とても参考になりました!ありがとうございました!!
めちゃめちゃ参考になりました!
自分の環境で試した際、zsh の compinit チェックで下記警告が出ましたが、警告がでたディレクトリのパーミッション変更することで解消できたので共有します!
非常に有益な情報ありがとうございます!
質問なのですが、こちらはターミナルアプリにIterm2を使用した場合でも同様に作動しますか?
最新版のiTerm2はユニバーサルアプリとなったため使用できますよ
M1 公式サポート来ましたね!
でもformula側がまだ対応してないのも多いから、結局Rosetta使うことになるんですかね?
情報、ありがとうございます。記事に追記しておきました。
公式ブログを見ると
とあるのでまだすべてのbottlesが対応していないし、Rosetta 2で動作するのは
/usr/local
にインストールする事が書いてあることからまだまだRosettaを使用しないといけない状況ですね(Homebrew以外にもDiscordなど対応していないアプリがまだありますし)
なるほど、詳しい情報ありがとうございます!
ressさんのこの記事のおかげで、M1でも快適にHomebrew使えてるので本当にありがとうございます🙇♂️