🍏

みんなの M1 Mac における Homebrew のベストプラクティス は間違っている

4 min read 13

https://github.com/Homebrew/install/pull/373
  • 追記(2021/02/07): Homebrew 3.0.0 がリリースされ正式に対応されました

https://brew.sh/2021/02/05/homebrew-3.0.0/

Apple Silicon (M1 チップ) を採用した Mac に Homebrew をインストールするときのみんなの設定に対してもっと楽な方法があるのにと思い投稿しました。

https://qiita.com/yujiod/items/56002a7cef5b5a3be3fb
https://qiita.com/shira-shun/items/0f6213f4923cb5544367
https://zenn.dev/sai2_dev/articles/20201213_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を使いたいので

~/.zshrc
typeset -U path PATH
path=(
	/opt/homebrew/bin(N-/)
	/usr/local/bin(N-/)
	$path
)

のようにARM版(/opt/homebrew/bin)を優先的に設定します。

(ちなみに(N-/)はフォルダが存在するとパスを追加するという意味です。)

https://qiita.com/mollifier/items/42ae46ff4140251290a7
~/.zshrc
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コマンドが使えるときのみ設定されます。

他にも

~/.zshrc
setopt magic_equal_subst

を設定するとこのあと説明しますが便利に使用できます。

ほかにも switch-arch で切り替えをできたり

x64a64で強制的に変更できます

使い方

同じように設定したのであればbrewarch -arch x86_64 /usr/local/bin/brewへとエイリアスになっていると思います

また $PATH 上で優先される brew コマンドは /opt/homebrew/bin/brew のはずです

そして magic_equal_subst を設定しているので先頭に = をつけてコマンドを実行するとそのコマンドの絶対パスが帰ってくるので /opt/homebrew/bin/brew が使われるはずです。

Terminal.app
# -> Rosettaを使ってXXXをインストール
brew install XXX
# -> ARMでXXXをインストール
=brew install XXX

まとめ

~/.zshrc
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 のように =をつける!

この記事に贈られたバッジ