Chromium Embedded Frameworkについて熱く語る

日本語情報が全く無いので、誰かの代わりにCEFについて語ります。年も開けて早々ですが。
記述量が多いので記事の装飾を雑にしますが許してください。

主にWindowsの話をします。
Linuxはちょっとだけ触れます。
MacOSは持ってないので知りません。

BSDくん...CEF非対応なんだね...。


2025-01-02: ライセンスの項目を追記

## CEFとは

タイトルにもある通り、`Chromium Embedded Framework`の略称です。
名前通り、`Chromium`を`Embedded`(埋め込みするための)`Framework`です。

Chromiumの本家のGoogleが管理しているようで[^4]、安心して使えます。

### どういうもの？

めっちゃ簡単に言えば、**Electronみたいなやつ**です。
もちろん厳密には違いますが[^2]。後述します。

GUIフレームワークとして使用するものです。
HTMLでGUIを作成し、ちょっとだけJavascriptを書きながら、他は言語独自の機能が使えます。

V8を積んでいるので、Javascriptで書いたほうが良い箇所はJavascriptで記述できます。
Blinkももちろんいます。

### 対応環境

「Windows, MacOS, Linux, あとはモバイルがちょっと」らしいです。
AndroidとiPhoneは非対応。ほぼデスクトップ向け。

## 使用されているアプリの例

Wikipediaを参考にしました[^1]が、自分でも確認してきました。

- Spotify Desktop
- Adobe Acrobaty や Brackets 等のAdobe製品
- Epic Games Launcher など、一部のLauncher系のソフト
- Unreal Engine

UEはマジで衝撃でした。お前も使ってるんかい！っていう感じです。


## 主なライブラリ

マジで数が多いです。気になる人はWikipediaを見に行ってください。
ただし、ホントに数が多いだけでほとんどのリポジトリは放棄されてます。Wikipediaに載ってるのは全部見ましたが

