public memo

エンジニア向け小ネタ書き溜め用。公開日記だけど親切な文章とは程遠いかもしれない。

M1 MacでAppleシリコンとIntelプロセッサのバイナリ管理を分離して共存させる

2022-02-21 by MasakiMisawa
Tweet
このエントリーをはてなブックマークに追加
Pocket
LINEで送る

前回の記事でApple シリコンCPUの環境から特定バージョン未満のTerraformを無理やり動かせる方法を書きましたが、他にも幾つかIntelプロセッサ用にしかバイナリが提供されていないものが出てきたり、前回の方法がかなり無茶な内容だった事もあり、「流石に毎回その場凌ぎ対応で乗り切るのは無理がある」ということで、改めてM1 Macでのローカル開発環境を作り直してみた内容のメモです。

前提

1. AppleシリコンCPUへの世の中的な対応は追いついておらず、arm64バイナリが提供されていないものはまだ多い

かなり普及してきたM1 Macですが、2022年2月現在ではまだ周辺の対応が追いついていない状態で、同環境から開発時に必要となるものをダウンロードしようとするとApple シリコン用のバイナリが提供されていないケースがまだ結構発生します。
時間の経過とともに徐々に改善されていくとは思いますが、まだしばらくは開発時に必要となるものでApple シリコン用バイナリが存在しないケースが発生することはある程度想定しておく必要がありそうです。

2. 恒久対応は、対応バージョン以上までVUPする方法

Appleシリコン用が存在しないものもまだ多い現状ですが、少しずつ対応は進んできておりarm64のバイナリが提供されているものもかなり多いです。
ですが、前回の記事で書いたTerraformを含む多くはバージョンxxx以上でのみ対応というケースが多く、同バージョン未満では提供されていない場合が多いです。

ですので、恒久対応は使用するバージョンをバイナリが提供されているバージョン以上まで上げることです。
バージョンアップが難しい場合もありますが、可能な限りバージョンアップができないかを検討してみるのをお勧めします。

3. バイナリが提供されていないバージョンでの対応は、無理やりな暫定対応に頼らざるを得ない

これはもう仕方ない面が大きいですが、バイナリが提供されていない状態で無理やり使えるようにする方法は、どうしても無理やりな暫定対応になります。
Appleシリコン環境にIntelプロセッサ用のバイナリを手動でダウンロードしてきてシンボリックリンクを無理やり貼ったりなどがそうですね。

とは言っても、諸々の事情ですぐにバージョンアップは難しかったり、そもそもバージョンに関係なくバイナリが提供されていないなんて場合もあります。
今回対応するのはそんなケースにも対応できる方法で、M1 MacなどのAppleシリコンCPU環境で今後開発していく上で有効な選択肢の一つになると思います。

対応方針

どうやって対応するかですが、今回は以下の方針で対応することにしました。

同一マシン上に二つの環境を作って管理を完全に分離した形で共存させる

違うCPU用のバイナリを無理やり動かすのはどうやっても無理があるのですっぱりと諦めて、それぞれのCPU用の環境を同一マシン上に二つ作る形です。
また、同一ホスト上に仮想環境を二つ作るまでやると少し大変な為、今回はそこまで大がかりなものではなく、各種バイナリをダウンロードするターミナル環境と、ダウンロードしたものの管理場所を分けるだけの以下のようなイメージです。

Macのアプリケーションなどマシン一台につき一つしか入れられないものは共通で使い、Homebrewや各種バージョン管理用のenvなどはそれぞれの環境用に分離して別で管理する形です。
Macのアプリケーションも複製すると一つのアプリケーションを複数個に分けて持てますが、バージョンアップで複製したアプリケーションが消えてしまったりなど無理に分けるのは止めた方が良さそうです。

Appleシリコン/Intelプロセッサ用の環境用意

方針が決まったところで、それぞれの環境の用意を進めていきます。

1. 作業前環境のお掃除

