M1 Mac の環境構築メモ

M1 Mac 環境構築のメモ

清水です。こんにちは。 M1 の環境構記事は世の中に溢れていますが、MKで役に立ちそうな内容を中心に記述します。

前提知識

linux とかMac ではCPU のアーキテクチャーに名前がついています。

Intel の64bit アーキテクチャ

x86_64 とか amd64 って言います。 Intel が昔作った x86 というCPUと互換性があるため x86_64 と言います。 歴史的に今の普通の人が使っている 64bit のIntel CPUのアーキテクチャーは、Athlon 64 という名前でAMD が作ったため、敬意を示してamd64 と言いますarm64 と極めて見間違えやすいです。

Apple M1 CPUのアーキテクチャー

arm64 って言います。 ちなみに ARM の32bit アーキテクチャはarmhf とか armv7lと言います。RaspberryPIでよく見かけるアーキテクチャでしたが、Raspberry PI も64ビットをサポートしたので、徐々に消えていくでしょう。 https://www.raspberrypi.com/news/raspberry-pi-os-64-bit/

Rosetta2

macOS では、Rosetta 2 という x86_64 環境のエミュレーターがインストールされています。 Rosetta 2 はよくできていて arm64 バイナリから x86_64 バイナリの呼び出しも、x86_64バイナリから、arm64 のバイナリの呼び出しも両方サポートされています

Apple M1 のHomebrew について

Homebrew はインストールされたbrew のアーキテクチャごとに、インストールするバイナリが異なります。 なのでM1 の環境に、x86_64のbrew とarm64 のbrew を混在させることができます

一部のパッケージはx86_64しか提供されていないものがあるとのことです。 またcask 等はarm64 版のbrewでインストールしても勝手にx86_64 が入るものもあります。 x86_64 のbrew をarm64 のbrew はインストールされる先のディレクトリが異なります。

  • /usr/local 配下: x86_64
  • /opt/homebrew 配下: arm64

https://brew.sh/index_ja Homebrew のトップページに書いてある下記のインストールコマンドは、現在の uname -m がx86_64かarm64 かどちらかによって、インストールするbrew のバイナリを決定します。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

よく使うコマンド

  • file $(which sqlcmd) file コマンドにバイナリを渡すと、実行コマンドがarm64 なのかx86_64なのかを表示することができます。
  • uname -m 自分のシェルのアーキテクチャを表示します
  • arch -arch x86_64 /bin/zsh x86_64 のシェルを立ち上げます

brew のパッケージインストール戦略

インターネット上にはパスを切り替えてx86_64 とarm64 を完全に分けて使っている記事や、Terminal.app をコピペして、Rosetta2で動かすオプションを付けて切り替えをしている記事がが多々見られますが、Rosetta2は実行時にどちらのバイナリからどちらのバイナリの呼び出しも実行することができるため清水はバイナリを混在させて使うことにしました。

  • 原則arm64 のバイナリを使う
  • brew はarm64版と、x86_64版を両方インストールして、arm64が動かないものや提供されてないものは、x86_64を使う
  • パスを /opt/homebrew/bin → /usr/local/bin の優先順位にすることで、arm64 が優先的に実行されるようにする
  • ややこしいのでx86_64 とarm64 のバイナリを両方インストールしないように注意する
    • openssql とかライブラリ系は両方インストールされてしまいますが、問題な無いのであきらめます
  • x86_64版を使いたいときは arch -arch x86_64 brew XXX で実行する

brew 自体のインストール

brew はarm64バージョンと、x86_64バージョンの両方をインストールします https://github.com/Homebrew/brew/issues/9173

# arm64のインストール
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# x86_64のインストール
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

ちなみにbrew tap は、arm64と、x86_64 でそれぞれ独立して設定が保持されます。

パッケージのインストール brew install PACKAGE をつかって、原則arm64 をインストールしますが、動かないものは arch -x86_64 brew install PACKAGE を使ってx86_64 をインストールします

プロセスがRosettaで動いているかどうかの確認

