Skip to content

Instantly share code, notes, and snippets.

@szktty
Last active April 16, 2023 15:04
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save szktty/a47213f0077294c64ea58621c2dcfaf2 to your computer and use it in GitHub Desktop.
Save szktty/a47213f0077294c64ea58621c2dcfaf2 to your computer and use it in GitHub Desktop.
詳解 WebRTC ビルド

詳解 WebRTC ビルド

以下の内容は M63 時点の情報です。

WebRTC ライブラリのソースコードはサイズが 6GB 以上あってダウンロード時間でペヤングが 100 個は食べられるほどで、ビルドするにも Mac Pro の 12 コアをフル回転させて 1 つのアーキテクチャにつき最低 15 分はかかります。その上ビルドは相当に複雑な構成をしており、全地球のプログラマの寿命を戦闘機のカタパルトで助走をつけて殴っていいレベルで削らせるブラックなボックスです。あまりに自力ビルドの難易度が高いので WebRTC Build Scripts というビルドスクリプトも登場しましたが、最近ビルド方法が大きく変更されたために残念ながらこのビルドツールの内容は古くなってしまいました。

幸い iOS では公式ビルドのバイナリをダウンロードできるようになりました。 ところが「これで iOS はすべて解決!」とも言えません。 WebRTC のビルドには様々なオプションが用意されており、公式ビルドはあくまで特定のオプションの組み合わせの一つです。残念なことに用途によっては公式ビルドでカバーできない場合もあり、気軽に依存できない状況もあると思います。 時雨堂の WebRTC SFU Sora とかそうです (宣伝)。

この記事の目的は、ビルドの各手順の意味を把握してもらうことです(理解とは言ってない)。おそらく自力ビルドせざるを得ない人はほとんどいないと思いますが、万が一の場合に参考になれば幸いです。

これらの結果は WebRTC ライブラリのビルドツールとしてまとめてあります。 こちらもビルドの参考になれば幸いです。

バージョン表記について

ビルドの説明の前に、 WebRTC ライブラリ固有のバージョン表記について触れておきます。

WebRTC ライブラリのバージョンは「リリース番号」と「コミットポジション」で表されます。リリース番号は "M + 数字" で表されるメジャーバージョンで、専用のブランチが作成されます(リリースブランチ)。コミットポジションはリリースブランチの作成以降にコミットされたリビジョンを表します。コミットポジションは単純にコミットの数です。リリースブランチの先頭となるコミットが 1 で、以降コミットのたびに数字が増えます。あまりコミットポジションを意識することはないと思いますが、聞き慣れない用語だと思いますので、一応頭に入れておくといいかと思います。

次はコミットログの一例です。

Create WebRTC 63 branch for Chrome 63

TBR=

