Mac初心者がiOSアプリの開発環境を作る(CocoaPodsがrbenvのrubyにインストール出来ない)
はじめに
Mac初心者がiOSアプリの開発環境を作りました。
かなり苦労したので、知見を共有出来ればと思います。
対象の読者
Mac初心者のエンジニアがiOSアプリの環境構築をする想定です。
環境構築の全体像を理解しながら、構築して貰えたら。
急いで手順だけを知りたい人は、具体的な環境構築手順を見て下さい。
MacでのiOSアプリ開発のツール管理の全体像
まず、開発環境の全体像を俯瞰しましょう。
Xcode
MacでのiOSアプリの開発には、Xcodeが絶対必要です。 色んな流派はありましょうが、必要なので入れてください。好きなIDEがあるなら別途インストールしましょう。App Storeからインストールすれば良いと思います。
Homebrew
Macにインストールするライブラリを管理します。
これから説明する全てのライブラリ管理ツールの親です。
rbenv
rubyのバージョンを管理に必要です。
homebrewの子としてインストールします。
ruby
プログラミング言語のrubyです。
rbenvの子としてインストールします。
Gemのインストールに必要です。
GemとはRubyで書かれたライブラリのことです。
CocoaPods
iOSアプリのライブラリ管理に必要です。
rubyの子としてインストールします。
Objective-cやSwiftで書かれるiOSアプリですが、ライブラリ管理にはrubyが用いられています。
階層を図にする
階層を図にすると下記。
Mac
├ Homebrew
│ └ rbenv
│ └ ruby
│ └ CocoaPods
└ Xcode
M1 MacとIntel Mac
Macには、2種類のCPUアーキテクチャがあります。
Arm64とX86_64の2種類です。
ターミナルでuname -m
と打ち込むと、現在実行しているアーキテクチャが表示されます。
Arm64
Arm64のアーキテクチャのCPUは、M1 MacとかM2 Macと呼ばれるものに比較的新しい製品に搭載されています。Appleが独自設計した規格です。Apple製品に最適化して作られている反面、互換性に欠けます。
X86_64
X86_64は、比較的古いMacに搭載されています。X86_64はIntel社の設計したアーキテクチャです。Apple製品に最適化されていない反面、互換性に優れています。
CPUアーキテクチャに応じてソフトウェアを管理する必要がある
ソフトウェアを実行するには、CPUに応じてコンパイルされている必要があります。
ソフトウェアを実行する時、実行するCPUに応じたプログラムを用意する必要があります。
X86_64のみに対応したソフトウェアがあります。Arm64では実行できません。
X86_64とArm64の両方に対応したソフトウェアもあります。ただし、インストールされているソフトウェアがX86_64向けならば、Arm64では実行できません。
Rosseta 2
Rosseta 2とは、Arm64向けのプログラムをX86_64向けに翻訳してくれるAppleの技術です。
Rosseta 2のお陰で、M1 MacでもX86_64向けのプログラムが起動できます。
アプリケーション毎に、Rossetaモードで起動するか設定できます。M1 Macでは、Finderからアプリケーション毎に設定できます。詳しい記事は沢山あるので調べてみて下さい。
CocoaPodsをインストール出来ない
ここまで説明した環境構築を順に行っていくと、CocoaPodsをインストール出来ない問題に行き着くと思います。
即ち、rbenvでインストールしたrubyにCocoaPodsがインストール出来ない問題に行き着くと思います。
そして、公式ドキュメントにあるように、システムのrubyにCocoaPodsをインストールすることになると思います。システムのrubyとは、Macに最初からインストールされているrubyのことです。
それでも問題がない場合もあるかと思います。しかし、問題が発生することもあります。
rubyのバージョンが指定されているライブラリをビルドする場合、システムのrubyのバージョンと合わない可能性があるからです。
では、何故、rbenvのrubyから、CocoaPodsがインストール出来なかったのでしょう?
CPUのアーキテクチャの問題です
M1のMacに普通にHomebrewをインストールした場合、Arm64のHomebrewがインストールされます。
Arm64のHomebrewには、Arm64のrubyがインストールされます。
一方、CocoaPodsはX86_64に依存しています。
正確には、CocoaPodsはffiに依存しています。
そして、ffiはX86_64のみのアーキテクチャです。
だから、rbenvのrubyにCocoaPodsがインストール出来なかったのです。
Arm64のrubyにX86_64のCocoaPodsをインストールしようとしたことが問題だったのです。
以下の方法で解決できます。
HomebrewをCPUに応じてインストールする
CPUのアーキテクチャに応じて、Homebrewをインストールすることが解決します!
Homebrew自体をアーキテクチャに応じてインストールし分けることで、X86_64のrubyをrbenvでインストール出来るようになります。
X86_64のrubyにならば、CocoaPodsは問題なくインストールされます。
階層を図にすると下記のようにします。
Mac
├ Homebrew(Arm64)
│ └ rbenv
│ └ ruby
│ └ CocoaPods
└ Homebrew(X86_64)
└ rbenv
└ ruby
└ CocoaPods
やり方は下記の記事が、参考になります。
というより、下記の記事のお陰でまともな環境が作れました。
超絶神です。
具体的な環境構築手順
Homebrewのインストール
Arm64
ターミナルを開いて、以下のスクリプトを実行。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Homebrewの公式サイトで案内されているインストールスクリプトです。
X86_64
Rossetaでターミナルを開いて、全く同じ事をします。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
ターミナル起動時にCPUに応じたHomebrewを読み込むようにする
ターミナル起動時にCPUに応じたHomebrewを読み込むように設定します。
homeディレクトリの.zprofileに下記を追加して下さい。(無ければ作って下さい。)
ARCH=$(uname -m)
if [[ $ARCH == arm64 ]]; then
echo "Current Architecture: $ARCH"
eval $(/opt/homebrew/bin/brew shellenv)
elif [[ $ARCH == x86_64 ]]; then
echo "Current Architecture: $ARCH"
eval $(/usr/local/bin/brew shellenv)
fi
それぞれのHomebrewにiOSの環境を構築する
既にターミナルを立ち上げた時点で、CPUアーキテクチャに応じた環境が作り分けられるようになっています。
即ち、
Ressetaで立ち上げれば、X86_64のソフトウェアがインストールされます。
Rossetaで立ち上げければ、Arm64のソフトウェアがインストールされます。
全く同じ事をRossetaと非Rossetaに行うだけなので、Rossetaの環境構築手順のみ記します。
Arm64の環境を作りたければ、以下の手順を非Rossetaで行って下さい。
rbenv
公式の通りに進めていきます。
インストールして
brew install rbenv ruby-build
ターミナル起動時にパスが読み込まれるように.zshrcに追記。(無ければ作る)
# 読み込んで
eval "$(rbenv init - zsh)"
# パスを通す
export PATH="$HOME/.rbenv/bin:$PATH"
あとはターミナルを再起動。
which ruby
で~/.rbenv/shims/ruby
にパスがrubyがあることを確認する。
ruby
rbenv install -l
で、最新の安定版を確認
rbenv install 2.7.7
で、お好みのversionをインストール。
rbenv local 2.7.7
で、現在のディレクトリと子孫のディレクトリに適応するrubyを設定(.ruby-versionというファイルが現在のディクレトリに作られるだけです)
bundler
gem install bundler --version 2.0.2
好きなバージョンのbundlerを
ffi
sudo arch -x86_64 gem install ffi
ffiをインストール
CocoaPods
sudo gem install cocoapods
CocoaPodsをインストール
pod install
arch -x86_64 pod install
pod install
最後に
思いついたらアップデートします。
Macを使う人が周りにいない中での試行錯誤なので、もっと良い方法があるとか、お前は完全に間違っているとか、コメント頂けたら幸いです!
Discussion