Open6

WasmLinux: Webブラウザ移植の計画を立てる

okuokuokuoku

とりあえずBusyboxは動いちゃったので、究極のゴールとして "Webブラウザ上でWebブラウザ" を考える。これはガチのマジで難しい。

okuokuokuoku

必要なもの

  1. (x86-64) BuildrootでWebブラウザが動く環境を作れること
  2. (x86-64) 自前のEGL + GLES2エミュレーター 上で動作するWayland compositorを作って動作させること
  3. (C-WebGL) EGL + GLES2をシリアライズして他所で動かす技術を確立する
  4. (x86-64) Wayland compositorをコンテナ側に移し、Waylandプロトコルと共有メモリが外部に出ないようにする
  5. (x86-32) ここまでの環境を x86-32 に移植する
  6. (WasmLinux) BuildrootをWasmLinuxに移植
  7. (WasmLinux) MMUエミュレーションなど動作に必要なものを設計 / 実装する
  8. (WasmLinux) ここまでの環境を WasmLinux に移植する

ディストリビューションの作成ツールはYoctoとBuildrootで悩んだが、YoctoでWasmLinux用のBSPを作りきる自信が無かったので一旦Buildrootにする。

WebブラウザとしてはWPE WebKitを一旦採用する。これに近いGNOME Web(元Epiphany)には必要なデスクトップ統合が既にあり、モジュラリティが高い(GStreamerをCodecに採用しているので、自前のアクセラレーションを導入するのが比較的容易と考えられる)ことが理由。Firefoxはビルド環境が激烈にゲームオーバーで更に組込み環境が無い。Chromiumは候補になるが何もかもを内蔵してしまっているのでCodec等の差し替えが辛そう。

最近のGNOME WebにはGtk4が必須で、これを真面目にビルドするのが地味に辛いと予想される。BuildrootにはGtk4が無いため、Gtk4に依存しているGNOME WebではなくWPE WebKitを先に移植することになる。GNOME Webの基盤であるGtkWebKitはWPE WebKitのほぼスーパーセットとなっているため、WPE WebKit動作のための努力は無駄にはならない。と、信じたい。。

32bit環境はRaspberry Piを除くとほぼ死滅しているため、動かしたいものが32bit ABIで動作するかどうかは事前に確認しておき、問題点を潰しておくのが望ましい。

okuokuokuoku

BuildrootでCogを選択するまでが遠い

これ結構ハマりポイントな気もする。

Alpineでbuildrootする

rsync patch は追加必要だった。 ... rsync って昔使ってたときは依存していた記憶が無いんだけど。。

あと、findコマンドのエラーが見えたので findutils も追加。ビルド中に死んだので diffutils も追加。さらに perl-dev coreutils

https://github.com/webmproject/libvpx/blob/495c4b596ca1b346f63850fb13c154bb1ae926d4/configure#L191

Busyboxのdiffは --version を受け入れないようだ。

Expat.xs:14:10: fatal error: EXTERN.h: No such file or directory
   14 | #include "EXTERN.h"
      |          ^~~~~~~~~~

このファイルは perl-devに入っている

ベースシステムの依存関係を選択する

パッケージではなく、システムそのもののCapabilityを先に選択しておく必要がある。今回の場合は:

  • libstdcpp: "Toolchain" => "Enable C++ Support"
  • udev: とりあえず今回は eudev を選んでおく。これudev-zeroとかにしておきたいな。。 "System configuration" => "/dev management" = Dynamic using devtmpfs + eudev

mesa3d

バックエンドを選べるが今回はLLVM + swrastで。更に:

  • "OpenGL EGL"
  • "OpenGL ES"

のオプションを選択しておく必要がある。

パッケージ類

  • dbus
  • wayland wayland_protocols
  • libxkbcommon
  • libinput
  • wpewebkit -- とりあえずメディアサポートも有効にしている
  • cog
okuokuokuoku

buildrootのビルドに失敗する

Muslだとダメケースが多いな。。

fakeroot

libfakeroot.c:147:13: error: conflicting types for 'id_t'; have 'int'
  147 | typedef int id_t;
      |             ^~~~
In file included from /usr/include/sys/types.h:57,
                 from communicate.h:84:
/usr/include/bits/alltypes.h:240:18: note: previous declaration of 'id_t' with type 'id_t' {aka 'unsigned int'}
  240 | typedef unsigned id_t;
      |                  ^~~~

とりあえず /usr/include/bits/alltypes.h の方を修正。。これはたぶんfakerootの方が間違っている。システムヘッダを使えば定義不要なので。

mkpasswd

>>> host-mkpasswd  Building
/usr/bin/gcc -O2 -I/home/oku/repos/buildroot/output/host/include -L/home/oku/repos/buildroot/output/host/lib -Wl,-rpath,/home/oku/repos/buildroot/output/host/lib /home/oku/repos/buildroot/output/build/host-mkpasswd/mkpasswd.c /home/oku/repos/buildroot/output/build/host-mkpasswd/utils.c -o /home/oku/repos/buildroot/output/build/host-mkpasswd/mkpasswd -lcrypt
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/ccKPONmJ.o: in function `display_help':
mkpasswd.c:(.text+0xa0): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text+0xca): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/ccKPONmJ.o: in function `display_methods':
mkpasswd.c:(.text+0x130): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/ccKPONmJ.o: in function `main':
mkpasswd.c:(.text.startup+0x56): undefined reference to `libintl_bindtextdomain'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x5e): undefined reference to `libintl_textdomain'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0xf0): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x1b3): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x424): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x491): undefined reference to `libintl_ngettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x67c): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x6be): undefined reference to `libintl_ngettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x6f6): undefined reference to `libintl_gettext'
/usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: mkpasswd.c:(.text.startup+0x72c): undefined reference to `libintl_gettext'
collect2: error: ld returned 1 exit status

