Open7

WebKitをEmscriptenでビルドするとどこで止まるのか調査

okuokuokuoku

(note: Webkit.jsの事は一旦忘れる)

かんそう

... とりあえず規模感はわかった。776/2630 ターゲットが失敗。逆に言えば70%はビルドできたって事だな!

完全にパッチ無しは無理 。WPE WebKit をベースとしつつ、一部はどうしてもEmscripten固有のパッチを当てる形になるだろう。

次の一手をやるとするならば:

  1. gpg-errorgcrypt のビルドをやっつける (これらは多分面倒なだけ)
  2. GStreamer移植が可能かどうか検討する。これらはgmoduleに依存していて、Emscriptenのshared libraryでどれくらい頑張れるかの問題になる。
  3. JSConlyビルドでとりあえずJSCを何とかやっつける。特に、 pthread_kill がどうやっても実現できないのでどうするか問題がある。
okuokuokuoku

Configure

https://github.com/WebPlatformForEmbedded/WPEWebKit

Configure自体は普通に emcmake でできる。

emcmake cmake -DPORT=WPE -DENABLE_SUBTLE_CRYPTO=OFF -DENABLE_XSLT=OFF \
-DENABLE_VIDEO=OFF -DENABLE_WEB_AUDIO=OFF -DENABLE_JIT=OFF \
-DENABLE_NATIVE_VIDEO=OFF -DENABLE_WEBDRIVER=OFF -DENABLE_WEB_CRYPTO=OFF \
-DENABLE_TEXT_SINK=OFF -DCMAKE_BUILD_TYPE=Debug -GNinja \
~/yocto-work/webkit/test/WPEWebKit/

glibは

https://gist.github.com/kleisauke/acfa1c09522705efa5eb0541d2d00887

okuokuokuoku

ライブラリの始末

Upstream

WebPが増えてる ...んだけど、最初から入ってるんだよなぁ。。たぶんWPEの開発当初(今回の試行で使ったWPEの開発リポジトリ)で対応してないだけだろう。

https://github.com/WebKit/WebKit/commit/d1c1ed12367d372175e27ec599140437cb1c4a3a

実際のSafariでWebPがサポートされたのはかなり最近(2020年)。

2.22

一旦、ライブラリをビルドしなくてもビルドが進むように加工してしまう。

https://github.com/okuoku/WPEWebKit/commit/35eda732a4e22a5892a89e92ac19ed4638fd44b6

https://github.com/okuoku/WPEWebKit/commit/be586f6ca6b39abc5d0694ad136a8f1c1e5deb0e

find〜のファイルを修正しなくても、本来はCMake側で適当に変数を指定しておけば無効化できる。 CMakeスクリプトの処理を中断するには return() コマンドが使える

find_package(Cairo 1.10.2 REQUIRED)
find_package(Fontconfig 2.8.0 REQUIRED)
find_package(Freetype2 2.4.2 REQUIRED)
find_package(GLIB 2.38.0 REQUIRED COMPONENTS gio gio-unix gobject gthread gmodule)
find_package(HarfBuzz 0.9.18 REQUIRED)
find_package(ICU REQUIRED)
find_package(JPEG REQUIRED)
find_package(LibEpoxy 1.4.0 REQUIRED)
find_package(LibGcrypt 1.6.0 REQUIRED)
find_package(LibSoup 2.42.0 REQUIRED)
find_package(LibXml2 2.8.0 REQUIRED)
find_package(PNG REQUIRED)
find_package(Sqlite REQUIRED)
find_package(Threads REQUIRED)

WPE WebKitのビルドに最低限必要なライブラリ 。 実際には、LibGcryptは libgpg-error に依存しているなど、間接的な依存も存在する。

okuokuokuoku

バグ: 余計な定義が残留している

Upstream

追記: ちゃんと消されてた

https://github.com/WebKit/WebKit/commit/b9e29f643a33d6bd5fbec84226b6a7231e01f485#diff-5b8cbbc626789eed80d264f4620841aa2b7c584e3a767509a02cfaa4c8da3981

2.22

余計な定義が残留していてEmscriptenの libc++ では正常にビルドできない。

In file included from /mnt/yocto-work/webkit/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__node_handle:15:
/mnt/yocto-work/webkit/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/optional:171:70: error: redefinition of 'bad_optional_access'
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
                                                                     ^
