M1版Macでのコマンドライン開発環境の雑多なこと


1. M1でIntel CPU版コマンドラインツールを使う

早い話が前回の記事 Apple M1のサポートする命令など の続きである。

Rosettaで動かすためにターミナルを複製する

全てのユニバーサルバイナリは明示的にRosettaで動作させることができるが、Rosetta版とネイティブ版を両方つかいたいケースは割とあると思う。ターミナルは特にそうである。
そんなわけでターミナル.appをコピーしてx86版プログラムを動かしたい方だけRosetta動作に設定した。なんなら見分けがつきやすいようにアイコンファイル(.icns)も書き換えようかなと思っている。

留意点

なお、Universal Binaryが用意されていないVisual Studio CodeではRosetta版ターミナルが実行される。つまりx86-64版clangその他のコマンドラインツールが実行される。
よって、M1ネイティブの開発をするのに内蔵のターミナルを使うのはちょっと控えた方がいい。あるいはRosettaのコマンドライン環境でもaarch64ホストへのクロス開発可能なコンパイラを別途導入する。

2. Homebrewのインストール

まず、ARM版はようやく対応したところで個々のアプリは正常にインストール・使用できないことがあるので、現時点ではRosettaでIntel版を動かした方が賢明である。

ARM Mac版をどうしても試したい方

一応、ARM Macネイティブ版は以下の手段でインストールまでは確認しているが対応していないプログラムの方が多いので参考に止める。
なお、/opt/homebrewはユーザー権限で読み書き実行権限を付与しておかれたい。

cd /opt/homebrew 
curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C .

/opt/homebrewというパスが存在するIntel版(Rosettaで動作)の方のHomebrew環境と競合するらしいので、どちらか一方を選択的にインストールすることになるだろう
(現状を考えればIntel版の方がいい)

HomebrewもIntel版なら当面は安心?

Rosettaで起動したターミナルからHomebrewをインストールすればIntel版Homebrewがそのまま使える。アプリレベルではまだARM Mac版の対応が不完全なので、こちらを選んだ方がいい。
当面はM1ネイティブで動作させたいものをaarch64向けにクロスコンパイルしながら段階的にM1ネイティブの開発環境を揃えていく形になりそうなので、Rosettaとネイティブのターミナルの行き来は割と頻繁にありそう。

3. clangでの開発

これがネイティブ起動とRosetta起動のターミナルを並べて双方のclangのオプションの違いを見比べてみたものである。

Rosetta上での -march=native は危険な感じがする

Rosettaでの -march=native で実行しているのだが、何やらサポートしないはずのAVX2からAVX512IFMAやらGFNIやらがオプション候補として出てきて不穏なので、M1のMacのRosetta環境で動くx86-64プログラムをビルドするときは念の為に -march=westmere を使った方がいいと思われる。
ひょっとしてこいつ自分のことをMacBook Pro 2020(Intel)だと思い込んでるMacBookPro 2020 (Apple)なのでは? とか考えたけど不毛なので考えるのをやめた。

AVX*向けにビルドすればIntel Macで動くバイナリは作れる

AVX*のコードはM1のマシンでは直接実行できないので、動作確認には実機を用意する必要があるが、一応AVX〜AVX-512までのプログラムもビルドできる。Intel MacにAirDropで転送してリモートで実行すれば、手元のM1マシンから離れる必要はないだろう。
リモートデバッグまではちょっと面倒なので状況次第であるが。

そういうわけで、Intel Mac向けにしばらく開発予定がある方は、念の為にIntel Mac実機は手元に残しておいた方がいいかもしれない。AVX-512が動くMacである必要はないかもしれないけど、念の為、MBA2020(Intel)がディスコンになったのでMBP13-2020(Intel)が最も安いAVX-512対応Intel Macで16インチの方はAVX-512非対応である。