WPE WebKitをCygwin+Clangでビルドする
とりあえずclangは何となく動くレベルにビルドできたと思うので、今までサボっていたGStreamerをビルドして真面目にexecutableをlinkするまで行きたいと思う。
GStreamerのビルド
最近のGStreamerは、いわゆるmonorepo化 https://gitlab.freedesktop.org/gstreamer/gstreamer したので、1つチェックアウトして meson
で全体をビルドできる。 ...ビルドできるが絶妙に上手くいかないので適当にワークアラウンドする。
meson --default-library=static \
-Dgst-full-libraries=app,audio,fft,gl,mpegts,pbutils,tag,video,codecparsers \
"-Dgst-full-plugins=coreelements;playback;typefindfunctions;app;pbtypes" \
-Dintrospection=disabled builddir
meson
のCMakeサポートは壊れていて、正常にreconfigureできない。オプションを変更した場合都度ビルドディレクトリを消せばOK。
生成された all
ターゲットは正常にビルドできない( gobject-introspection
がsubprojectなのに他のsubprojectから依存されている)ので、直接ターゲットを指定してビルドする。
ninja cyggstreamer-full-1.0.dll libgstreamer-full-1.0.a
pkg-config
が暴走する
... そこ!?
pkgconf --static --libs-only-l gstreamer-full-1.0
これがビジーループになり返ってこなくなる。
というかコレよく見たらpkgconf( https://github.com/pkgconf/pkgconf )じゃん。
$ pkg-config --version
1.6.3
とりあえずcygwinのsetupで差し替え。
$ pkg-config --version
0.29.1
Clangでビルド
cmake -GNinja -DCMAKE_C_COMPILER=/cygdrive/f/webkit/llvm/bin/clang \
-DCMAKE_CXX_COMPILER=/cygdrive/f/webkit/llvm/bin/clang++ \
-DCMAKE_BUILD_TYPE=Debug -DPORT=WPE \
-DWPE_INCLUDE_DIR=/cygdrive/f/webkit/proj/libwpe/include \
-DWPE_LIBRARY=/usr/lib/libelf.a \
-DUSE_SOUP2=ON -DENABLE_JOURNALD_LOG=OFF -DENABLE_JIT=OFF \
-DENABLE_C_LOOP=ON -DENABLE_SAMPLING_PROFILER=OFF \
-DENABLE_UNIFIED_BUILDS=OFF ../../proj/WebKit
デバッグ情報はサイズ的にリンクできないのが分かっているので、リンカのオプションで落としてしまうことにした。
diff --git a/Source/cmake/OptionsCommon.cmake b/Source/cmake/OptionsCommon.cmake
index c3ae81234f57..a52eddb56e08 100644
--- a/Source/cmake/OptionsCommon.cmake
+++ b/Source/cmake/OptionsCommon.cmake
@@ -97,6 +97,13 @@ if (DEBUG_FISSION)
endif ()
endif ()
+if (CYGWIN)
+ # Strip debug information for now
+ string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-S")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,-S")
+ string(APPEND CMAKE_MODULE_LINKER_FLAGS " -Wl,-S")
+endif()
+
set(GCC_OFFLINEASM_SOURCE_MAP_DEFAULT OFF)
if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(GCC_OFFLINEASM_SOURCE_MAP_DEFAULT ON)
ClangはPDBも出力できるはずなので、そっちに寄せるのがたぶん簡単だろう。。 BFD ldじゃリンクできないじゃん。。lldがCOFF+PEもリンクできるのでそれをビルドして使うのが多分早道ではあるが。。
UninstalledなGLibが正常に使えない
... マジでダメっぽいので次からはGLib(とgobject-introspection)は別途ビルドしてインストールしてから使う方が良さそうだな。。
最終的に、CMakeが検出するGLibのヘッダ/ライブラリパスは正常に使えなかったのでoverrideした。
GLIB_INCLUDE_DIR:PATH=/cygdrive/f/webkit/proj/gstreamer/subprojects/glib/glib;/cygdrive/f/webkit/proj/gstreamer/subprojects/glib;/cygdrive/f/webkit/proj/gstreamer/builddir/subprojects/glib;/cygdrive/f/webkit/proj/gstreamer/subprojects/glib/gmodule
GLIB_LIBRARIES:FILEPATH=/cygdrive/f/webkit/proj/gstreamer/builddir/subprojects/glib/glib/libglib-2.0.a;-lpcre;-liconv;-lintl
WebKit供給の FindGLIB.cmake
は、このとき GLIB_LIBRARY_DIR
が1つだけということに依存していたので適当に修正した。
diff --git a/Source/cmake/FindGLIB.cmake b/Source/cmake/FindGLIB.cmake
index 07f984ac09cf..8761cba76f2c 100644
--- a/Source/cmake/FindGLIB.cmake
+++ b/Source/cmake/FindGLIB.cmake
@@ -50,9 +50,14 @@ find_library(GLIB_LIBRARIES
${PC_GLIB_LIBRARY_DIRS}
)
+# FIXME: Handle multiple libraries returned from find_library
+
+list(GET GLIB_LIBRARIES 0 GLIB_LIBRARIES0)
+
# Files in glib's main include path may include glibconfig.h, which,
# for some odd reason, is normally in $LIBDIR/glib-2.0/include.
-get_filename_component(_GLIB_LIBRARY_DIR ${GLIB_LIBRARIES} PATH)
+get_filename_component(_GLIB_LIBRARY_DIR ${GLIB_LIBRARIES0} PATH)
+unset(GLIB_LIBRARIES0)
find_path(GLIBCONFIG_INCLUDE_DIR
NAMES glibconfig.h
HINTS ${PC_LIBDIR} ${PC_LIBRARY_DIRS} ${_GLIB_LIBRARY_DIR}
ヘッダ
/cygdrive/f/webkit/proj/gstreamer/subprojects/glib/glib/glib.h:30:10: fatal error: 'glib/galloca.h' file not found
#include <glib/galloca.h>
^~~~~~~~~~~~~~~~
1 error generated.
/cygdrive/f/webkit/proj/gstreamer/subprojects/glib/glib/glib-object.h:25:10: fatal error: 'gobject/glib-enumtypes.h' file not found
#include <gobject/glib-enumtypes.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
GLIB_INCLUDE_DIR
は1つのディレクトリしか検出しないようなので、自動生成されるヘッダが含まれるディレクトリを手動で追加してやる必要があった。
config.h
↑ のようにインクルードパスを追加すると、 WebKit 側の config.h
と GLib側の config.h
が衝突してしまって正常にリンクできなくなってしまった。
#if ENABLE(ALLOCATION_LOGGING)
^
/cygdrive/f/webkit/proj/WebKit/Source/JavaScriptCore/llint/LLIntCommon.h:36:5: error: function-like macro 'ENABLE' is not defined
#include "..." search starts here:
#include <...> search starts here:
JavaScriptCore/Headers
/cygdrive/f/webkit/proj/gstreamer/subprojects/glib/glib
/cygdrive/f/webkit/proj/gstreamer/subprojects/glib
/cygdrive/f/webkit/proj/gstreamer/builddir/subprojects/glib // ★ ← ここに config.h がある
/cygdrive/f/webkit/proj/gstreamer/subprojects/glib/gmodule
/cygdrive/f/webkit/proj/gstreamer/builddir/subprojects/glib/glib
. // ★ ← ここの config.h を #include したい
/cygdrive/f/webkit/proj/WebKit/Source/JavaScriptCore
/cygdrive/f/webkit/proj/WebKit/Source/JavaScriptCore/API
/cygdrive/f/webkit/proj/WebKit/Source/JavaScriptCore/assembler
/cygdrive/f/webkit/proj/WebKit/Source/JavaScriptCore/b3
/cygdrive/f/webkit/proj/WebKit/Source/JavaScriptCore/b3/air
:
こればっかりはどうしようもないので、 glib
内の config.h
を手で削除した。これはGLibのビルド時にしか必要ないはずだし。。
ライブラリ
... なぜか PCRE と libintl、libiconvの依存が正常にリンクされなかった。shared libraryになることを前提にしている。。??
大文字小文字の区別が必須
どうもまだコンパイルがうまくいかないのでプリプロセスしてみたら
Source/WebKit/Shared/API/c/wpe/WebKit.h
Source/WebKit/UIProcess/API/wpe/webkit.h
の2ファイルが存在し、これらは大小文字で区別されていることがわかった。
CygwinはNTFSのcase insensitive filesystemを使えるので、
chattr +C .
してからファイル消して再チェックアウトすればOK。
オープンするファイルが多すぎてリンクに失敗する
EDIT: そもそもWebKitのビルドオプションに USE_THIN_ARCHIVE
というのがあったのでそれを OFF
にすれば良いだけだと思う。( ar
の代わりに CMAKE_AR=llvm-ar
するのとセットで。。)
コンパイルは全部通ったが、リンクに失敗する。
ld: lib/libWebCore.a: error adding symbols: malformed archive
とりあえず strace
でsyscallを確認してみると、 EMFILE
https://github.com/cygwin/cygwin/blob/fb1fe932038e5a9833fcc5fc53365a2212d76584/winsup/cygwin/errno.cc#L192 つまりオープンしたファイルが多すぎて失敗していることがわかった。
1481 296127668 [main] ld 12990 open: open(lib/../Source/WebCore/CMakeFiles/WebCore.dir/editing/ReplaceNodeWithSpanCommand.cpp.o, 0x10000)
229 296127897 [main] ld 12990 __set_errno: int dtable::extend(size_t, size_t):83 setting errno 24
72 296127969 [main] ld 12990 open: -1 = open(lib/../Source/WebCore/CMakeFiles/WebCore.dir/editing/ReplaceNodeWithSpanCommand.cpp.o, 0x10000), errno 24
(errno 24 = EMFILE
)
よく見ると、 WebCore.a
は静的ライブラリのはずなのに .o をオープンしているのがわかる。これはCMakeがstatic libraryをthin archiveとして作っているのが原因で、 file
コマンドで確認できる。
$ file lib/libWebCore.a
lib/libWebCore.a: thin archive with 2662554 symbol entries
というわけで thin archive を適当に通常のアーカイブに変換することでリンクができるようになった。
ar t lib/libWebCore.a | xargs ar rs temp.a
(実際には ar
では小一時間掛かってもアーカイブが終わらなかったので llvm-ar
を使った。)