Help us understand the problem. What is going on with this article?

Apple SiliconにおけるHomebrewのベストプラクティス

開発環境としてのApple Silicon

みなさんApple SiliconなMac mini/Macbook Air/Macbook Proは買いましたか?

DockerやVirtualBoxが2020年11月18日時点では動作しないので開発環境としては絶望的ですが、Visual Studio Codeは86エミュレーションでも比較的快適に動いてくれるので、せめてCLIまわりは整備できないかなと思って試行錯誤した結果をまとめてみました。

概要

ターミナルからはアーキテクチャを意識せず混在して実行できるけど、2020年11月18日時点のHomebrewではarm64とx86_64でバイナリが分かれてしまうので、arm64のパッケージが入れられるものはそれを使うけど、入れられないものはx86_64のバイナリを使うための比較的快適な環境を構築する。

Apple SiliconにおけるターミナルとHomebrewの動作について

  • Rosetta2により子プロセスのアーキテクチャは混在できる
    • x86_64のzshからarm64のhtopを起動できる
  • Homebrewのインストール先は、これまでは/usr/local配下だったが、arm64ビルドでは/opt/homebrew配下となる
    • 今後ユニバーサルバイナリが提供されるようになることに期待
  • Homebrewにてインストールするarm64のパッケージは、現状バイナリが提供されていないのでソースからビルドされる
  • x86_64のシェルからarm64のHomebrewのパッケージはインストールできない
    • 逆もしかり

対応方針

arm64ビルドのものを優先して使えるようにし、arm64ビルドのないコマンドはx64_64ビルドのコマンドを実行する。
(Rosetta2によるオーバーヘッドを減らすため、それでも十分良いパフォーマンスは出ているけど)

  • arm64でビルドできるパッケージは、arm64版をインストールする
  • ディフォルトのシェルはarm64ビルドのものを利用する
  • ビルドに時間がかかって時間が惜しい場合やビルドできない場合は、x86_64のパッケージをインストールする

対応内容

Homebrewのインストール

x86_64

ターミナルが開いていれば閉じてからFinderからターミナルの「情報を見る」を開き「Rosettaを使用して開く」にチェックを付け実行したうえで、
macOS(またはLinux)用パッケージマネージャー — Homebrew
どおりにインストールする。

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

arm64

ターミナルが開いていれば閉じてからFinderからターミナルの「情報を見る」を開き「Rosettaを使用して開く」のチェックを外し実行したうえで、
Installation — Homebrew Documentation
のAlternative Installs - Untar anywhereに記載のものを参考にインストールする。

$ cd /opt
$ sudo mkdir homebrew
$ sudo chown $USER:admin homebrew
$ curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew

シェルのアーキテクチャ切り替えをコマンドで実現する

Homebrewのパッケージをインストールする際、ビルドターゲットがシェルの実行アーキテクチャに依存しているようで、異なるアーキテクチャのパッケージをインストール(もしくはビルド)することができない。

標準で入っているコマンドはUniversal対応となっている。

lipoで指定されたバイナリの対象アーキテクチャを表示
$ lipo -archs /bin/zsh
x86_64 arm6e

ユニバーサルバイナリとなっているコマンドについては、実行されているターミナルのアーキテクチャから自動的にシェルのアーキテクチャが決定される。
Homebrewのインストールでも操作していたように、Finderからターミナルの「情報を見る」にて「Rosettaを使用して開く」にチェックを付けることでx86_64のシェルを起動できる。

「Rosettaを使用して開く」が有効なターミナルのアーキテクチャ
$ uname -m
arm64
「Rosettaを使用して開く」が無効なターミナルのアーキテクチャ
$ uname -m
x86_64

しかしながら、アーキテクチャの切り替えが面倒なのと、ターミナル内でコマンドを実行する際にアーキテクチャを指定して実行する方法が現状ないと思われるので、Homebrewからarm64のzshとx86_64のzshの両方を導入する。(他のシェルを使いたい場合も同様)

x86_64ビルドのzshパッケージをインストール

ターミナルが起動している場合には終了し、Finderからターミナルの「情報を見る」にて「Rosettaを使用して開く」にチェックを付けて起動したうえで以下のコマンドを実行する。

$ /usr/local/bin/brew install zsh

以降、x86_64版のシェルに切り替える場合には以下を実行する。

$ /usr/local/bin/zsh
$ uname -m
x86_64

arm64ビルドのzshパッケージをインストール

ターミナルが起動している場合には終了し、Finderからターミナルの「情報を見る」にて「Rosettaを使用して開く」のチェックを外し起動したうえで以下のコマンドを実行する。

$ /opt/homebrew/bin/brew install zsh

以降、arm64版のシェルに切り替える場合には以下を実行する。

$ /opt/homebrew/zsh
$ uname -m
arm64

パスの設定

export PATH=/opt/homebrew/bin:/usr/local/bin:$PATH

パッケージのインストール

対応表(macOS 11.0 Big Sur compatibility on Apple Silicon · Issue #7857 · Homebrew/brew · GitHub)で対応しているもので、比較的ビルドが早そうで軽量なパッケージはarm64のパッケージをインストールする。

x86_64のパッケージをインストールする

$ uname -m
arm64
# シェルの実行アーキテクチャがarm64の場合はx86_64のシェルを起動する
$ /usr/local/bin/zsh
$ uname -m
x86_64
$ /usr/local/bin/brew install sl
$ which sl
/usr/local/bin/sl
$ sl

実行されているシェルのアーキテクチャを判別してbrewコマンドの実行アーキテクチャを切り替えることも考えたが、今のシェルはどっちのアーキテクチャなのか意識せず絶対混乱しそうなので、面倒だけどbrewコマンドのパスは明示的に指定することにした。

arm64のパッケージをインストールする

$ uname -m
x86_64
# シェルの実行アーキテクチャがx86_64の場合はarm64のシェルを起動する
$ /opt/homebrew/zsh
$ uname -m
arm64
$ /opt/homebrew/bin/brew install sl
$ which sl
/opt/homebrew/sl
$ sl

x86_64のパッケージもインストールされているが、arm64のパッケージを優先して使うようにしたことでx86_64のパッケージが不要なら、必要に応じてアンインストールする。

$ uname -m
arm64
# シェルの実行アーキテクチャがx86_64の場合はarm64のシェルを起動する
$ /usr/local/bin/zsh
$ uname -m
x86_64
$ /usr/local/bin/brew uninstall sl

おまけ: シェルプロンプトに実行中のシェルのアーキテクチャ名を表示する

実行中のアーキテクチャをunameでいちいち確認するのも面倒なので、プロンプトに表示しておく。

zsh

~/.zshrc
export PROMPT="%n@%m(`uname -m`) %1~ %# "

fish

~/.config/fish/functions/fish_prompt.fish
# 以下をfish_promptの関数内の冒頭に追加する、なければ定義する
echo -n "("(uname -m|sed "s/\r//")")"

最後にひとこと

絶対混乱する

salesrobotics
テクノロジーで、営業をもっとスマートに!新しい営業のカタチを提案するインサイドセールスのSaaSサービスを開発、提供しています。
https://salesrobotics.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away