DerivedSources/ForwardingHeaders/wtf/Optional.h:281:7: note: previous definition is here
class bad_optional_access : public std::logic_error {
      ^

https://github.com/okuoku/WPEWebKit/commit/09613120193651a139c6f480f8d61dc78e83f5cc

... これ既にupstreamでは修正されているので、取ってくるブランチが古すぎたかも。。

https://trac.webkit.org/changeset/235661/webkit

okuokuokuoku

バグ: Gcryptのインクルードパス指定忘れ

Upstream

治ってない。

https://github.com/WebKit/WebKit/blob/e890d5837dc9900080bc85f3a1e329a525244f01/Source/WebCore/PAL/pal/PlatformWPE.cmake

2.22

https://github.com/okuoku/WPEWebKit/commit/f8c61d9cf8a606c6ee7d647262bbed746a55fbcc

diff --git a/Source/WebCore/PAL/pal/PlatformWPE.cmake b/Source/WebCore/PAL/pal/PlatformWPE.cmake
index c01409961aa5..d805b861fec6 100644
--- a/Source/WebCore/PAL/pal/PlatformWPE.cmake
+++ b/Source/WebCore/PAL/pal/PlatformWPE.cmake
@@ -31,4 +31,5 @@ endif ()
 
 list(APPEND PAL_SYSTEM_INCLUDE_DIRECTORIES
     ${GLIB_INCLUDE_DIRS}
+    ${LIBGCRYPT_INCLUDE_DIRS}
 )

まぁ普通は /usr/include にあるからね。。

okuokuokuoku

謎: <glib-object.h> を使用していない

Upstream

治って(?)ない。

https://github.com/WebKit/WebKit/blob/e890d5837dc9900080bc85f3a1e329a525244f01/Source/WTF/wtf/glib/GRefPtr.h

2.22

https://github.com/okuoku/WPEWebKit/commit/e7f00b70381a03476089c37338207695ec070cd4

diff --git a/Source/WTF/wtf/glib/GRefPtr.h b/Source/WTF/wtf/glib/GRefPtr.h
index aaa16de2d6ad..4465aae48cb0 100644
--- a/Source/WTF/wtf/glib/GRefPtr.h
+++ b/Source/WTF/wtf/glib/GRefPtr.h
@@ -28,9 +28,12 @@
 #include <wtf/HashTraits.h>
 #include <algorithm>
 #include <glib.h>
+#include <glib-object.h>
 
+#if 0
 extern "C" void g_object_unref(gpointer);
 extern "C" gpointer g_object_ref_sink(gpointer);
+#endif
 
 namespace WTF {

APIヘッダを使ってくれ〜 。これも libc++ でのビルドを失敗させるようだ。

... そもそも、WPE WebKitのメンテナはGStreamerや他のGNOMEプロジェクトとの縁が深い Igalia で、その辺をサボるとは思えないんだけど。。

okuokuokuoku

LLIntOffsetsExtractor を静的ライブラリにする

普通にビルドすると

[1117/2614] Generating ../../DerivedSources/JavaScriptCore/LLIntAssembly.h
FAILED: DerivedSources/JavaScriptCore/LLIntAssembly.h
cd /home/oku/yocto-work/webkit/build/DerivedSources/JavaScriptCore && /usr/bin/ruby /home/oku/yocto-work/webkit/test/WPEWebKit/Source/JavaScriptCore/offlineasm/asm.rb -I/home/oku/yocto-work/webkit/build/DerivedSources/JavaScriptCore/ /home/oku/yocto-work/webkit/test/WPEWebKit/Source/JavaScriptCore/llint/LowLevelInterpreter.asm /home/oku/yocto-work/webkit/build/bin/LLIntOffsetsExtractor.js /home/oku/yocto-work/webkit/build/DerivedSources/JavaScriptCore/LLIntAssembly.h && /usr/bin/cmake -E touch_nocreate /home/oku/yocto-work/webkit/build/DerivedSources/JavaScriptCore/LLIntAssembly.h
offlineasm: No magic values found. Skipping assembly file generation.
[1309/2614] Generate bindings (WebCoreBindings)
ninja: build stopped: cannot make progress due to previous errors.

のように、 LLIntAssembly.h の生成に失敗してしまう。これは、 LLIntOffsetsExtractor という実行ファイルをビルドしてrubyスクリプトでパースすることでこのヘッダファイルを生成することに起因している。 Emscriptenの出力はJavaScriptのスクリプトファイルになってしまうため、必要なデータが抽出できない。

(生成された実行ファイルは、データの抽出のみに使用され実行されないので、クロスコンパイルでも問題にはならない)

今回は、実行ファイルではなく静的ライブラリに変換してしまうことにした。

https://github.com/okuoku/WPEWebKit/commit/377ffdb1dc38040b6aa4b8adc1628da7ebfba834

diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 3716906818f8..9ec97413684e 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -251,7 +251,7 @@ add_custom_command(
 # Additionally, setting the OBJECT_DEPENDS property will make the .h files a Makefile
 # dependency of both LLIntOffsetsExtractor and LLIntOffsetsExtractor.cpp, so the command will
 # actually be run multiple times!
-add_executable(LLIntOffsetsExtractor
+add_library(LLIntOffsetsExtractor STATIC
     ${JAVASCRIPTCORE_DIR}/llint/LLIntOffsetsExtractor.cpp
     ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntDesiredOffsets.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/Bytecodes.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/BytecodeStructs.h
 )