81
57

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

M1 MacでARMとIntelのターミナルを切り替えて使う (Homebrew 3以降の場合)

Last updated at Posted at 2021-08-12

M1 MacではRosetta 2を使って x86, x86_64 (以下x64) のIntelアプリやライブラリを実行できるのは有名だが、ターミナルを切り替えて使うことで、ARM非対応のツールやライブラリを使ってIntel版の開発を進めることができ、かつARM版と共存させることができる。

ARMとIntelのターミナルを切り替えて使う記事は既にあるものの、2021/2/5にARMに正式対応したHomebrew 3.0.0以前の記事しか見当たらず、Homebrew 3.0.0以降の正式対応後の手順と設定を改めてまとめてみることにした。

iTermをインストール

デフォルトのターミナルでも良いのだけれど、後述の見た目を分けることができなかったり、名称変更後のターミナルがSpotlightで呼び出しにくいなどで不便が多いので、iTermをインストールしている前提で以下説明する。

Intel版 (x64版) のターミナルを作る

/Applications/iTerm.app をコピーして、「iTerm_x64.app」などに名称変更する。(ターミナル.appの場合は、/Applications/Utilities/Terminal.appを複製。)

スクリーンショット 2021-08-12 15.26.45.png

複製した方の「iTerm_x64.app」を右クリックして「情報を見る」を選択し、「Rosettaを使用して開く」にチェックを入れる。

スクリーンショット_2021-08-12_15_23_53u.png

ターミナルの見た目をそれぞれで変える

2つのターミナルをそのまま使うと非常に紛らわしいので、見た目を変える。.bash_profileなどから切り替えてもいいのだけれど、簡単な方法として、プロファイルの背景色を変えるのがおすすめ。

スクリーンショット 2021-08-12 15.30.45.png

変えたい方のターミナルを一度起動して、メニューの iTerm > Preferences から、Profiles > Colors > Background で変更できる。(ターミナル.appだと、この設定を変えると両方に反映されてしまう。)

追記: プロファイルが一つだと、iTermでも設定が共有されてしまうことがあるようなので、ちゃんと切り替える方が良いみたい。2つプロファイル、例えば「ARM」と「Intel」を作成して、以下のように.bash_profileに追記することで自動切り替えを実現する。

.bash_profile
alias change_profile='(){echo -e "\033]1337;SetProfile=$1\a"}'

if [ "$(uname -m)" = "arm64" ]; then
  # arm64
  change_profile ARM
else
  # x86_64
  change_profile Intel
fi

新規プロファイルを作る際は、Defaultのプロファイルを「Other Actions...」から複製して、Generalタブから名称変更するのが楽。

ちなみに上記設定を追記すると、最初の実行時に警告が出るので、Always Allowを選択する。

スクリーンショット 2021-08-18 21.13.08.png

後でこの設定を変更したい場合は、Preferences > Advanced から、 Show only non-default valuesにチェックを入れ、Prevent control sequences from changing the current profile? の値を変更する (デフォルトはUnspecified)。

スクリーンショット 2021-08-18 21.13.17.png

ちゃんとx64になっていることを確認

それぞれのターミナルを起動して、uname -m を実行すると、ARM版ではarm64、Intel版ではx86_64と表示される。

スクリーンショット 2021-08-12 15.55.45a.png

Homebrewをそれぞれでインストールする

次に、各ターミナルを起動して、Homebrewをそれぞれでインストールする。(ARM版のHomebrewを既にインストール済みの場合は、Intel版のターミナルでのみインストールする。)

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

Homebrew 3.0.0以降でARM版に正式対応したので、ARM版ターミナルでは /opt/homebrew、Intel版では /usr/local/ 以下にそれぞれ自動判別してインストールされる。

最後にパスの設定を促されるのだが、今回は共存させる必要があるので、bashの場合は~/.profile、zshの場合は ~/.zprofileに以下のように設定する。(既にeval "$(/opt/homebrew/bin/brew shellenv)"が記載されている場合は置き換える。)

.profile
if [ "$(uname -m)" = "arm64" ]; then
  eval "$(/opt/homebrew/bin/brew shellenv)"
  export PATH="/opt/homebrew/bin:$PATH"