アクティビティモニタ.app で確認ができます。 種類がIntel になっているプロセスは Rosetta配下で動作しています。

activity

docker について

Docker for mac を使うとarm64 アーキテクチャのdocker が動きますが、arm64アーキテクチャでdocker を動かしたい人は世の中にいないので(暴言)、amd64(x86_64) で動かします。 x86_64 のdocker 実行環境ををmac で構築するには colima を使います。

インストールはここを見ます。 https://github.com/abiosoft/colima

そのまま colima start を叩くと、arm64 のdockerが動くようになってしまって意味がないので、colima start --arch x86_64 を叩きます。

こうなったら成功です

$ colima list
PROFILE    STATUS     ARCH      CPUS    MEMORY    DISK
default    Running    x86_64    2       2GiB      60GiB

動作確認

$ docker run --rm -ti ubuntu bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
125a6e411906: Pull complete
Digest: sha256:26c68657ccce2cb0a31b330cb0be2b5e108d467f641c62e13ab40cbec258c68d
Status: Downloaded newer image for ubuntu:latest
root@a356d6d87fff:/# uname -a
Linux a356d6d87fff 5.10.93-0-virt #1-Alpine SMP Thu, 27 Jan 2022 09:34:38 +0000 x86_64 x86_64 x86_64 GNU/Linux

x86_64 が出ているので完璧ですね。

docker-compose について

docker-compose.yml に platform: linux/x86_64 を追加するとdocker pull のイメージのアーキテクチャーを指定することもできますが、指定しなくてもデフォルトでdocker 実行環境のアーキテクチャが採用されます。そのためcolima でx86_64 のアーキテクチャがちゃんと構築できていればこの設定は不要です。

dotnet-sdk について

Intell Mac 環境で、dotnet-sdk を使い、複数バージョンを共存させる場合、

  1. dotnet-sdk versions tap を brew tap する https://github.com/isen-ng/homebrew-dotnet-sdk-versions
  2. 古いバージョンのdotnet-sdk を入れる 例: brew install isen-ng/dotnet-sdk-versions/dotnet-sdk5-0-400
  3. 最新のバージョンのdotnet-sdk をインストールする brew install dotnet-sdk

ことで、プロジェクトにおいてある global.json を 最新のdotnet-sdk がいい感じに参照してくれて複数バージョンの共存がいい感じに動作するのですが、 dotnet-sdk 6 はネイティブでarm64環境をサポートしてしまっているためか、VSCode + .NET 6 => .NET5x の参照状態でブレイクポイントを使ったデバッグがうまく動きません。

6を使う必要がない場合、

  1. dotnet-sdk versions tap を brew tap する https://github.com/isen-ng/homebrew-dotnet-sdk-versions
  2. 古いバージョンのdotnet-sdk を入れる 例: brew install isen-ng/dotnet-sdk-versions/dotnet-sdk5-0-400
  3. sudo ln -s /opt/homebrew/bin/dotnetx64 /usr/local/bin/dotnet

こうしたったら動きました。 6もx86_64で入れてしまえば良い気もします。

関係しそうなIssue (動いてしまったので、バージョン共存は問題になっていないので読んでないです。困ったら読む) https://github.com/dotnet/runtime/issues/59168 https://github.com/dotnet/installer/issues/11164

mssql-tools

上の.NET5 のプロジェクトがunixodbc を参照していますが、x86_64 のダイナミックリンクバイナリーを要求してきますので、x86_64 版を入れます。 sqlcmd も使いたいので、mssql-tools ごと、x86_64でインストールしてしまいます。

https://docs.microsoft.com/ja-jp/sql/connect/odbc/linux-mac/install-microsoft-odbc-driver-sql-server-macos?view=sql-server-ver15

arch -x86_64  brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
arch -x86_64  brew install msodbcsql17 mssql-tools

nodejs

