8
7

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 3 years have passed since last update.

M1 Macで、arm64とx86_64のruby環境を共存させて、Flutterの環境構築

Last updated at Posted at 2021-04-22

概要

  • MacbookAir BigSur, Apple M1 チップ

において、

  • Flutter(AndroidStudio)

の開発環境を最低限構築したが、
とてもとても大変だったのでメモを残す。

m1 Macにおいてruby環境をどうコントロールするか
という点がメインの話になるので、Flutterに関わらず ruby周りで困っている人 は見て頂ければ幸いです。

以下の方針。

  • arm64x86_64、それぞれの独立ターミナル環境を構築
  • rubyはそれぞれ別個にインストールしなおす(macデフォルトrubyを使わない)
  • AndroidStudio は内部でx86_64でターミナルを起動しているようなので、x86_64の方の環境でflutter環境を整える
  • arch -x86_64コマンドは使わない!!

特に最後。
M1 Macでcocoapods周りで上手く行かないときに、解決策として、

arch -x86_64 sudo gem install cocoapods

がサイトによく載っているが、相当しっかり理解している人でない限り、
これはしない方が良いので注意が必要(最後に詳しく述べます)。

おまけ

  • AndroidStudioのPreferenceを開くとフリーズする問題
    • 以下の記事を参考にさせて頂きました
    • タブでPreferencesを開こうとするとフリーズするようです
    • 自分の環境ではデフォルト設定だと、フルスクリーン状態でなければ新規ウィンドウで開かれるので、AndroidStudioをフルスクリーンではなくした後にPreferencesを開くことで解決しました

M1チップ周りの前提知識

詳しくないので厳密には正しくない情報かもしれないが、
以下のような概念をなんとなく把握しておく必要がある。

  • M1チップ: arm64(略してa64)
    • Appleシリコンとも呼ぶ
    • arm64eとの違いはなんだろう、、、
  • Intelチップ: x86_64
  • M1のMacでも、 x86_64 でアプリケーションを起動したりコマンド実行したりできる
    • Finderからアプリケーションの情報を見るで、Rosettaを使用して開くをオンにする
    • arch -x86_64をコマンドの先頭につけてコマンドを実行する
      • arch -x86_64 sudo gem install hogehoge
        • 個人的にはこれは危険なのでやらない方が良いという結論に(後述)
      • これを応用すればRosettaのオプションを使わなくてもx86_64のシェルを立ち上げられる
        • exec arch -x86_64 /bin/zsh
  • uname -mコマンドでarm64x86_64かを確認できる

arm64x86_64の各ターミナル環境を構築

次の記事を大変参考にさせて頂きました。
この記事に出会わなければどれだけ迷走していたことか、、、大変感謝です。

以下実際自分が行った手順

x86_64版ターミナルアプリの作成

Apple Silicon (ARM, M1) のmacOSにaarch64とx86_64のhomebrewを共存させる
を参考にさせて頂きました。アプリをコピーペーストして増やすという発想にびっくり。

  • Finderでターミナルアプリをコピーペーストして複製
    • 自分はiterm2ですが、デフォルトのターミナルアプリでも何でもいい(Rosettaがちゃんと効けば)
  • 複製した方のアプリをターミナル_x86_64のような名前に設定
  • 複製した方だけ、情報を見るからRosettaを使用して開くをオンにしておく
  • これでarm64で動かしたい時は普通のターミナル、x86_64で動かしたい時はターミナル_x86_64を起動すればok
    • uname -mコマンドで今のターミナルがどちらか確認できる

双方でhomebrewをインストール

  • 順番が関係あるか分からないが、arm64 -> x86_64 の順で自分は行った
  • それぞれで次のコマンドを実行 (brew公式のコマンド通り)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

ちなみにhomebrewがarm64に対応していないという情報がよく出てきますが、
今は対応済みなので普通にインストールできます。

双方でrubyをインストール