else
  eval "$(/usr/local/bin/brew shellenv)"
fi

これでそれぞれのターミナルを再起動すると、きちんとbrewがそれぞれのアーキテクチャで使えるようになっている。which brewでbrewのパスを確認できる。

スクリーンショット 2021-08-12 15.55.45ax.png

あとは、それぞれのbrewはまるで別々のパソコンで使っているかのように別のフォルダに棲み分けされるので、必要なツールやライブラリはそれぞれでインストールする。

注意として、パスが通っているとARMかIntelかに関係なく実行できるのが、便利だが紛らわしい。ARMとIntelが混ざっていても問題ない場合もあるが、きちんとフォルダと設定を分けておいたほうが無難。

.bash_profile
if [ "$(uname -m)" = "arm64" ]; then
  # arm用の設定...
else
  # intel用の設定...
fi

*envを棲み分けする

ARMとIntelで設定を分けたほうがいい具体例として、pyenv、nodenv、rbenvなどの*envがある。

anyenvの場合

自分の場合はこれらをまとめて設定できるanyenvを使っているが、何も考えずに使ってしまうと~/.anyenvに両方混ざっておかしなことになるので、例えば以下のようにする。

git clone https://github.com/anyenv/anyenv ~/.anyenv_arm64
cp -r ~/.anyenv_arm64 ~/.anyenv_x64
.bash_profile
if [ "$(uname -m)" = "arm64" ]; then
  # arm64
  export ANYENV_ROOT="$HOME/.anyenv_arm64"
  export PATH="$HOME/.anyenv_arm64/bin:$PATH"
  eval "$(anyenv init -)"
else
  # x86_64
  export ANYENV_ROOT="$HOME/.anyenv_x64"
  export PATH="$HOME/.anyenv_x64/bin:$PATH"
  eval "$(anyenv init -)"
fi

pyenvの場合

(anyenvを使っている場合は前述の設定だけで問題ないので、追加設定は不要。)

git clone https://github.com/pyenv/pyenv ~/.pyenv_arm64
cp -r ~/.pyenv_arm64 ~/.pyenv_x64
.bash_profile
if [ "$(uname -m)" = "arm64" ]; then
  # arm64
  export PYENV_ROOT="$HOME/.pyenv_arm64"
  export PATH="$HOME/.pyenv_arm64/bin:$PATH"
  eval "$(pyenv init -)"
else
  # x86_64
  export PYENV_ROOT="$HOME/.pyenv_x64"
  export PATH="$HOME/.pyenv_x64/bin:$PATH"
  eval "$(pyenv init -)"
fi

nodenvやrbenvなどの場合も、node-buildやruby-buildのcloneが追加で必要なくらいで、設定は同様。

ARMとIntelが混ざってしまった場合

前述の通り、パスが通っているとARMかIntelか関係なく呼び出せてしまうので、アーキテクチャが混ざっていると困まったことがよく起こる。

コマンドの場合は、whichwhereなどでどれが呼ばれているかを特定して、場合によってlipo -infootoolを使ってアーキテクチャを判断してケースバイケースで対処。

ライブラリの場合も同様で、brew doctorlocateなどのコマンドで判別しつつ、C_INCLUDE_PATHLD_LIBRARY_PATHなどの環境変数を切り分けたり、brewなどで調整したりする。

いずれにしても、片方のアーキテクチャのみでインストールされているツールやライブラリが問題になることが多いので、きちんと切り分けていれば大丈夫。

arch -x86_64 をうまく使うと便利

ちなみに一度Rosettaがインストールされていれば、

$ arch -x86_64 uname -m

のように arch -x86_64 をつけてコマンドを実行すればRosettaで実行でき、ちょっとしたことはこれで十分。(逆にARM64で実行したい場合は arch -arm64e。 )

この方法を使えば、ターミナルごと分けなくても、

$ arch -x86_64 zsh

とか

$ arch -x86_64 bash

でRosettaのシェルに切り替えることもできる。これでも今までの設定はちゃんと読み込まれるので、どちらがいいかは好み。(ARCHでシェルを切り替える方が、ターミナルのGUI自体はネイティブに実行される分、電池消費はいいかもしれない。)

81
57
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
81
57

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?