asdf install nodejs 14.15.0
... 中略
make[1]: *** No rule to make target `/private/var/folders/5k/zm33wz5n3f96x2763t5ql4dm0000gn/T/node-build.20220506125735.59310.ec2k6p/node-v14.15.0/out/Release/obj.target/openssl/deps/openssl/openssl/ssl/ssl_quic.o', needed by `/private/var/folders/5k/zm33wz5n3f96x2763t5ql4dm0000gn/T/node-build.20220506125735.59310.ec2k6p/node-v14.15.0/out/Release/libopenssl.a'.  Stop.

nodejs 14.15.0 はコンパイルできない 新しいバージョンを使うか、x86_64版を入れる

x86_64はこのコマンドで入る

arch -x86_64 asdf install nodejs 14.15.0

ruby

ruby2.6.6

ruby-build.20220506143208.6954.log

... 中略
closure.c:264:14: error: implicit declaration of function 'ffi_prep_closure' is invalid in C99 [-Werror,-Wimplicit-function-declaration]

RUBY_CFLAGS=-DUSE_FFI_CLOSURE_ALLOC asdf install ruby 2.6.6

cf: https://github.com/ffi/ffi/issues/869#issuecomment-752123090

sassc

bundle install
... 中略
Installing sassc 2.2.1 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/katsusuke/git/github.com/value-promotion/shiraseru-web/vendor/bundle/ruby/2.7.0/gems/sassc-2.2.1/ext
/Users/katsusuke/.asdf/installs/ruby/2.7.6/bin/ruby -I /Users/katsusuke/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0 -r ./siteconf20220506-86580-r5kv95.rb extconf.rb
creating Makefile

current directory: /Users/katsusuke/git/github.com/value-promotion/shiraseru-web/vendor/bundle/ruby/2.7.0/gems/sassc-2.2.1/ext
make "DESTDIR=" clean

current directory: /Users/katsusuke/git/github.com/value-promotion/shiraseru-web/vendor/bundle/ruby/2.7.0/gems/sassc-2.2.1/ext
make "DESTDIR="
compiling ./libsass/src/units.cpp
clang: error: the clang compiler does not support '-march=native'
make: *** [units.o] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/katsusuke/git/github.com/value-promotion/shiraseru-web/vendor/bundle/ruby/2.7.0/gems/sassc-2.2.1 for inspection.
Results logged to /Users/katsusuke/git/github.com/value-promotion/shiraseru-web/vendor/bundle/ruby/2.7.0/extensions/arm64-darwin-21/2.7.0/sassc-2.2.1/gem_make.out

An error occurred while installing sassc (2.2.1), and Bundler cannot continue.
Make sure that `gem install sassc -v '2.2.1' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  rails_admin was resolved to 2.2.1, which depends on
    sassc-rails was resolved to 2.1.2, which depends on
      sassc

cf: https://qiita.com/mmaumtjgj/items/ca07d3149a4f5577c667

bundle config build.sassc  -- --disable-march-tune-native

番外編

開発と関係ないですがハマった奴ら

OneDrive

OneDriveの現行最新版はx86_84で動作するのですが、ヤバいくらい激重です。 Microsoft から出ている開発版を使うと、許せる速度で動作します。

ここからDLします (Standalone for Apple silicon devices) と書いてあるやつをDLします https://support.microsoft.com/en-us/office/onedrive-release-notes-845dcf18-f921-435e-bf28-4e24b95e5fc0#OSVersion=Mac

2022/05/04時点の注意点として、Apple silicon版は、iCloud ドライブ的な挙動をするような変更が加われており、すでにx86_64版がインストールされた状態から、そのまま上書きでインストールするとバグります。 下記の手順でインストールすると動きました。

  1. OneDrive→基本設定→「このMacのリンクを解除」をクリックする
  2. /Applications/OneDrive.app/Contents/Resources/ResetOneDriveAppStandalone.command を実行する(インストールされているバージョンが違うと ResetOneDriveAppStandalone.command の名前が違う場合があるらしいです)
  3. /Applications/OneDrive.app をゴミ箱に入れる
  4. OneDriveの開発版を入れる
  5. ログインする
この記事をシェア

弊社では、一緒に会社を面白くしてくれる仲間を募集しています。
お気軽にお問い合わせください!