brew reinstall -s ruby

flutterをインストール

ここはターミナルとかarm64とかx86_64とかは関係ない

flutterインストールページからzipをダウンロードしてインストール

ターミナル構築が一通り完了してからやってもいいが、
パス設定を一気にやってしまいたいのでこのタイミングでflutter入れておくのが効率的。

rubyflutterのパスを設定

  • ~.zshrcファイル等に以下のように設定することでarm64,x86_64双方で独立して動作するようにする
  • arm64ruby
    • ruby: /opt/homebrew/opt/ruby/bin
    • gems: /opt/homebrew/lib/ruby/gems/x.x.x/bin (x.x.xは実際に確かめる)
  • x86_64ruby
    • ruby: /usr/local/opt/ruby/bin
    • gems: /usr/local/lib/ruby/gems/x.x.x/bin (x.x.xは実際に確かめる)
if [[ $(uname -m) = "x86_64" ]]; then
  typeset -U path PATH
  path=(
    /usr/local/opt/ruby/bin
    /usr/local/lib/ruby/gems/x.x.x/bin
    /usr/local/bin
    /usr/local/sbin
    /usr/bin
    /bin
    /usr/sbin
    /sbin
    $HOME/flutter/bin
  )
else
  typeset -U path PATH
  path=(
    /opt/homebrew/bin
    /opt/homebrew/sbin
    /opt/homebrew/opt/ruby/bin
    /opt/homebrew/lib/ruby/gems/x.x.x/bin
    /usr/local/bin
    /usr/local/sbin
    /usr/bin
    /bin
    /usr/sbin
    /sbin
    $HOME/flutter/bin
  )
fi
  • パスの順番は必要に応じて調整
    • 前にある方が優先
  • 今後新しいパスを追加する必要があれば、双方に追加する
    • もちろん分けて管理する必要があるものであれば別個に追加する
細かい話

export文を使うと何度もシェルをリロードする度に重複してパス設定がなされてしまうので、
path変数をここで完全に上書きしている。
特にarchコマンドによってシェル自体を切り替える想定のある人はこのような書き方の方が安心。
しかし、今回はターミナルアプリ毎分けたので、
リロードによる重複が気にならない人は、このような書き方ではなくても、
普通にexportの羅列で問題ないはず。(if分岐自体は必要)
その場合は、/etc/pathsで事前に読み込まれているであろう /usr/local/bin ~ /sbinまでの設定は省いていい。
ただし優先度には気を付ける必要がある。($PATHの前に追加するのか後ろに追加するのか)

各ターミナルの確認

双方のターミナルで、以下を確認

  • uname -mコマンドを打つと、対応するアーキテクチャ名(arm64orx86_64)が返ってくること
    • ここがおかしい場合は、コピーして作ったターミナルアプリの方にRosettaの設定ができていない可能性がある
  • ruby -vコマンドを打つと、アーキテクチャに応じて以下のように返ってくること
    • arm64: ruby x.x.xoo (xx revision oo) [arm64-xxoo]
    • x86_64: ruby x.x.xoo (xx revision oo) [x86_64-xxoo]
    • ここがおかしい場合は、パス設定が不適切な可能性がある

これで、それぞれのターミナルで独立したruby環境を使っているということになる!
これが本記事で一番重要なところ。

AndroidStudioXcodeのインストール

ここら辺は普通です。他にも詳しく解説してくださっているサイトがたくさんあります。

  • AndroidStudioインストール
    • AndroidStudioインストールページ
    • 一度起動してセットアップを実行
    • 一部エミュレータでエラーが出るが、とりあえず気にしない!
      • とりあえず一部のエミュレータがダメでも基本的には無事動作します
      • もし気になる人はここら辺詳しく解説して下さっているサイトが他にたくさんあると思うのでそちらを!
    • pluginインストール
      • Configure -> PluginsFlutter をインストール
        • Dart は自動で入るはず
  • Xcodeインストール
    • AppleStoreからインストール