二つの環境の用意を始める前に、作業前の環境にAppleシリコン用とIntelプロセッサ用のバイナリがごちゃ混ぜに共存している場合は、一度環境を掃除します。
この手順はSKIP可ですが、異なる環境用のバイナリが同一パスにごちゃ混ぜになっている状態だと今後予期せぬトラブルにハマってしまわないようにする為にも、一度綺麗にしておくことをお勧めします。

以下の手順ですぐに終わるのと、基本的には全て復元可能です。

  1. 作業前に使用していたHomebrewの内容をメモ
  2. ZSH
    1
    $ brew list

    表示された一覧をどこかにメモしておきます。

  3. Homebrew を一度アンイントール
  4. ZSH
    1
    2
    3
    4
    $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
    Warning: This script will remove:
    ...
    You may wish to remove them yourself.

    途中で一度本当に消すか聞かれるので、yesで進ませます。

2. 普段使っているターミナルアプリをRosettaを非有効化して起動

Mac純正のターミナルやiTermなどターミナル用のアプリは複数ありますが、普段使用しているターミナルアプリをRosettaを非有効化した状態で起動します。

Rosettaは、特定のアーキテクチャのプログラムコードを持つバイナリを、別のアーキテクチャ用のアーキテクチャ用に適宜変換してバイナリの互換性を維持するAppleの技術で、Appleシリコン用の実行環境のターミナルアプリをIntelプロセッサ用の実行環境で開かせたりなどができます。
また、各アプリケーション毎の設定で有効化/非有効化を切り替えられます。
自分は普段iTermをメインで使用している為、iTermをメインのターミナルアプリとして話を進めます。

開発メイン用のターミナルはRosettaを非有効化して起動するので、Appleシリコン用として動作します。

ZSH
1
2
$ uname -m
arm64

ハイスペックなM1 Macを使っている以上、AppleシリコンのCPUではバイナリが存在せず操作が実行できないなどの場合を除き、可能な限りこの環境を使用して普段の開発を行なっていきます。

3. arm64環境にHomebrewインストール

Homebrewのアンインストールを飛ばした場合は、この手順もSKIPしてください。

Homebrewのインストールは、公式に載っている以下コマンドを打つだけです。

ZSH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
...
==> Installation successful!
 
==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics
 
==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations
==> Next steps:
- Run `brew help` to get started
- Further documentation:
    https://docs.brew.sh

arm64用のHomebrewは、 /opt/homebrew/ 配下にインストールされます。

ZSH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/
└── opt
    └── homebrew
        ├── CHANGELOG.md
        ├── CONTRIBUTING.md
        ├── Dockerfile
        ├── LICENSE.txt
        ├── Library
        ├── README.md
        ├── SECURITY.md
        ├── bin
        ├── completions
        ├── docs
        └── manpages

インストールが完了したらパスを通すところまでやっておきます。

ZSH
1
2
3
4
$ export PATH="$PATH:/opt/homebrew/bin" >> ~/.zshrc
$ source ~/.zshrc
$ which brew
/opt/homebrew/bin

M1 Macデフォルトのzsh用にパスを追記していますが、ログインシェルに別のものを使用している場合は追記する設定ファイルを適宜置き換えてください。

4. アンインストール前にメモしたHomebrewパッケージの再インストール

上記に同じく、Homebrewアンインストールを飛ばした場合はSKIPしてください。
また、バージョン管理用の各種envパッケージをインストールした場合のログインシェルの設定ファイルへのパス追記なども必要に応じて行なってください。

ここでAppleシリコン用のバイナリが提供されていないバイナリを無理やり手動でダウンロードするなどは絶対に行わないようにしてください。
Intelプロセッサ用のバイナリをAppleシリコン用の管理環境に混入してしまうと、環境を分けた意味が無くなってしまいます。

5. 普段使っているターミナルアプリとは別のアプリでRosettaを有効化して起動

arm64環境が一旦できたので、続いてIntelプロセッサ用の環境を作成していきます。
普段使っているターミナルのアプリとは別のアプリケーションを、Rosettaを有効化した状態で起動します。
自分はメインターミナルがiTermだったので、Mac純正のターミナルアプリをサブとして使用します。

今度はRosettaを有効化して起動するので、Intelプロセッサ用として動作します。

