🍑

Mac初心者がiOSアプリの開発環境を作る(CocoaPodsがrbenvのrubyにインストール出来ない)

2023/02/04に公開

はじめに

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

やり方は下記の記事が、参考になります。
というより、下記の記事のお陰でまともな環境が作れました。
超絶神です。

https://zenn.dev/junjunjunk/articles/4b230519d87de4

https://zenn.dev/ress/articles/069baf1c305523dfca3d

具体的な環境構築手順

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に下記を追加して下さい。(無ければ作って下さい。)

~/.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に追記。(無ければ作る)

~/.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