Bug: 
Change-Id: I66dbd9443c8833221043228faaf89bdcc1d180d6
Reviewed-on: https://webrtc-review.googlesource.com/8580
Reviewed-by: Guido Urdaneta <guidou@webrtc.org>
Cr-Commit-Position: refs/branch-heads/63@{#1}
Cr-Branched-From: bef8a5d2ca5413c680995584b8c0976852ba5f25-refs/heads/master@{#20237}

Cr-Commit-Position がコミットポジションです。このコミットは 63@{#1} で表されます。マイナーバージョンやメンテナンスバージョンのように意味のある数字ではありません。単なるコミットの順番です。

まとめるとこうなります。

  • リリースブランチは 機能追加のコミットも修正のコミットもすべて一緒くた になっている
  • リリース以降もブランチにコミットが追加される

リリースブランチをビルドする場合、ソースコードを取得したタイミングによってリビジョンが異なってしまうので注意しましょう。本当にバージョンを固定するにはリビジョンを指定する必要があります。

これは個人的な意見ですが、同じリリースブランチだからと言っても最新のコミットに追従するメリットは少ない気がします。リリースブランチへのコミットは hotfix を意味しませんし、コミットポジションはメンテナンスバージョンでも何でもないただのコミット回数です。追従したところで安定性も安全性も特に保証されないと思います。

ビルドの流れ

WebRTC のビルドはちょっと特殊です。と言うのは、 Google が Chrome のために作ったツールを使わなければならないからです。それもソースコードのダウンロードからです。

WebRTC のビルド過程は次のようになります。ユーザーが行う操作だけではないので注意してください。

  1. ビルドツール depot_tools をダウンロード、インストールする。
  2. depot_tools を使ってソースコードをダウンロードする。
  3. depot_tools を使ってビルドファイルを生成する。
  4. もう一つのビルドツール GN を使い、プラットフォームごとに Ninja 用ビルドファイルを生成する。
  5. Ninja と GN を使ってビルドする。

このうち depot_tools と GN が Google 製のツールです( GN という名前は "GeNerate" から来てるんじゃないかと思います)。 GN は gyp というツールの代替となった最近のツールで、 gyp を使っているビルドの記事は古いと考えて問題ありません。

ダウンロードですら Git 以外のツールを使うのは、ダウンロード後にフックスクリプトを実行してビルド用のファイルを生成するなどのためです。一応 Git でチェックアウトできることはできますが、それだけではビルドは難しいでしょう。

ソースコードのダウンロードとビルドファイルの生成

以下はユーザーが行うビルドの手順です。

公式に書かれているダウンロード方法が次のコマンドです。

$ fetch --nohooks webrtc_ios
$ gclient sync

fetchgclient も depot_tools に含まれるコマンドです。 fetch はソースコードのダウンロードの設定を行い、 gclient sync でダウンロードを行います。 gclient はダウンロード後にビルドファイルを生成します。 gclient sync は中断しても同じコマンドで再開できます。ここは Git でも同様の処理ができるので、 Git でダウンロードしてから gclient sync しても問題ありません。

実は fetchgclient で使われる設定ファイルを生成するだけなので、自分で設定ファイルを用意すれば省略できます(確か以前の公式には設定ファイルについて書かれていた)。手動で用意するメリットは特にないので、気にしなくてもいいと思います。

前述の通りダウンロードには非常に時間がかかります。下手すると一日がかりになりますから、他の作業をしながら気長に待つのがいいと思います。

Android の注意点

Android 用のソースコードのダウンロード中、 Google Play ライブラリのライセンス許諾を求められます。許諾するとダウンロードが進みます。

GN を使って Ninja 用のビルドファイルを生成する

次のコマンドは公式で挙げられている例です。

# debug build for 64-bit iOS
$ gn gen out/ios_64 --args='target_os="ios" target_cpu="arm64"'

# debug build for simulator
$ gn gen out/ios_sim --args='target_os="ios" target_cpu="x64"'

gn が GN のコマンドです。 gn はビルドツール Ninja で使われるビルドファイルをプラットフォーム別、用途別に生成します。この例では iOS の arm64 アーキテクチャとシミュレーター向けのビルドを行うビルドファイルを別々のディレクトリに生成します。ここは比較的簡単に自動化できる処理です。

Ninja を使ってビルドする

最後に Ninja を使ってビルドします。 iOS だと次のコマンドで WebRTC.framework を生成できます。

$ ninja -C out/ios framework_objc

Android だと他にもコマンドを実行する必要がありますが、 Ninja でビルドする点は同じです。

公式に書かれているこの方法でのビルドの注意点は、ターゲット以外の設定をカスタマイズしにくいことです。いやできるんですが、後述のビルドスクリプトを使うのが簡単です。

iOS での注意点

デフォルトの設定

デフォルトでは次のオプションが設定されます。

  • VP9 が無効
  • Bitcode が無効

公式に配布されているバイナリもおそらくデフォルトの設定で、 Bitcode 非対応です。もちろんアプリケーションも Bitcode 非対応にならざるを得ないので困る人もいると思います。現状、その場合は自力でビルドするしかないです。

ただし、 Bitcode を有効にしてビルドすると、バイナリが 300MB を超えます。そりゃ配布しにくいよな。さらにアプリケーションの実機テストの際のインストールに時間がかかるようになります。ソースコードの規模によってはカップ焼きそばが作れるんじゃないですかね。もちろんアプリケーションのサイズも余裕で 300MB 超えます。はっきり言って開発時は Bitcode に何もメリットがないです。

Universal Binary を生成してくれない

上記の手順では生成したバイナリが 1 つのアーキテクチャしか含んでいないため、複数のアーキテクチャ(最低でも arm64 と armv7 )を一つのフレームワークにまとめるにはユーザー側でバイナリを統合する必要があります。安心してください、後述のビルドスクリプトならやってくれます。

もう一つのビルド方法:ビルドスクリプトを使ってビルドする(推奨)

最近のリリースで、 Ninja によるビルドをラップするビルドスクリプトが追加されました。 iOS にも Android にも用意されています。ビルドスクリプトは次のパスにあります。

  • iOS: tools_webrtc/ios/build_ios_libs.pybuild_ios_libs.sh があるが .py を呼んでるだけ)
  • Android: tools_webrtc/android/build_aar.py

これらのビルドスクリプトはビルド設定をコマンドラインオプションで指定できるようになっており、ビルドスクリプトを使えば GN と Ninja の実行を省略できます。

iOS の場合

iOS では Bitcode 対応もコマンドラインオプションで指定できます。そのため公式では Bitcode に対応したければ次のコマンドを実行するように書かれています。

$ python build_ios_libs.py --bitcode

でも build_ios_libs.py に関する説明なんかどこにも書いてないんですよ。スクリプトのあるディレクトリすら書いてない。公式仕事しろと思ったでしょ? わかるわ。

ただし、 VP9 はこのスクリプトを使っても無効のままです。 VP9 を有効にするとなぜか CPU の負荷が全体的に重くなるので、設定が無効で固定されています。有効にしたければスクリプトを書き換える必要があります (M63 時点) 。それくらいついでにコマンドラインオプションを追加してもらえませんかね...

Android の場合

Android のビルドスクリプトはリリース用のバイナリしか生成してくれません。デバッグ用のバイナリを生成するにはスクリプトを書き換える必要があります。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment