WasmLinux: Webブラウザ移植の計画を立てる
とりあえずBusyboxは動いちゃったので、究極のゴールとして "Webブラウザ上でWebブラウザ" を考える。これはガチのマジで難しい。
必要なもの
- (x86-64) BuildrootでWebブラウザが動く環境を作れること
- (x86-64) 自前のEGL + GLES2エミュレーター 上で動作するWayland compositorを作って動作させること
- (C-WebGL) EGL + GLES2をシリアライズして他所で動かす技術を確立する
- (x86-64) Wayland compositorをコンテナ側に移し、Waylandプロトコルと共有メモリが外部に出ないようにする
- (x86-32) ここまでの環境を x86-32 に移植する
- (WasmLinux) BuildrootをWasmLinuxに移植
- (WasmLinux) MMUエミュレーションなど動作に必要なものを設計 / 実装する
- (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で動作するかどうかは事前に確認しておき、問題点を潰しておくのが望ましい。
WPE WebKitは既にbuildrootにある
これを使った簡易ブラウザであるCogもある。
というわけで、一旦これが動く環境を作り、WebKitだけ最新に置き換えるのが早いだろう。WebKitはビルド時にCPUを見るはず(JITC都合)なので、どちらにせよWasmへの移植は必須になる。
BuildrootでCogを選択するまでが遠い
これ結構ハマりポイントな気もする。
Alpineでbuildrootする
rsync
patch
は追加必要だった。 ... rsync
って昔使ってたときは依存していた記憶が無いんだけど。。
あと、findコマンドのエラーが見えたので findutils
も追加。ビルド中に死んだので diffutils
も追加。さらに perl-dev
coreutils
。
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
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で治る。
一旦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/
デバッグしようが無いやつが来てしまった
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