Chromium を Build して動かすまでの待ち時間を「7 時間」から「30 分」まで高速化してみる
Chromium をゼロから Build して動かしてみる という前回のブログでは、Chromium を Build して動かすという一連のフローを試してみました。
この時は、Checking out and building Chromium on Linux の手順に従って作業をしました。これは、「最新の Chromium」を Linux 上で Build する事が出来るしっかりした公式手順です。しかしながら、8core, 32GiB memory の GCP VM instance でも Build に 6-7 時間程度かかってしまうのがネックでした。
そこで今日は、Chromium を Build して動かすまでのサイクルを 30 分で試せるようにすること を目指します。7時間と比較すると約15倍の高速化です!
なお、具体的には 事前に Build 済みの Object File を GCS に置いておき、ダウンロードして再利用することで再ビルドの手間を避ける というアプローチをとります。そのため、「最新の Chromium ではなく事前に Build 済みの古い Version しか試せない」ことが欠点となります。「最新の Chromium へのコミット」などを行いたい場合には適さないアプローチでしょう。
しかしながら、「過去の Version の Chromium でも良いから、試しに Build して動かしてみたい」という場合には役立つのではないかと期待しています。
以下、ステップ 0 から順番に作業を進めてみます。
ステップ0. 事前に Chromium の Build 成果物を用意して、GCS へアップロードしておく
Chromium はまともにゼロから Build すると、とてつもなく長い時間がかかってしまいます。そこで、「事前に Chromium を Build して生成した一連の Object File 及び Binary を tar.gz にまとめたもの」を用意しておきます。これをダウンロードして利用することで、「再ビルドの手間」を省くことができるはずです。
対象の File は、chromium-dev-south37
GCS Bucket の中で chromium20201213.tar.gz
という名前で配置しています(suffix は日付で、2020/12/13 時点の Chromium のコードを Build したことを示しています)。
$ gsutil ls -l gs://chromium-dev-south37/chromium20201213.tar.gz 18900879483 2020-12-13T15:56:30Z gs://chromium-dev-south37/chromium20201213.tar.gz TOTAL: 1 objects, 18900879483 bytes (17.6 GiB)
Public にダウンロード可能な形で公開しているので、誰でも試していただくことが可能です。ソースコードも含んでいるので、17.6GiB というかなり巨大なサイズになっています。
この後のステップでは、上記の「ソースコードと Build 成果物を tar.gz でまとめたもの」を利用して作業を進めます。
ステップ1. Linux マシンを用意する
この部分は 前回 と同様です。
GCP の Compute Engine で以下の VM Instance を立ててそこで作業を行うことにします。
以下のコマンドで ssh して、そこで作業を行います。
$ gcloud beta compute ssh --zone "asia-northeast1-b" <instance 名>
ステップ2. 事前に用意しておいた Chromium の一連の Build 成果物をダウンロードする
早速、ステップ0 として事前に用意しておいた「Chromium の一連の Build 成果物」をダウンロードしましょう。以下のように $ gsutil cp
コマンド利用して GCS からダウンロードをします。
$ gsutil -o 'GSUtil:parallel_thread_count=1' \ -o 'GSUtil:sliced_object_download_max_components=8' \ cp gs://chromium-dev-south37/chromium20201213.tar.gz ./chromium20201213.tar.gz
なお、ここでは Cloud Storage のパフォーマンスを最適化する - Google Cloud Platform の推奨に従って、GSUtil:parallel_thread_count
オプションや GSUtil:sliced_object_download_max_components=8
オプションを利用しています。これは、 「1つの巨大なファイルの転送」をしたい場合に推奨されるオプション として紹介されています。
上記のコマンドを実行すると、環境にもよりますが大体 3 分ほどでダウンロードが完了するはずです。
minami@chromium-dev-20210226:~$ gsutil -o 'GSUtil:parallel_thread_count=1' \ > -o 'GSUtil:sliced_object_download_max_components=8' \ > cp gs://chromium-dev-south37/chromium20201213.tar.gz ./chromium20201213.tar.gz Copying gs://chromium-dev-south37/chromium20201213.tar.gz... - [1 files][ 17.6 GiB/ 17.6 GiB] 25.7 MiB/s Operation completed over 1 objects/17.6 GiB.
ダウンロードが終わると、 17.6 GiB の chromium20201213.tar.gz
が作られているはずです。
minami@chromium-dev-20210226:~$ ls -l | grep chromium total 18457900 -rw-rw-r-- 1 minami minami 18900879483 Feb 26 12:34 chromium20201213.tar.gz
今度は、この File を $ tar xvzf chromium20201213.tar.gz
で展開します。これは大体 10-15 分程度で完了するはずです。
minami@chromium-dev-20210226:~$ time tar xvzf chromium20201213.tar.gz chromium/ . . . chromium/src/cloud_print/OWNERS chromium/.gclient chromium/.gclient_entries real 15m45.171s user 5m57.618s sys 2m49.498s
展開が終わると、以下のように chromium
directory が作られているはずです。chromium
directory の中には chromium/src/out/Default
directory が入っています。その中には Build 済みの Object File や chrome
Binary が存在する事も確認できます。
minami@chromium-dev-20210226:~$ ls -la | grep chromium drwxrwxr-x 4 minami minami 4096 Dec 12 12:33 chromium -rw-rw-r-- 1 minami minami 18900879483 Feb 26 12:34 chromium20201213.tar.gz minami@chromium-dev-20210226:~$ ls chromium/src/out/ Default minami@chromium-dev-20210226:~$ ls chromium/src/out/Default/ | grep '\.so$' | wc -l 375 minami@chromium-dev-20210226:~$ ls -la chromium/src/out/Default/chrome -rwxrwxr-x 1 minami minami 1058842464 Dec 13 14:43 chromium/src/out/Default/chrome
ただし、この状態ではまだ chrome
Binary は実行できません。実行しようとすると、以下のようにエラーが出てしまいます。
minami@chromium-dev-20210226:~$ ./chromium/src/out/Default/chrome ./chromium/src/out/Default/chrome: error while loading shared libraries: libnss3.so: cannot open shared object file: No such file or directory
ステップ3. 必要な package を install
chrome
Binary 実行にはいくつか package が必要となります。
まず、python2 が必要になるので、install しておきます。
minami@chromium-dev-20210226:~$ sudo apt update -y minami@chromium-dev-20210226:~$ sudo apt install -y python2 minami@chromium-dev-20210226:~$ which python2 /usr/bin/python2 minami@chromium-dev-20210226:~$ python2 -V Python 2.7.18 minami@chromium-dev-20210226:~$ sudo ln -s /usr/bin/python2 /usr/local/bin/python minami@chromium-dev-20210226:~$ which python /usr/local/bin/python minami@chromium-dev-20210226:~$ python -V Python 2.7.18
次に、./build/install-build-deps.sh
を実行します。これは 6 分程度で完了するはずです。
minami@chromium-dev-20210226:~/chromium/src$ time ./build/install-build-deps.sh . . . Installing locales. Generating locales (this might take a while)... da_DK.UTF-8... done en_US.UTF-8... done fr_FR.UTF-8... done he_IL.UTF-8... done zh_TW.UTF-8... done Generation complete. real 6m10.812s user 2m35.472s sys 0m58.130s
これで、必要な package の install が完了しました。この状態で、試しに chrome
Binary を実行してみましょう。前回のように、「headless mode での実行」を試してみます。以下のようにちゃんと動作をすることが確認できました 🎉
minami@chromium-dev-20210226:~/chromium/src$ ./out/Default/chrome --headless --disable-gpu --dump-dom https://example.com <!DOCTYPE html> . . .
ここまで、 GCP VM instance への ssh から大体 20-25 分 ほどで「chrome
Binary を動かすこと」が出来ました 。
ステップ4. Build に必要な環境をセットアップ
さて、「ダウンロードした chrome
Binary」を動かせただけでは、あまり嬉しくありません。「コードを書き換えながら、chrome
を Build して実行することができる」という状態を目指します。
まず、ninja
など Build に必要なツールを利用するために、depot_tools
をインストールします。
minami@chromium-dev-20210226:~/chromium/src$ cd $HOME minami@chromium-dev-20210226:~$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git # PATH を通しておく minami@chromium-dev-20210226:~$ export PATH="$PATH:${PWD}/depot_tools"
これで、gn
などの Build に必要なコマンドが使えるようになります。
minami@chromium-dev-20210226:~$ which gn /home/minami/depot_tools/gn
次に、この状態で chrome
Binary の Build をしてみます。autoninja -C out/Default chrome
を実行すると、既に chrome
Binary は存在するため、no work to do
という表示が出て 5 秒程度で終了します。
minami@chromium-dev-20210226:~$ cd chromium/src/ minami@chromium-dev-20210226:~/chromium/src$ autoninja -C out/Default chrome ninja: Entering directory `out/Default' ninja: no work to do.
前回と同様に、chrome/common/channel_info.cc
という File を touch して timestamp を更新してみます。こうすると、更新した File (及びその File に依存した File)だけを対象に Build が行われるので、20 秒程度で chrome
Binary の Build が終了します。
minami@chromium-dev-20210226:~/chromium/src$ touch chrome/common/channel_info.cc minami@chromium-dev-20210226:~/chromium/src$ time autoninja -C out/Default chrome ninja: Entering directory `out/Default' [4/4] LINK ./chrome real 0m21.574s user 0m20.022s sys 0m5.478s
ということで、 「コードを書き換えながら、chrome
をBuild して実行することができる」という状態も実現できました!🎉
まとめ
事前に Build 済みの Object File を GCS からダウンロードすることで、再ビルドの手間を避けるアプローチを試しました。その結果、前回の「ゼロからの Build」ではトータルで 7 時間かかったのに対して、今回は 30 分程度で「Chromium を Build して動かすまでのサイクルを試す」ことが出来るようになりました。
このように、「事前に用意した Build 成果物」をうまく活用することで、再ビルドの時間的・マシン的コストは劇的に下げることができます。この記事が、Chromium を試しに触ってみることへの障壁を下げることに少しでも貢献していれば幸いです。