arch コマンドを使う
Rosetta を入れると arch
と言うコマンドが使えるようになります。[1]
mac arch command
などで調べてもいまいち説明が見つからないので、man arch
の冒頭を見てみます。
man arch
DESCRIPTION
The arch command with no arguments, displays the machine's architecture type.
The other use of the arch command is to run a selected architecture of a universal binary. A universal binary contains code that can run on different architectures. By default, the operating system will select the architecture that most closely matches the processor type. A 64-bit architecture is preferred over a 32-bit architecture on a 64-bit processor, while only 32-bit architectures can run on a 32-bit processor.
When the most natural architecture is unavailable, the operating system will try to pick another architecture. On 64-bit processors, a 32-bit architecture is tried. Otherwise, no architecture is run, and an error results.
The arch command can be used to alter the operating system's normal selection order. The most common use is to select the 32-bit architecture on a 64-bit processor, even if a 64-bit architecture is available.
引数なしで実行するとアーキテクチャを表示、そうでなければアーキテクチャを指定して実行、といったところでしょうか。
ユニバーサルバイナリのシェルを切り替える
確認してみましょう。
x86_64 ターミナル → x86_64 シェル → x86_64 シェル が ( 意味はないけど ) 可能です。
$ uname -m
x86_64
$ arch -x86_64 /bin/zsh
$ uname -m
x86_64
x86_64 ターミナル → x86_64 シェル → ARM64 シェル が ( 前の章と違い ) 可能です。
$ uname -m
x86_64
$ arch -arm64e /bin/zsh
$ uname -m
arm64
ARM64 ターミナル → ARM64 シェル → x86_64 シェル が可能です。
$ uname -m
arm64
$ arch -x86_64 /bin/zsh
$ uname -m
x86_64
ARM64 ターミナル → ARM64 シェル → ARM64 シェル が ( 意味はないけど ) 可能です。
$ uname -m
arm64
$ arch -arm64e /bin/zsh
$ uname -m
arm64
全てのパターンが感覚的に期待する通りに動いていますね。
brew を使い分ける
brew
の挙動も確認しておきます。
ARM64 ターミナルでの x86_64 brew の利用
まず前の章では割愛しましたが、ただ ARM64 ターミナルから x86_64 brew
を使うことはできません。
$ uname -m
arm64
$ /usr/local/bin/brew install mysql-client
Error: Cannot install in Homebrew on ARM processor in Intel default prefix (/usr/local)!
Please create a new installation in /opt/homebrew using one of the
"Alternative Installs" from:
https://docs.brew.sh/Installation
You can migrate your previously installed formula list with:
brew bundle dump
arch -x86_64
を付与して同じコマンドを実行してみると、x86_64 バイナリのインストールに成功します。
$ arch -x86_64 /usr/local/bin/brew list | grep mysql
$ arch -arm64e /opt/homebrew/bin/brew list | grep mysql
$ arch -x86_64 /usr/local/bin/brew install mysql-client
bla bla bla
$ arch -x86_64 /usr/local/bin/brew list | grep mysql
mysql-client
$ arch -arm64e /opt/homebrew/bin/brew list | grep mysql
$ lipo -archs /usr/local/opt/mysql-client/bin/mysql
x86_64
mysql
はどのアーキテクチャのターミナルからでも、問題なく動きます。
$ uname -m
x86_64
$ /usr/local/opt/mysql-client/bin/mysql -h 127.0.0.1 -u foo -pbar
mysql>
$ uname -m
arm64
$ /usr/local/opt/mysql-client/bin/mysql -h 127.0.0.1 -u foo -pbar
mysql>
インストールするバイナリのアーキテクチャは brew
のアーキテクチャと連動することと、ターミナルやシェルをいちいち切り替えなくても arch
を使えば brew
を使い分けられることが確認できました。
x86_64 ターミナルでの ARM64 brew の利用
同じく前の章では割愛しましたが、ただ x86_64 ターミナルから ARM64 brew
を使うことはできません。
$ uname -m
x86_64
$ /opt/homebrew/bin/brew install mysql-client
Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:
arch -arm64 brew install ...
To install under x86_64, install Homebrew into /usr/local.
arch -arm64e
を付与して同じコマンドを実行してみると、ARM64 バイナリのインストールに成功します。
$ arch -x86_64 /usr/local/bin/brew list | grep mysql
$ arch -arm64e /opt/homebrew/bin/brew list | grep mysql
$ arch -arm64e /opt/homebrew/bin/brew install mysql-client
bla bla bla
$ arch -x86_64 /usr/local/bin/brew list | grep mysql
$ arch -arm64e /opt/homebrew/bin/brew list | grep mysql
mysql-client
$ lipo -archs /opt/homebrew/Cellar/mysql-client/8.0.26/bin/mysql
arm64
mysql
はどのアーキテクチャのターミナルからでも、問題なく動きます。
$ uname -m
x86_64
$ /opt/homebrew/Cellar/mysql-client/8.0.26/bin/mysql -h 127.0.0.1 -u foo -pbar
mysql>
$ uname -m
arm64
$ /opt/homebrew/Cellar/mysql-client/8.0.26/bin/mysql -h 127.0.0.1 -u foo -pbar
mysql>
先ほどと完全に対称的なことができるのがわかりました。
が、どちらでも同じことが実現できるのなら、運用するのは片方だけで良いでしょう。
結論
arch
を使えば全てのパターンが問題なく動くことが確認できました。
が、2 ケースだけ扱えるようにしておけば十分でしょう。
ターミナル | シェル | brew | 取得結果 | 取得結果の利用 | メモ |
---|---|---|---|---|---|
x86_64 | x86_64 | x86_64 | x86_64 | 可能 | |
x86_64 | x86_64 | ARM64 ( arch ) | ARM64 | 可能 | |
x86_64 | ARM64 | x86_64 ( arch ) | x86_64 | 可能 | |
x86_64 | ARM64 | ARM64 | ARM64 | 可能 | |
ARM64 | x86_64 | x86_64 | x86_64 | 可能 | |
ARM64 | x86_64 | ARM64 ( arch ) | ARM64 | 可能 | |
ARM64 | ARM64 | x86_64 ( arch ) | x86_64 | 可能 | 対象が ARM64 未対応時 |
ARM64 | ARM64 | ARM64 | ARM64 | 可能 | 基本 |
設定の要点はこうですね。
- ターミナルとシェルを複数インストールする必要はない
- ARM64 を基本として、困ったときだけ x86_64 バイナリを取得する
-
brew
はarch -arm64e /opt/homebrew/bin/brew
のエイリアスにする - もう一方は
brew86 ( arch -x86_64 /usr/local/bin/brew )
みたいな alias にする
-
- 取得バイナリがなんであれ、ARM64 ターミナルから全然気にしないで使える
-
$PATH
は ARM64 バイナリの方 > x86_64 バイナリの方 の優先順位で設定しておく - もし x86_64 シェルが使いたければ、デフォルトのユニバーサルバイナリで十分
-
zsh86 ( arch -x86_64 /bin/zsh )
みたいな alias を使う
-
参考にした記事
公開後追記 ( 2021/08 )
いくつか指摘をいただいたので、ここで訂正および補足をします。
1. コマンドのペーストミス
同じく前の章では割愛しましたが、ただ x86_64 ターミナルから ARM64
brew
を使うことはできません。
でのコマンドが arch -arm64 /opt/homebrew/bin/brew install mysql-client
になっていましたが、これだとエラーになりません。
本文を訂正しました。
2. brew の実態について補足 1
/opt/homebrew/bin/brew
と /usr/local/bin/brew
はどちらも Homebrew/brew を持ってきているはずなので、実態自体には差分はありません。
shebang が /bin/bash
になっているからどちらのアーキテクチャでも動くようです。
$ diff -u /usr/local/bin/brew /opt/homebrew/bin/brew
$ head -n 1 /usr/local/bin/brew
#!/bin/bash
2. brew の実態について補足 2
brew
は実行環境のガードに HOMEBREW_PREFIX
という値を使っています。
これは叩いた brew
のインストール場所に応じているようで /usr/local
か /opt/homebrew
になり、それが変に捻れていないかを判定しています。
HOMEBREW_DEFAULT_PREFIX
が /usr/local
で HOMEBREW_MACOS_ARM_DEFAULT_PREFIX
が /opt/homebrew
でしょう。
def check_prefix
if (Hardware::CPU.intel? || Hardware::CPU.in_rosetta2?) &&
HOMEBREW_PREFIX.to_s == HOMEBREW_MACOS_ARM_DEFAULT_PREFIX
if Hardware::CPU.in_rosetta2?
odie <<~EOS
Cannot install under Rosetta 2 in ARM default prefix (#{HOMEBREW_PREFIX})!
To rerun under ARM use:
arch -arm64 brew install ...
To install under x86_64, install Homebrew into #{HOMEBREW_DEFAULT_PREFIX}.
EOS
else
odie "Cannot install on Intel processor in ARM default prefix (#{HOMEBREW_PREFIX})!"
end
elsif Hardware::CPU.arm? && HOMEBREW_PREFIX.to_s == HOMEBREW_DEFAULT_PREFIX
odie <<~EOS
Cannot install in Homebrew on ARM processor in Intel default prefix (#{HOMEBREW_PREFIX})!
Please create a new installation in #{HOMEBREW_MACOS_ARM_DEFAULT_PREFIX} using one of the
"Alternative Installs" from:
#{Formatter.url("https://docs.brew.sh/Installation")}
You can migrate your previously installed formula list with:
brew bundle dump
EOS
end
end
これを見る限り、arch
を使うにしても brew
自体は 2 箇所にインストールしておかないとだめですね。
案の定 arch
で x86_64 を指定して ARM brew
を叩いてもエラーになりました。
$ uname -m
arm64
$ arch -x86_64 /opt/homebrew/bin/brew install mysql-client
Error: Cannot install under Rosetta 2 in ARM default prefix (/opt/homebrew)!
To rerun under ARM use:
arch -arm64 brew install ...
To install under x86_64, install Homebrew into /usr/local.
3. arch コマンドについて補足 1
Rosetta を入れると
arch
と言うコマンドが使えるようになります。
arch
コマンド自体は Intel Mac にも入っていました。
Intel Mac と ARM Mac の man arch
を抜粋して掲載します、興味がある方は読んでみてください。
man arch ( Intel Mac )
DESCRIPTION
The arch command with no arguments, displays the machine's architecture type.
The other use of the arch command it to run a selected architecture of a universal binary. A universal binary contains code that can run on different architectures. By default, the operating system will select the architecture that most closely matches the processor type. This means that an intel architecture is selected on intel processors and a powerpc architecture is selected on powerpc processors. A 64-bit architecture is preferred over a 32-bit architecture on a 64-bit processor, while only 32-bit architectures can run on a 32-bit processor.
When the most natural architecture is unavailable, the operating system will try to pick another architecture. On 64-bit processors, a 32-bit architecture is tried. If this is also unavailable, the operating system on an intel processor will try running a 32-bit powerpc architecture. Otherwise, no architecture is run, and an error results.
The arch command can be used to alter the operating system's normal selection order. The most common use is to select the 32-bit architecture on a 64-bit processor, even if a 64-bit architecture is available.
The arch_name argument must be one of the currently supported architectures:
i386 32-bit intel
x86_64 64-bit intel
man arch ( ARM Mac )
DESCRIPTION
The arch command with no arguments, displays the machine's architecture type.
The other use of the arch command is to run a selected architecture of a universal binary. A universal binary contains code that can run on different architectures. By default, the operating system will select the architecture that most closely matches the processor type. A 64-bit architecture is preferred over a 32-bit architecture on a 64-bit processor, while only 32-bit architectures can run on a 32-bit processor.
When the most natural architecture is unavailable, the operating system will try to pick another architecture. On 64-bit processors, a 32-bit architecture is tried. Otherwise, no architecture is run, and an error results.
The arch command can be used to alter the operating system's normal selection order. The most common use is to select the 32-bit architecture on a 64-bit processor, even if a 64-bit architecture is available.
The arch_name argument must be one of the currently supported architectures:
i386 32-bit intel
x86_64 64-bit intel
x86_64h 64-bit intel (haswell)
arm64 64-bit arm
arm64e 64-bit arm (Apple Silicon)
微妙に内容が違いますね、powerpc
という単語が見えます。
Rosetta 1 および macOS における 32bit と 64bit の混在のために使われているようです。
参考
3. arch コマンドについて補足 2
arch -arm64
よりは arch -arm64e
の方が適切そうですが、よしなに解釈してくれるみたいなので打つのが楽な方を使っていました。
brew
のエラーメッセージも arch -arm64
付けてみたらどうだと言っていますし、理解していればどちらもで良いと僕は思います。
と思っていましたが、本文は全て -arm64e
に訂正しました。
-
Rosetta を入れた後に知ったので自分の手で確認したわけではありませんが。 ↩︎