Flutter環境構築

やっと本題。
flutter doctorコマンドで進めていくわけだが、重要なことは、

  • x86_64ターミナルの方を開いて環境構築を進める
  • gemにsudoをつけない

ということ!

詳しい仕組みはわからないが、AndroidStudioが内部で呼び出すシェルは、
x86_64/bin/zshになっている。
パス設定も、x86_64側のパス設定がAndroidStudioからコマンド実行される際に呼び出される。
なので、少なくともx86_64側のターミナルで構築を行う必要がある。
(自分は一応双方とも構築しました)

上記の手順でターミナル環境を構築すると、sudoを使わずにgemを利用できる。
sudoをつけて操作してしまうと、例えばgem installをした際にはそのgemだけ権限がおかしくなったりするのでよくない。
(gemsの配下をllしてみるとよくわかる)

cocoapodsのインストール

gem install cocoapods

sudoを付けない!

cocoapodsが見つからないエラー

cocoapodsを入れたはずなのにAndroidStudioで見つからないという問題が、ネット上でもよく挙がっています。
自分はその問題の1つの可能性として、AndroidStudioが内部で呼び出すシェルのパスと、
gem installを実行した環境のパスの不一致があるのではないかと思います。

AndroidStudioはデフォルトだと、/bin/zshx86_64で内部起動していそうです。
なので、今回みたいにアーキテクチャによって環境変数を分けて管理してる場合は注意が必要です。

自分は最初arm64側で構築し、flutter doctorが全部OKになりましたが、
AndroidStudioでいざビルドをしてみるとcocoapodsが無いというエラーが発生しました。
AndroidStudioが呼び出すx86_64のシェルでは、arm64側のgemsにパスが通っていないので、至極当然なエラーでした。
それに気づいて、x86_64側でもcocoapodsを入れたら解決した、という流れでした。

flutter doctorの指示に沿って環境構築

flutter doctorコマンドの指示に従って構築する!
(詳しく解説してくださっているサイトがたくさんあるのでここでは省略)
確か以下を行う必要があった。

  • AndroidStudio系でライセンス承諾
  • xcode系で2つほどよくわからないコマンドを打たされた

以上で無事完了!
M1 MacでFlutterを用いたアプリ開発できるはずです!

archコマンドを推奨しない理由

ハマるポイントはruby, gem周りと思います。
特にarm64系でcocoapodsがうまく動かない、というサイトをたくさん目にしました。

よく解決方法として、

arch -x86_64 sudo gem install cocoapods

等々が記載されていますが、自分はこの方法は非推奨と思います。
しっかと理解して行うならばよいのですが、
何となくこれで解決するだろうと思ってこのコマンドを実行してしまうのは危険です。

それは、同じruby環境の中でgemを、arm64x86_64とを混ぜて操作することになるからです。
これは1つ間違えればgem全体を破壊することになりかねません。
(自分は実際に一度やらかしました。まったくgemコマンドが動作しなくなり、ruby毎再インストールする羽目になりました。)

色々迷走した挙句にたどり着いたのが、

この方々の記事でした。
これらの記事にbrewarm64用とx86_64用とで別々に共存させるという発想を頂き、
これを利用してrubyも別個管理できるのではないかと思い至り、
試してみたらうまくいきました。

arm64用とx86_64用とで分離して管理できれば、
この地獄のような問題をすっきりと解決できますね!

おわりに

m1 Macを買ったことを後悔しかけていましたが、
今はむしろ良かったとも思えるくらいです。

それくらい納得のいく環境を整えることができました。
これだけ分かればFlutter環境だけでなく、
そのほかのアプリケーションやフレームワークも何とかなりそうと思います。

残念なのはAndroidStudioはx86_64で動いていそうなことですね、、
せっかくなのでarm64で動かすことはできないのだろうか、、

8
7
1

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
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?