ZSH
1
2
$ uname -m
x86_64

Intelプロセッサ用の環境はAppleシリコン用のバイナリが提供されていないものを動かす時にだけ使用するもので、普段は起動させない環境です。

6. Intelプロセッサ用環境にHomebrewインストール

Intelプロセッサ用にもHomebrewをインストールしていきますが、普通に入れるとAppleシリコン用のHomebrewとパスが被ってしまうので、別のインストール先を用意して手動で入れる形を取ります。
今回は、/opt/homebrew-x86_64/配下に入れることにします。

ZSH
1
2
3
$ sudo mkdir /opt/homebrew-x86_64
$ sudo chown `whoami`:staff /opt/homebrew-x86_64
$ curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C /opt/homebrew-x86_64

インストール完了後のディレクトリ構成は以下のようになります。

ZSH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/
└── opt
    ├── homebrew
    │   ├── CHANGELOG.md
    │   ├── CONTRIBUTING.md
    │   ├── Dockerfile
    │   ├── LICENSE.txt
    │   ├── Library
    │   ├── README.md
    │   ├── SECURITY.md
    │   ├── bin
    │   ├── completions
    │   ├── docs
    │   └── manpages
    └── homebrew-x86_64
        ├── CHANGELOG.md
        ├── CONTRIBUTING.md
        ├── Dockerfile
        ├── LICENSE.txt
        ├── Library
        ├── README.md
        ├── SECURITY.md
        ├── bin
        ├── completions
        ├── docs
        └── manpages

7. Appleシリコン環境とIntelプロセッサ環境でHomebrewの環境変数パスを変更させる

Intelプロセッサ用のHomebrewを/opt/homebrew-x86_64 に手動インストールしましたが、ログインシェルの環境変数にパスを通していないのでこの段階ではまだ認識されません。
この段階で which brew を打つと、Appleシリコン用のHomebrewのパスが表示されます。

起動中のターミナルの実行環境(Appleシリコン環境 or Intelプロセッサ環境)により設定する環境変数のパスを切り替える必要があるので、ログインシェルの設定ファイルを以下のように変更します。

1
2
3
4
5
6
7
if [ "$(uname -m)" = "arm64" ]; then
  export PATH="$PATH:/opt/homebrew/bin"
  // Appleシリコン用のHomebrewで入れた各種env用のパスはここに書く
else
  export PATH=$PATH:/opt/homebrew-x86_64/bin
  // Intelプロセッサ用のHomebrewで入れる各種env用のパスはここに書く
fi

上記のようにIntelプロセッサ用のHomebrewの環境変数を書くと、/opt/homebrew-x86_64/bin がHomebrewのパスとして認識されるようになります。

ZSH
1
2
3
$ source ~/.zshrc
$ which brew
/opt/homebrew-x86_64/bin

念のために、Appleシリコン環境のメインのターミナルで再度Homebrewのパスを確認しておきます。

ZSH
1
2
$ which brew
/opt/homebrew/bin

実行環境によりHomebrewのパスが制御できているのが確認できます。

8. Intelプロセッサ環境のHomebrewにパッケージインストール

Intelプロセッサ環境のHomebrewにもパッケージをインストールします。
こちらの環境にインストールするのは、Appleシリコン用のバイナリが提供されていないものなど必要最小限のパッケージだけです。

また、バージョン管理用の各種env用に設定する環境変数のパスについても、Homebrewと同じくAppleシリコン用のHomebrewで入れたenvで設定しているパスとは完全に分けたパスを設定します。

pyenvのパス設定を例に出すと、ログインシェルの設定ファイルへの記載は以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
if [ "$(uname -m)" = "arm64" ]; then
  export PATH="$PATH:/opt/homebrew/bin"
  export PYENV_ROOT="$HOME/.pyenv"
  export PATH="$PYENV_ROOT/bin:$PATH"
  eval "$(pyenv init --path)"
  eval "$(pyenv init -)"
else
  export PATH=$PATH:/opt/homebrew-x86_64/bin
  export PYENV_ROOT="$HOME/.pyenv_x86_64"
  export PATH="$PYENV_ROOT/bin:$PATH"
  eval "$(pyenv init --path)"
  eval "$(pyenv init -)"
