Windows での QtWebEngine build from source

## 1. はじめに

この記事は [Qt Advent Calender 2024](https://qiita.com/advent-calendar/2024/qt) の20日目の記事です。
一昨日に続き、2度目の執筆となります。

https://qiita.com/advent-calendar/2024/qt

昨日は @task_jp さんによる  [Qt Creator を微かに改善してみました](https://qiita.com/task_jp/items/051afa3b0d60e3e73aa9) でした。

Suzuki さんが度々パッチを送られているのを見て、いつか自分もできるようになりたいなと密かに思っております（Contributor と呼ぶのでしょうか、憧れます）。

<br>

また、この記事は [苦行またはメロンパン](https://adventar.org/calendars/10188) の20日目の記事でもあります。
個人的に qtwebengine のビルドは苦行だったので参加しました。

https://adventar.org/calendars/10188

<br>



[学生ライセンス](https://www.qt.io/qt-educational-license) で Qt を使わせていただいている立場なので、学生でなくなった時にどうしようかと偶に考えます。結局はやはりソースからビルドしたいと思うものです。

ところで、QtWebEngine だけは何回試みてもビルドに成功したことがなく悔しいので、一度落ち着いて取り組むとします。


<br>


## 2. 環境構築

### 2.1. ビルド要件
 [Qt Documentation](https://doc.qt.io/qt-6/qtwebengine-platform-notes.html#all-platforms) に書いてあります。
 各々インストールした後はターミナルにコマンドを打って、対応する表示が出ることを確認します（例：`cmake --version`）。

 <br>

|ライブラリ名など|備考|
|---|---|
|[Visual Studio 2022](https://visualstudio.microsoft.com/ja/thank-you-downloading-visual-studio/?sku=Community&channel=Release&version=VS2022&source=VSLandingPage&cid=2030&passive=false)|「C++ によるデスクトップ開発」を選択し、インストール|
|[CMake](https://cmake.org/download/#:~:text=Files-,Windows%20x64%20Installer%3A,-cmake%2D3.31.2%2Dwindows)|インストーラをダウンロード|
|[Bison](https://gnuwin32.sourceforge.net/packages/bison.htm)|「Complete package, except sources」よりインストーラをダウンロード|
|[Flex](https://gnuwin32.sourceforge.net/packages/flex.htm)|同上|
|[html5lib](https://pypi.org/project/html5lib/)|`python -m pip install html5lib`。Python 3.10.16 を使用|
|[GPerf](https://gnuwin32.sourceforge.net/packages/gperf.htm)|「Complete package, except sources」よりインストーラをダウンロード|
|[Node.js](https://github.com/coreybutler/nvm-windows/releases)|インストールが完了したら、`nvm install lts`|
|[Perl](https://www.perl.org/get.html#win32)|「DOWNLOAD STRAWBERRY PERL」からインストール|


<br>

### 2.2. モジュールの依存関係
[こちら](https://code.qt.io/cgit/qt/qt5.git/tree/.gitmodules) に書いてあります。
「depends」欄はもちろんのこと、「recommends」欄は無いとビルドされないソースがあるので準備した方がよいのでしょう。

|モジュール名|依存・および推奨モジュール|
|---|---|
|qtbase||
|qtsvg|qtbase|
|qtimageformats|qtbase|
|qtshadertools|qtbase|
|qtlanguageserver|qtbase|
|qtserialport|qtbase|
|qtactiveqt|qtbase|
|qtdeclarative|qtbase, qtimageformats, qtshadertools, qtsvg, qtlanguageserver|
|qtquicktimeline|qtbase, qtdeclarative|
|qtquick3d|qtbase, qtdeclarative, qtshadertools, qtquicktimeline|
|qtmultimedia|qtbase, qtshadertools, qtdeclarative, qtquick3d|
|qtwebsockets|qtbase, qtdeclarative|
|qtwebchannel|qtbase, qtdeclarative, qtwebsockets|
|qttools|qtbase, qtdeclarative, qtactiveqt|
|qtpositioning|qtbase, qtdeclarative, qtserialport|
|qtwebengine|qtdeclarative, qtwebchannel, qttools, qtpositioning|

## 3. ビルド
**Visual Studio 2022 Developer Command Prompt** を起動。
スタートにて「x64」と入力すれば候補に出てくるはず。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926187/389348a3-f09a-2edb-2864-fe3f3dffd578.png">

ソースを取得します。今回はバージョン 6.5.3 を選びました。

```bash
git clone git://code.qt.io/qt/qt5.git
cd qt5
git checkout 6.5.3
```
<br>

続いて、サブモジュールを取得。
非常に時間がかかります（QtWebEngineの 3rd party のソースの量が莫大なため）。ちなみに新しいバージョンでは、`init-repository.bat` があるので、perlは必要なかった気がします。

```bash
perl init-repository --module-subset=qtbase,qtsvg,qtimageformats,qtshadertools,qtlanguageserver,qtserialport,qtactiveqt,qtdeclarative,qtwebsockets,qtwebchannel,qttools,qtpositioning,qtwebengine
```

<br>

ビルドシステム作成。
インストールフォルダを `-prefix` オプションで指定できます。

```bash
cd ..
mkdir build
cd build
C:/Qt_source/qt5/configure -prefix "C:/Qt-6.5.3" -platform win32-msvc
```

最後に出力される Log は無視せず確認します。
「Warning」とか「won't be built」とか偶に書いてあるので。

<br>

最後にビルド・インストール。
```bash
cmake --build . --parallel
cmake --install .
```

<br>

## 4. 結果
うーん、上手くいかない。

エラー文のパスを調べていると、記載されているパスに「gn.exe」が存在しません。どうやら qtwebengine の 3rd party ソースの一つである [gn](https://gn.googlesource.com/gn/) のビルドに失敗しており、その後の処理が出来なくなっているようです。

<br>

というわけで試すこと以下2点。
- qtwebengine 以外のモジュールは問題なくビルドできるのか
- gn.exe は問題なくビルドできるのか

<br>

### 4.1. qtwebengine 以外のビルド
`init-repository` の `--module-subset` 指定するモジュールから qtwebengine を省いてビルドを進めてみます。
```bash
git clone git://code.qt.io/qt/qt5.git
cd qt5
git checkout 6.5.3
perl init-repository --module-subset=qtbase,qtsvg,qtimageformats,qtshadertools,qtlanguageserver,qtserialport,qtactiveqt,qtdeclarative,qtwebsockets,qtwebchannel,qttools,qtpositioning
```

ビルドシステム作成、ビルド、インストールコマンドは上記と同じ。

```bash
cd ..
mkdir build
cd build
C:/Qt_source/qt5/configure -prefix "C:/Qt-6.5.3" -platform win32-msvc
cmake --build . --parallel
cmake --install .
```

<br>

これらは問題なくビルドが完了しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926187/8519b03e-bdf3-9106-437c-11a5c62d3d5e.png)


<br>

### 4.2. gn.exe のビルド

まずは [こちら](https://gn.googlesource.com/gn/) よりソースを取得。これもまた Visual Studio 2022 Developer Command Prompt にて行う。

```bash
git clone https://gn.googlesource.com/gn
```

続いて、gn.exe をビルドする。

```bash
cd gn
python build/gen.py
ninja -C out
```

<br>

これが上手くいかない。

![スクリーンショット 2024-12-20 025735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926187/4328e0dc-e711-ced5-3be8-f32415ea2512.png)

めぼしいエラーメッセージも無いので何もしようが無い。

とりあえず `out` ディレクトリを削除し、オプションを付けて試してみます。

```bash
python build/gen.py --allow-warnings
```

`build/gen.py` にはこのオプションが書いてありますが、サイトに書いてあるように「--allow-warning」としてもコマンドは通ります（argparse の仕様？）。

<br>

改めてビルド。

```bash
ninja -C out
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926187/c4a205b2-7650-762e-26b2-3417e9bc6c83.png)

あれ、gn.exe がビルドできました。
ちゃんと使えるのか試してみます。

```bash
cd out
gn_unittests.exe
```

![スクリーンショット 2024-12-20 034222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926187/bce4b3ae-0fb9-3f6a-546b-bc560426b9af.png)

どう見ても大丈夫ではなさそうですが、`Debug` ディレクトリに出力された `foo.json` には「true」と書いていて、成功したのか不明です。

example をビルドしてみます。

```bash
cd ..
cd examples/simple_build
"C:/gn/out/gn.exe" gen -C out
ninja -C out
cd out
hello.exe
```

問題なくビルドでき、「Hello, world」と表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926187/fd56e2c8-443e-815b-8915-903925f238d2.png)

<br>

### 4.3. 再挑戦
前章で分かったのは、「`--allow-warnings` オプションを付ければ gn.exe は（一応）ビルド可能」ということなので、qtwebengine ビルド時にこのオプションを指定できるようにします。

qtwebengine 以外がビルドでき、`C:/Qt-6.5.3` にインストールした状態から始めます。


```bash
git clone git://code.qt.io/qt/qt5.git
cd qt5
git checkout 6.5.3
perl init-repository -f --module-subset=qtwebengine
```

`C:\Qt_source\qt5\qtwebengine\src\gn\CMakeLists.txt` 内の `add_custom_command` の引数の記述に、`--allow-warnings` オプションを加えます。

```cmake
add_custom_command(
    OUTPUT ${GN_EXECUTABLE}
    WORKING_DIRECTORY ${GN_BINARY_DIR}
    COMMAND ${Python3_EXECUTABLE} ${GN_SOURCE_DIR}/build/gen.py
        --allow-warnings # ここにオプションを追加
```

続いてビルドシステム作成。

```bash
cd ..
mkdir build
cd build
"C:/Qt-6.5.3/bin/qt-configure-module.bat" C:/Qt_source/qt5/qtwebengine
```

最後にビルド。

```bash
cmake --build .
```


<br>

うーん、上手くいかない。
エラー文のコマンドを実行して何が原因か見てみます。

```bash
<path/to/cmd.exe> /C "cd /D C:\Qt_source\build\src\gn && <path/to/python.exe> C:/Qt_source/qt5/qtwebengine/src/3rdparty/gn/build/gen.py --allow-warnings --no-last-commit-position --out-path C:/Qt_source/build/src/gn/Release --cc "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe" --cxx "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe" --ld "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe" --ar "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/lib.exe" --qt-version 6.5.3.qtwebengine.qt.io
```

<br>

『gen.py: error: unrecognized arguments: --allow-warnings』

<br>

なぜ… ？？

<br>


どうやら `C:/Qt_source/qt5/qtwebengine/src/3rdparty/gn/build/gen.py` と、4.2節 でクローンしてきた `gen.py` の中身が違うようです。`init-repository` を行った時の出力を確認すると、gn は [qtwebengine-chromium](https://code.qt.io/cgit/qt/qtwebengine-chromium.git/) から取得されているようで、`gen.py` を見ると確かに `--allow-warnings` オプションはありませんでした。

これを踏まえると、gn.exe をビルドできるかどうかはクローンしてきた方のソースで確かめる必要があります。


```bash
cd "C:/Qt_source/qt5/qtwebengine/src/3rdparty/gn"
python build/gen.py --no-last-commit-position --out-path out --cc "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe" --cxx "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe" --ld "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe" --ar "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/lib.exe" --qt-version 6.5.3.qtwebengine.qt.io
ninja -C out
```

<br>

結果、ビルドは成功しませんでした。

```bash
[2/155] ninja -t msvc -- C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe /nologo /showIncludes /FC -I..\src -I. /O2 /DNDEBUG /Zc:inline /DNOMINMAX /DUNICODE /DWIN32_LEAN_AND_MEAN /DWINVER=0x0A00 /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_UNICODE /D_WIN32_WINNT=0x0A00 /FS /W4 /Zi /wd4099 /wd4100 /wd4127 /wd4244 /wd4267 /wd4505 /wd4577 /wd4838 /wd4996 /std:c++17 /GR- /D_HAS_EXCEPTIONS=0 /c ..\src\gn\escape.cc /Fosrc/gn/escape.obj
FAILED: src/gn/escape.obj
ninja -t msvc -- C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/cl.exe /nologo /showIncludes /FC -I..\src -I. /O2 /DNDEBUG /Zc:inline /DNOMINMAX /DUNICODE /DWIN32_LEAN_AND_MEAN /DWINVER=0x0A00 /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_UNICODE /D_WIN32_WINNT=0x0A00 /FS /W4 /Zi /wd4099 /wd4100 /wd4127 /wd4244 /wd4267 /wd4505 /wd4577 /wd4838 /wd4996 /std:c++17 /GR- /D_HAS_EXCEPTIONS=0 /c ..\src\gn\escape.cc /Fosrc/gn/escape.obj
```

うーん、何も分からない。

<br>


## 5. おわりに
時間を浪費する訳にもいかないので、このあたりで諦めようと思います。
もし何か知見をお持ちの方がいれば共有してくださると大変助かります。

<br>

[苦行またはメロンパン](https://adventar.org/calendars/10188) の明日は わゃをん さんです。「学園アイドルのためならお茶を20kg分買って運んだってかまわない」とのこと、お楽しみに～。