|言語|名前|メモ|
|--|--|--|
|C++|[CEF](https://bitbucket.org/chromiumembedded/cef/src/master/)|本家。ビルドしにくいとか。|
|Java|[java-cef](https://bitbucket.org/chromiumembedded/java-cef/src/master/)|こちらも本家。使い方は知らん...。|
|Delphi|[CEF4Delphi](https://github.com/salvadordf/CEF4Delphi)|公認。もう一個の公認の[dcef3](https://github.com/hgourvest/dcef3)が2016年に死んでるので、選択肢はこれしかない。|
|C# (.NET)|[CefSharp](https://github.com/cefsharp/CefSharp)|公認。Windows以外だと話にならんらしい[^3]。|
|C# (Mono)|[CefGlue](https://gitlab.com/xiliumhq/chromiumembedded/cefglue)|公認。Windows以外でも話になるらしい[^3]。|
|Go|[cef2go](https://github.com/cztomczak/cef2go)|公認。[energy](https://github.com/energye/energy)よりStar数が多いが、最終コミットは「4 years ago」。できたら使いたくない古さ。|
|Go|[energy](https://github.com/energye/energy)|公認。何故か "Apache-2.0 license"。現在も保守されている。|
|Python|[CEF Python](https://github.com/cztomczak/cefpython)|公認。pipで入れればすぐ使える。numpyくらい気軽で困る。|
|？？？|[WebKitX](https://www.webkitx.com/)|有料？これが差異を吸収して、いろんな言語で使えるようにするっぽい？なんもわからんかった...|

※1 調べた限り、Javascriptはありません。もともとはNW.jsがCEFのラッパーだったようですが[^2]、今は違うようです。

※2 WebKitXは調べてもわかりませんでした。公式のドキュメントにレジストリエディタの画像が乗ってたんで私は逃げます。Qiitaにも記事が一つもないし...。

個人的にはRustで使えてほしかったんですが無理みたいです。ただ、Rustってdllとかの関数が叩けるので、バイナリを自分で用意したら使えるかもしれません。骨が折れますね。

## 他と比べてどうよ

近年はElectron以外にもWebviewとかもいますからねえ...。ちょっと比べてみます。

### VS Electron

さっきチラッと触れましたが、そもそもElectronはCEFとは設計と思想が違います。
ElectronがChromiumをラップするのに対し、CEFはChromiumのAPIを使用できる環境を構築します。

あと、ElectronはNode.jsの機能も入ってきますね。時にはそれが便利だったり、時にはそれが邪魔だったり。

### VS WebView

すべてのGUIツールキットの敵のWebView。
正直WebViewがあれば全て解決する。ネイティブとかいらん。
だって高速だし軽量だし...。

メリットデメリットはWebViewとElectronの関係とほぼ変わらんです。
WebViewが非対応の環境ではCEFしか使えませんが、CEFはバイナリがGUIツールキットにしてはアホかと思うほどデカいです。

Acrobatとか想像してもらえばいいと思います。
「なんで1GBもあるんだろ」とか思いません？
`AcroCEF`が400MB取ってるのが一つの原因です。

逆に、WebViewはユーザーのPC上のブラウザとかに寄生するので、軽くて済みます。
WebViewのアプリって、Webサイトみたいなもんですから。

そもそもWebViewって.NETのランタイムとかJVMみたいなもんで、ユーザー側に対応を求めるものなんですよね。**バイナリの軽量さを求める代わりに、ユーザーに対応を求める**って感じです。

一方、CEFとかElectronは.NETやJVMを一緒に配布してるみたいなものなので、**バイナリのデカさを犠牲にユーザーに対応を求めない**って感じです。

どっちもどっちです。
ただ、最近だと最初っからWebView2のランタイムが入ってるWindowsのように、対応が進んでるのでWebViewの一強時代かもと思っています。

---
本題から逸れるので畳みます。

<details>
<summary>いろんな言語でのWebViewライブラリ</summary>

|言語|名前|メモ|
|--|--|--|
|C++|公式又はネイティブ|WebView2とかWebKitGTKとか。ラッパーないのでは？あんまり知らん。|
|Python|[pywebview](https://github.com/r0x0r/pywebview)|割と使いにくかった...。悪くはない。|
|Go|[Wails](https://github.com/wailsapp/wails)|結構使いやすい。バイナリが10MBくらいで済む。嬉しい。|
|Rust|[Tauri](https://github.com/tauri-apps/tauri)|使いやすい。モバイル対応。依存関係が複雑すぎてライセンス表記ができないんだが？|

GoだとWailsが強いなあって感じです。個人的にはGoのGUIはWailsで決まりだと思ってます。Fyneはレイアウト崩壊しますし...。
RustもTauriがめっちゃ使いやすいです。商用のリリースは大変かもしれない。

で、WailsとTauriに対して、独自CLIツールのないpywebviewが使いにくく見えるってオチです。「悪くはないんだ。でも他と比べるとイケてない。」
</details>


## 使い方

各ラッパーで使ってきました。
MSVCを使える環境が手元にないので動かせないのが結構あります。Cドライブの空き容量が17GBしかないんです。許して

### C++

申し訳ないですが、動かす物理的余裕がありませんでした。手順は添えておきます。

ビルド済みバイナリは配布されていないので、自分でビルドすることになります...
と言いかけましたが、Spotifyからビルド済みバイナリが提供されています。
https://www.spotify.com/jp/opensource/

どうやら個人でのビルドは面倒なようなので、こちらを使うのが良いでしょう。
なお、msys2のgccではお話になりませんでした☆。
ただ、上手く使えた例もあるっぽいので、頑張ればできるかもです。

https://blog.csdn.net/along1990q/article/details/143570846

誰かcmakeとBazelの使い方教えてくれ。makefileで精一杯や...。
気が向いたらLinuxとかでビルドして追記します。

### Java

MSVCがないからビルドできない...。

https://bitbucket.org/chromiumembedded/java-cef/wiki/BranchesAndBuilding

が、Windows向けにビルドしている人を発見。

https://github.com/jcefbuild/jcefbuild

残念なことに、こちらも2021年を最後に更新されていません。
が、動かすだけ動かしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530797/e1e25121-12ba-92c6-faed-f9cd12886004.png)

良くも悪くもJavaだなあって感じがしますね。

なお、配布されているファイルは**210MB**でした。
ただ、JVMが入っておらず、かつbatから起動するタイプなので、JVMごと配布したらもっと大きくなると思います。

気が向いたらまた追記します。

### Python

Pythonの`cefpython3`はpipでインストールしたらgithubにあるサンプルをすぐに実行できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530797/775b0a5f-c100-8bf2-5146-2bcded47c5d1.png)

良いですね。ただのChromiumって感じです。

#### pyinstaller

ビルドに失敗しました。UPXがエラーを吐いてましたが...？
調べる気力がないのでパスします。

#### cx_Freeze

上手くいきませんでした。
This is not necessarily a problem - the dependencies may not be needed on this platform.
だそうです。
頑張ったらビルドできそう。

#### nuitka 

なにか工夫をする必要もなく、ビルドに成功しました。

バイナリは脅威の **262MB**。`libcef.dll`が90MB超えてました。
何故か2つも入ってましたし(ハッシュまで一緒だったんですが?!)。

`7z`で圧縮したら80MBくらいに。WebViewならこれの1/10くらいですかね...。
upxとかで潰して配布したほうがいいかも。

一つ気づいた事があるんですが、`ffmpeg`と`vulkan`のdllがありませんでした。ffmpegはともかく、vulkanは何処へ？

#### Python embeddable

例の再配布用のやつです。
検証してないですが、動くはず。

検証し次第、書き直します。

##### CEFはいつダウンロードした？

どうやらpipでcefpython3をインストールしたタイミングで`site-packages`の中に入ってたみたいです。ビルド済みのやつが。

### Go

Goはenergyを使ってみました。ただねえ、なーんか変なんですよね...。

中国系のコミュニティが維持してるっぽいです。ドキュメントの一部が英語になってなくて困ります。ちょっと中国語は読めない。

#### 茶番

CLIツールがある[^5]ので、それをダウンロードしようと公式サイト上からビルド済みのものをダウンロード...しようとしたら、「**ウイルスが検出されました**」。何やねん。

これねえ、よくよく調べてみたら、SourceForge上に`v2.5.1`ってディレクトリと`cli`って2つのディレクトリがあるんですけど、`v2.5.1`の方からツールをダウンロードするとダメっぽいです。
が、公式サイトはダメな方を案内してます。どうなってんの

ただ、謎なのが、`v2.5.1`と`cli`の中に、ファイル名にハイフンがあるかないかしか差のないzipがあって、両方のハッシュは同じ、ファイルサイズも同じなのに片方だけ誤検知という...。なんなのまじで

VMで色々検証してきましたが謎のままです。誰か情報求む。

茶番に付き合わせました。以下が使い方です。

#### 本番

CLIツール、自分でビルドすることもできるので、今回はそっちで行きました。怖いので。
Goが必要です。

##### 1. ツールをビルドする

```sh
git clone https://github.com/energye/energy.git
go mod tidy
cd ./energy/cmd/energy
go install

# ウチは怪しいからビルドした
go build
```

とりあえず`energy`コマンドが使える用になったらOKです。

##### 2. 必要なものをダウンロードする

`energy env`で、何が足りていないかわかります。
`energy install .`をすることで、足りていないものをダウンロードできます。
CEFもこのタイミングでダウンロード。

Windowsなら、`CEF`、`NSIS`、`7z`、`UPX`をダウンロードするのですが、全員、全部入ってないと思います。
ウチの環境、NSISと7zとUPXが入ってるんですが、検出されませんでした。なんなの...。

なのでオプションのダウンロードとか書いてますが、全部入れたらいいと思います。
というか全部入れてください。後で困るので

##### 3. プロジェクトの作成

`energy init`でプロジェクトを作成します。指示に従って実行してください。

##### 4. 実行、ビルド、パッケージング

`go run main.go`で実行できます。

`go build -ldflags "-s -w"`か`energy build`でビルドできるってinitしたときに出てきますが真っ赤な嘘です。確かにビルドは通りますが、起動しません。

`energy package`でビルドできます。
上記のだとdll等がないので動きません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3530797/97711b21-99e9-0acb-ab31-3d08b77fe851.png)

これでOKです。

出力されたバイナリは、何と**422MB**でした。

**？？？？？？？？？？** 

Pythonのとき驚愕とか言ったせいで、私の辞書にはこの驚きを表す言葉がありません。
見てみると、`libcef.dll`が約**210MB**あるじゃありませんか。

絶望しました。「使いたい人はどうぞ。止めはしないよ」って感じです。

### 結局どれがいいの？

見てもらったとおりなのですが、個人的にはPython推しです。どこでも動くみたいですし。
Delphiは試しませんでしたが、メンテナンスが死んでるので...。

## ライセンス管理の容易さ

一つ素晴らしいのは、ライセンス管理が容易なところです。
仕事だと絶対に忘れられないオープンソースライセンスの管理。CEFなら簡単にできます。

GoogleのウェブサイトにCEFのライセンスと依存するライブラリをまとめたページがあります。ライセンス情報をこのページから抜き出せば終わりです。seleniumとか諸々のHTMLを扱えるライブラリで自動化もできます。

CEF自体はオープン系の「**Chromium Embedded Framework ライセンス**」ですし、依存するものにもGPLとか入ってないっぽいので大丈夫。

https://support.google.com/webdesigner/answer/3413931?hl=ja

個人的な話ですが、Windows向けにGTK4を使用したオープンじゃないプロジェクトを前に作ろうとしたことがあります。ただ、ライセンスの所在が謎だったのでやめました。そういうことを考えると、ライセンス管理がしやすいのは安心。

## まとめ

1. WebViewとElectronとCEFと、使い所を見極めるべし
2. `C++`、`Java`、`C#`、`Go`、`Python` 以外ではまともに使えない
3. 好きな方を使え

[^1]: https://en.wikipedia.org/wiki/Chromium_Embedded_Framework
[^2]: https://www.electronjs.org/ja/blog/electron-internals-building-chromium-as-a-library
[^3]: https://stackoverflow.com/questions/71572827/is-cefsharp-supported-in-mac-os-and-linux
[^4]: https://support.google.com/webdesigner/answer/3413931?hl=ja
[^5]: https://energye.github.io/en/course/install-env