SkiaとC++でデスクトップアプリを作る(Windows) その1

# 目次

SkiaとC++でデスクトップアプリを作る(Windows) その1
[SkiaとC++でデスクトップアプリを作る(Windows) その2](https://qiita.com/Nageler_Kotls/items/1ba6d82603795fe093b4)

# Skiaを使いたい

趣味で低レイヤの2Dグラフィックライブラリを使いたいなと思い、色々漁っていたのですが

- OpenGL→難しい
- Vulkan→もっと難しい
- DirectX→Windowsでしか動かない
- Skia→使い方が分からない(情報が少ない)

と、どれも一長一短なようでした。OpenGLも少し触ったもののCGは門外漢のため、より高レイヤのSkiaを使おうという考えに至りました。

Skia([skia.org](https://skia.org/))はGoogleがOSSで開発している2Dグラフィックライブラリで、ChromiumやFirefoxの他Flutter等のクロスプラットフォーム環境でよく使われています[^1][^2]。

ただ日本語のみならず英語でも情報が少ないため数日間格闘を重ねました。そのためここに手順を残しておきます。

# 環境

- Windows 10 64bit 2004
- VisualStudio2019
- CMake version 3.17.20032601-MSVC_2

諸々のプロダクトは2020年8月時点の最新版です(多分)

# SkiaをWin向けにビルドする

Skiaはバイナリでなくソースで配布されているので、自分のマシン向けにビルドする必要があります。

基本的には
https://skia.org/user/download
https://skia.org/user/build

を見てやる感じですが、Windowsだとうまくいきません。

## ダウンロード

まずは適当な場所(C:/srcとか)に移動しビルドに必要なchromiumのdepot_toolsをダウンロード、そしてパスを通します。Gitが使えない人は[ここ](https://gitforwindows.org/)とかからGitをインストールしましょう。

```console
C:\src> git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
C:\src> set PATH=C:\src\depot_tools;%PATH%
```

skiaフォルダを作ってその中にSkiaをgclientを使ってcloneします。コマンドが使えない場合はdepot_toolsにパスが通っていることを確認してください。
[Chromiumの説明](https://chromium.googlesource.com/skia/+/chrome/m41/site/user/download.md)ではname引数に.を渡していますが、相対パスはだめと怒られるので絶対パスで現在のディレクトリを指定しましょう。

```console
C:\src> mkdir skia
C:\src> cd skia
C:\src\skia> gclient config --name C:/src/skia --unmanaged https://skia.googlesource.com/skia.git
C:\src\skia> gclient sync
C:\src\skia> git checkout master
```

gclient syncのときに`AssertionError: The "gclient_gn_args_from" value must be in recursedeps.`というエラーが出るかもですが、無視して構いません。

続いて外部ライブラリなど必要なものをダウンロードしていきます。Skiaのビルド周りはPython2で書かれているため、用意する必要があります。[ここから](https://www.python.org/downloads/release/python-2718/)素直にインストールしましょうね[^3]。

```console
C:\src\skia> python -V
Python 2.7.17
C:\src\skia> python tools/git-sync-deps //パス指定はスラッシュでもOK
C:\src\skia> tools\install_dependencies.sh //コマンド指定のときはバックスラッシュじゃないと受け付けられない
```

## ビルドする

### clangのインストール

SkiaはMSVCよりもclangのビルドに最適され、早く終わるようなので用意します。

[LLVMのサイト](https://releases.llvm.org/download.html)からclangのなるべく新しいバージョンのインストーラ(Windows 64bit)をダウンロードし、適当な場所(C:\src\LLVM等)にインストールします。

### VisualStudioとVC++のインストール

clangでやる場合でも必要らしいので[Visual Studio](https://visualstudio.microsoft.com/ja/downloads/)をインストールしましょう。

忘れずにC++(赤線部分)、特にMSVCを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177771/da31851e-e94a-e52c-e473-499a0f5ee441.png)

VsDevCmd.batを実行します。場所は大体同じだと思いますが確認してください。コンソールを再起動している場合はdepot_toolsのパスを通し直すのを忘れずに。

```console
C:\src\skia> call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -arch=x64
C:\src\skia> set PATH=C:\src\depot_tools;%PATH% //必要なら
```

### ビルド

一回生成して引数の種類を確認します。gnコマンドはdepot_toolsのパスが通っていれば使えるはず。

```console
C:\src\skia> gn gen out/release -args="is_official_build=true is_component_build=false"
C:\src\skia> gn args out/release --list --short
...中略...
skia_use_system_expat = true
skia_use_system_harfbuzz = true
skia_use_system_icu = true
skia_use_system_libjpeg_turbo = true
skia_use_system_libpng = true
skia_use_system_libwebp = true
skia_use_system_zlib = true
...略...
```

たくさん出てきますが、興味があるのはskia_use_system_xxxという引数です。これらを全部falseにした上で渡します。

加えてビルドに必要な情報も渡します。clangの場所、MSVCのパスは自分の環境によって変えてください。

```console
C:\src\skia> gn gen out/release -args="is_official_build=true is_component_build=false skia_use_system_expat = false skia_use_system_harfbuzz = false skia_use_system_icu = false skia_use_system_libjpeg_turbo = false skia_use_system_libpng = false skia_use_system_libwebp = false skia_use_system_zlib = false target_cpu=""x64"" cc=""clang"" cxx=""clang++"" clang_win=""c:\src\LLVM"" win_vc=""C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC"" extra_cflags=[""-MTd""]
```

ninja_buildを使ってビルドしましょう。

```console
C:\src\skia> ninja -C out/release
ninja: Entering directory `out/release'
[492/1738] ACTION //third_party/icu:make_data_assembly(//gn/toolchain:msvc)
Generated gen/third_party/icu/icudtl_dat.S
[1738/1738] stamp obj/modules.stamp
```

最後までビルドしきれば成功です。エラーの出る場合はgn時の引数に問題がある可能性があります。

# 参考
- [How to download Skia](https://skia.org/user/download)
- [How to build Skia](https://skia.org/user/build)
- [aseprite/skia - GitHub](https://github.com/aseprite/skia#skia-on-windows)
- [How to download Skia - Chromium](https://chromium.googlesource.com/skia/+/chrome/m41/site/user/download.md)
- [Skia is actually not too hard to build - Hacker News](https://news.ycombinator.com/item?id=19586159)

[^1]: Xamarin.FormsもSkiaで動いていると聞くが確証がない...
[^2]: ChromiumとFirefoxで使われてるってもはやブラウザの根幹を担ってるやばいやつじゃないですか！
[^3]: Python3と競合したくない？　ならPython3を消そう