libintlわすれ。

diff --git a/package/mkpasswd/mkpasswd.mk b/package/mkpasswd/mkpasswd.mk
index c1117ef65c..196becf09a 100644
--- a/package/mkpasswd/mkpasswd.mk
+++ b/package/mkpasswd/mkpasswd.mk
@@ -16,7 +16,7 @@ endef
 define HOST_MKPASSWD_BUILD_CMDS
        $(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) \
                $(@D)/mkpasswd.c $(@D)/utils.c \
-               -o $(@D)/mkpasswd -lcrypt
+               -o $(@D)/mkpasswd -lcrypt -lintl
 endef

 define HOST_MKPASSWD_INSTALL_CMDS

LLVMのビルドに失敗する

/home/oku/repos/buildroot/output/build/host-llvm-15.0.3/lib/Support/raw_ostream.cpp: In member function 'uint64_t llvm::raw_fd_ostream::seek(uint64_t)':
/home/oku/repos/buildroot/output/build/host-llvm-15.0.3/lib/Support/raw_ostream.cpp:808:11: error: '::lseek64' has not been declared; did you mean 'lseek'?
  808 |   pos = ::lseek64(FD, off, SEEK_SET);
      |           ^~~~~~~
      |           lseek

LLVM17で治る。

https://github.com/llvm/llvm-project/commit/5cd554303ead0f8891eee3cd6d25cb07f5a7bf67

一旦MesaからLLVMを抜くか。。

xsltのビルドに失敗する

checking for libxml libraries >= 2.6.27... readlink: unrecognized option: e

と出たあとに

  CCLD     xsltproc
/home/oku/repos/buildroot/output/host/lib/gcc/x86_64-buildroot-linux-musl/13.2.0/../../../../x86_64-buildroot-linux-musl/bin/ld: warning: libc.musl-x86_64.so.1, needed by ../libexslt/.libs/libexslt.so, not found (try using -rpath or -rpath-link)
/home/oku/repos/buildroot/output/host/lib/gcc/x86_64-buildroot-linux-musl/13.2.0/../../../../x86_64-buildroot-linux-musl/bin/ld: xsltproc.o: in function `xsltProcess':
xsltproc.c:(.text+0xae3): undefined reference to `xmlDebugDumpDocument'
/home/oku/repos/buildroot/output/host/lib/gcc/x86_64-buildroot-linux-musl/13.2.0/../../../../x86_64-buildroot-linux-musl/bin/ld: ../libxslt/.libs/libxslt.so: undefined reference to `xmlXPathDebugDumpObject'
collect2: error: ld returned 1 exit status

これはもう coreutils を入れるしかないな。。不正なconfigをしてしまったあとは一旦ビルドディレクトリを消す必要がある。

rm -rf /home/oku/repos/buildroot/output/build/libxslt-1.1.39

WebKitのビルドに失敗する

/home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/platform/graphics/gstreamer/PlatformDisplayGStreamer.cpp:26:10: fatal error: gst/gl/gl.h: No such file or directory
   26 | #include <gst/gl/gl.h>
      |          ^~~~~~~~~~~~~

これは見落しですね。。GStreamer GLはオプション。 BR2_PACKAGE_WPEWEBKIT_USE_GSTREAMER_GL を有効にするためには BR2_PACKAGE_GST1_PLUGINS_BASE_LIB_OPENGL (Target packages → Audio and video applications → gst1-plugins-base) が必要。

rm -rf /home/oku/repos/buildroot/output/build/gst1-plugins-base-1.22.9/
okuokuokuoku

デバッグしようが無いやつが来てしまった

In file included from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/platform/graphics/ImageBufferBackend.h:44,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/platform/graphics/ImageBuffer.h:31,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/html/ImageBitmapBacking.h:28,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/html/ImageBitmap.h:30,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/workers/WorkerGlobalScope.h:32,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h:35,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:36,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:32,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/WebCore/DerivedSources/unified-sources/UnifiedSource-f8afad56-57.cpp:1:
/home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/sysroot/usr/include/cairo/cairo.h:2860:39: error: expected ‘,’ or ‘...’ before end of line
 2860 |                              double x2, double y2,
      |                                       ^

こういう正常な記述がエラーになるのは x2 がマクロで定義されて何かにexpandされているパターンだな。。

とりあえず -DENABLE_UNIFIED_BUILDS=OFF して様子を見る。

ICEになった

ダメだこりゃ。。

In file included from /home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/include/c++/13.2.0/bits/ranges_base.h:39,
                 from /home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/include/c++/13.2.0/bits/ranges_util.h:34,
                 from /home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/include/c++/13.2.0/tuple:44,
                 from /home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/include/c++/13.2.0/bits/unique_ptr.h:36,
                 from /home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/include/c++/13.2.0/memory:78,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/WTF/Headers/wtf/StdLibExtras.h:30,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/WTF/Headers/wtf/FastMalloc.h:26,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/JavaScriptCore/config.h:39,
                 from /home/oku/repos/buildroot/output/build/wpewebkit-2.42.5/Source/JavaScriptCore/bytecode/ArrayProfile.cpp:26:
/home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/include/c++/13.2.0/bits/max_size_type.h: In member function ‘constexpr std::ranges::__detail::__max_size_type& std::ranges::__detail::__max_size_type::operator/=(const std::ranges::__detail::__max_size_type&):
/home/oku/repos/buildroot/output/host/x86_64-buildroot-linux-musl/include/c++/13.2.0/bits/max_size_type.h:171:18: internal compiler error: Segmentation fault
  171 |         else if (!_M_msb && __r._M_msb)
      |                  ^
0x7f6075b2dea7 ???
        src/signal/x86_64/restore.s:1