fi

それぞれのパスが効いているのを確認します。

ZSH
1
2
$ which python
/Users/masakimisawa/.pyenv_x86_64/shims/python

ZSH
1
2
$ which python
/Users/masakimisawa/.pyenv/shims/python

長くなりましたが、以上で全ての設定が完了です。
Appleシリコン用のバイナリが存在しない問題はM1 Macで長く開発をしていくと避けては通れないので、多少面倒でも最初に開発環境を作っておくと後々便利です。

今回は以上になります。

参考

Qiita
 
5 Users
3 Pockets
Apple Silicon (ARM, M1) のmacOSにaarch64とx86_64のhomebrewを共存させる - Qiita
https://qiita.com/chibiegg/items/43b7604a589e3760e88e
ARM版Macで開発を始めている方も多いかと思います。Rosetta2やDocker Desktop on macのおかげでウェブ開発において全く開発ができないということはないんじゃないかと思います。一方で、Dockerを使わず...
Tweet
このエントリーをはてなブックマークに追加
Pocket
LINEで送る

カテゴリー: M1 Mac タグ: env, Homebrew, M1 Mac

profile

profile_img Web系のソフトウェアエンジニアです。
野球観戦(横浜DeNAベイスターズ)、格闘ゲーム、カメラ、ランニング、愛犬、インテリア、美味しいものの食べ歩き、などなどが好き。

  • twitter MasakiMisawa
  • facebook MisawaMasaki
  • github MasakiMisawa
  • instagram masakimisawa
  • follow us in feedly

search

recent entry

  • M1 MacでAppleシリコンとIntelプロセッサのバイナリ管理を分離して共存させる
  • M1 MacでtfenvからTerraform1.0.2未満のダウンロードに失敗する問題を無理矢理解決する
  • GitHub ActionsからAWS利用時に永続的クレデンシャル情報を渡さないようにする
  • TerraformでAuroraのエンジンバージョンアップグレードをする時は、対象リソースをクラスターだけに絞る
  • CloudWatch Logsに出力されたエラーログ本文のSlackへの転送

category

  • AWS (17)
    • ACM (1)
    • AWS CLI (1)
    • Chatbot (2)
    • CloudWatchAlarm (1)
    • CloudWatchLogs (1)
    • CodeBuild (3)
    • DynamoDB (1)
    • IAM (1)
    • Kinesis (2)
    • Lambda (5)
    • OpenId Connect (1)
    • RDS (1)
    • S3 (2)
    • SNS (2)
    • SSM (2)
    • STS (1)
  • CI (2)
  • GCP (1)
    • PageSpeedInsights (1)
  • Git (3)
    • GitHub (2)
      • GitHub Actions (1)
  • M1 Mac (2)
  • Python (2)
  • Redis (1)
  • selenium (1)
  • Slack (3)
  • Terraform (3)
  • その他 (1)

archive

  • 2022年2月 (3)
  • 2021年1月 (1)
  • 2020年12月 (1)
  • 2020年11月 (1)
  • 2020年9月 (2)
  • 2020年8月 (1)
  • 2020年7月 (1)
  • 2020年6月 (1)
  • 2020年5月 (2)
  • 2020年4月 (1)
  • 2020年3月 (1)
  • 2020年1月 (1)
  • 2019年1月 (1)
  • 2017年12月 (1)
  • 2017年9月 (1)
  • 2017年8月 (1)
  • 2017年7月 (1)
  • 2017年2月 (1)
  • 2016年10月 (1)

tag cloud

ACM Aurora AWS AWS CLI Billing CI CloudWatchAlarm CloudWatch Logs CodeBuild Code Format Docker DynamoDB EC2 env find firehose Git GitHub GitHub Actions Homebrew husky IAM Role Java kinesis KinesisFirehose Lambda lint-staged M1 Mac Node.js OpenId Connect PHP Python RDS Redis RI S3 Selenium Slack SNS SSM Terraform tfenv セッションマネジャー リモートワーク 生産性

Copyright © 2023 public memo.