Open7

WebKitを頑張ってCygwinでコンパイルしたい

okuokuokuoku

マジでどうやってんの。。?(CygwinにはWebKitGtkのパッケージがあるので)

Configure

cmake -GNinja -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_VIDEO=OFF \
-DENABLE_WEB_AUDIO=OFF -DENABLE_JIT=OFF -DENABLE_C_LOOP=ON \
-DENABLE_SAMPLING_PROFILER=OFF -DENABLE_UNIFIED_BUILDS=OFF .

とりあえず、

  • USE_SOUP2 -- Cygwinにはlibsoupがver.2系しか無かったため
  • WebAudio、Video無効 -- CygwinのGStreamerが古くてビルドに使えなかったので
  • ENABLE_C_LOOP 、 JSCのJITC無効 -- 無理に決まってるので
  • ENABLE_UNIFIED_BUILDS=OFF -- デバッグ用

また、 libwpe に関してはビルドせずとりあえずヘッダだけ供給してお茶を濁すことにした。 libelfは適当に選んだダミー。

okuokuokuoku

ビルドオプションの調整

GLibの要求バージョンを下げる

たぶんDebianとかのバージョンを基準に適当に上げてるよね。

https://bugs.webkit.org/show_bug.cgi?id=231726

diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake
index 023fbaab4f70..c71367e093c5 100644
--- a/Source/cmake/OptionsWPE.cmake
+++ b/Source/cmake/OptionsWPE.cmake
@@ -8,7 +8,7 @@ set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string")
 find_package(Cairo 1.14.0 REQUIRED)
 find_package(Fontconfig 2.8.0 REQUIRED)
 find_package(Freetype 2.4.2 REQUIRED)
-find_package(GLIB 2.56.4 REQUIRED COMPONENTS gio gio-unix gobject gthread gmodule)
+find_package(GLIB 2.54.3 REQUIRED COMPONENTS gio gio-unix gobject gthread gmodule)
 find_package(HarfBuzz 0.9.18 REQUIRED COMPONENTS ICU)
 find_package(ICU 61.2 REQUIRED COMPONENTS data i18n uc)
 find_package(JPEG REQUIRED)

IsDebuggerPresent が検出されないようにする

/cygdrive/f/webkit/proj/WebKit/Source/WTF/wtf/Assertions.cpp: In function ‘void vprintf_stderr_common(const char*, va_list)’:
/cygdrive/f/webkit/proj/WebKit/Source/WTF/wtf/Assertions.cpp:170:9: error: ‘IsDebuggerPresent’ was not declared in this scope
  170 |     if (IsDebuggerPresent()) {
      |         ^~~~~~~~~~~~~~~~~
/cygdrive/f/webkit/proj/WebKit/Source/WTF/wtf/Assertions.cpp:176:17: error: ‘OutputDebugStringA’ was not declared in this scope
  176 |                 OutputDebugStringA(buffer.data());
      |                 ^~~~~~~~~~~~~~~~~~

CygwinはWindowsなので、Windows用のAPIであるところのIsDebuggerPresentが検出される。これだとビルドが通らないので検出自体を抑制してやる必要がある。

+if(NOT CYGWIN)
 WEBKIT_CHECK_HAVE_FUNCTION(HAVE_ISDEBUGGERPRESENT IsDebuggerPresent)
+endif()

C++のプラットフォーム固有拡張を有効にする

Cygwinでは可能な限り標準に準拠しようとする挙動のため -std=c++2a を指定するとPOSIX拡張がC++で使えなくなってしまう。

/cygdrive/f/webkit/proj/WebKit/Source/WTF/wtf/Threading.h:278:49: error: ‘siginfo_t’ has not been declared
  278 |     static void signalHandlerSuspendResume(int, siginfo_t*, void* ucontext);
      |                                                 ^~~~~~~~~

これはCMakeの CMAKE_CXX_EXTENSIONS 変数で -std=gnu++2a を使うように調整できる。

diff --git a/Source/cmake/OptionsCommon.cmake b/Source/cmake/OptionsCommon.cmake
index fb6e8a122145..c3ae81234f57 100644
--- a/Source/cmake/OptionsCommon.cmake
+++ b/Source/cmake/OptionsCommon.cmake
@@ -1,6 +1,10 @@
 set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
+if(CYGWIN)
+    set(CMAKE_CXX_EXTENSIONS ON)
+else()
+    set(CMAKE_CXX_EXTENSIONS OFF)
+endif()

 add_definitions(-DBUILDING_WITH_CMAKE=1)
 add_definitions(-DHAVE_CONFIG_H=1)
okuokuokuoku

pthread関連の調整

_GNU_SOURCE する

diff --git a/Source/WTF/wtf/StackBounds.cpp b/Source/WTF/wtf/StackBounds.cpp
index e9d9d583e355..e08dd6f0621d 100644
--- a/Source/WTF/wtf/StackBounds.cpp
+++ b/Source/WTF/wtf/StackBounds.cpp
@@ -1,3 +1,4 @@
+#define _GNU_SOURCE 1 // pthread_getattr_np
 /*
  *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>

<pthread_np.h> の一部定義に必要 ...これはCygwinの仕様だけどちょっとやりすぎ感はあるな。。(非標準ヘッダだし)

pthread_key_t がポインタである

WTF/Headers/wtf/ThreadingPrimitives.h:119:63: error: invalid conversion from ‘int’ to ‘WTF::ThreadSpecificKey’ {aka ‘__pthread_key_t*} [-fpermissive]
  119 | static constexpr ThreadSpecificKey InvalidThreadSpecificKey = PTHREAD_KEYS_MAX;
      |                                                               ^~~~~~~~~~~~~~~~
      |                                                               |
      |                                                               int
WTF/Headers/wtf/ThreadingPrimitives.h:119:63: error:reinterpret_cast’ from integer to pointer

すげぇそもそも論として PTHREAD_KEYS_MAX は個数なので pthread_key_t にキャストできない(はず)。とりあえず nullptr になることは無いので、ゼロを設定しておく。

diff --git a/Source/WTF/wtf/ThreadingPrimitives.h b/Source/WTF/wtf/ThreadingPrimitives.h
index fd559b242ddf..f3b083998ec8 100644
--- a/Source/WTF/wtf/ThreadingPrimitives.h
+++ b/Source/WTF/wtf/ThreadingPrimitives.h
@@ -57,7 +57,7 @@ using PlatformThreadHandle = pthread_t;
 using PlatformMutex = pthread_mutex_t;
 using PlatformCondition = pthread_cond_t;
 using ThreadSpecificKey = pthread_key_t;
-#if OS(LINUX)
+#if OS(LINUX) || defined(__CYGWIN__)
 using ThreadIdentifier = pid_t;
 #endif
 #elif OS(WINDOWS)
@@ -116,7 +116,8 @@ private:

 #if USE(PTHREADS)

-static constexpr ThreadSpecificKey InvalidThreadSpecificKey = PTHREAD_KEYS_MAX;
+//static constexpr ThreadSpecificKey InvalidThreadSpecificKey = PTHREAD_KEYS_MAX;
+static constexpr ThreadSpecificKey InvalidThreadSpecificKey = 0;

 inline void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
 {
okuokuokuoku

ANGLEの修正

TLSIndexの修正

WebKit本体と違ってこちらは -1 を使っていて、整数からポインタには static_cast できないので reinterpret_cast に置き換え。

diff --git a/Source/ThirdParty/ANGLE/src/common/tls.h b/Source/ThirdParty/ANGLE/src/common/tls.h
index 4075f3c03068..4f6897dd8ec5 100644
--- a/Source/ThirdParty/ANGLE/src/common/tls.h
+++ b/Source/ThirdParty/ANGLE/src/common/tls.h
@@ -39,7 +39,11 @@ typedef DWORD TLSIndex;
 #    include <pthread.h>
 #    include <semaphore.h>
 typedef pthread_key_t TLSIndex;
+#ifdef __CYGWIN__
+#    define TLS_INVALID_INDEX (reinterpret_cast<TLSIndex>(-1))
+#else
 #    define TLS_INVALID_INDEX (static_cast<TLSIndex>(-1))
+#endif
 #else
 #    error Unsupported platform.
 #endif

Dl_info には _GNU_SOURCE が必要

ELF系のOSによくある Dl_info はCygwinにもあるが _GNU_SOURCE しないと見えない。

diff --git a/Source/ThirdParty/ANGLE/src/common/system_utils_posix.cpp b/Source/ThirdParty/ANGLE/src/common/system_utils_posix.cpp
index feb944518997..f0343b1e8e00 100644
--- a/Source/ThirdParty/ANGLE/src/common/system_utils_posix.cpp
+++ b/Source/ThirdParty/ANGLE/src/common/system_utils_posix.cpp
@@ -1,3 +1,4 @@
+#define _GNU_SOURCE 1 // Dl_info
 //
 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
@@ -11,7 +12,6 @@

 #include <array>
 #include <iostream>
-
 #include <dlfcn.h>
 #ifdef ANGLE_PLATFORM_FUCHSIA
 #    include <zircon/process.h>
okuokuokuoku

JavaScriptCoreまわりの修正

mincore はWindowsには存在しない

/cygdrive/f/webkit/proj/WebKit/Source/JavaScriptCore/heap/BlockDirectory.cpp:68:77: error: ‘mincore’ was not declared in this scope; did you mean ‘minor’?
   68 |     using MincoreBufferType = std::remove_pointer_t<FunctionTraits<decltype(mincore)>::ArgumentType<2>>;
      |                                                                             ^~~~~~~
      |                                                                             minor

ここでは無くても困らないので、関連コードを #if で外してしまう。

diff --git a/Source/JavaScriptCore/heap/BlockDirectory.cpp b/Source/JavaScriptCore/heap/BlockDirectory.cp
p
index e2a3540f86d2..8f20b820a892 100644
--- a/Source/JavaScriptCore/heap/BlockDirectory.cpp
+++ b/Source/JavaScriptCore/heap/BlockDirectory.cpp
@@ -60,7 +60,7 @@ void BlockDirectory::setSubspace(Subspace* subspace)
 void BlockDirectory::updatePercentageOfPagedOutPages(SimpleStats& stats)
 {
     // FIXME: We should figure out a solution for Windows.
-#if OS(UNIX)
+#if OS(UNIX) && !defined(__CYGWIN__)
     size_t pageSize = WTF::pageSize();
     ASSERT(!(MarkedBlock::blockSize % pageSize));
     auto numberOfPagesInMarkedBlock = MarkedBlock::blockSize / pageSize;

MemoryPressureHandler はLinux用のものを使える

CygwinはLinuxのprocfsをエミュレートするので、MemoryPressureHandlerについてはLinux用のものを流用できる。

okuokuokuoku

#include が欠けているのを修正

最近あったコミットのせいでビルドが失敗しているようだ。

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

WTF/Headers/wtf/GenericHashKey.h:90:93: error: expected template-name before ‘<’ token
   90 | template<typename K, typename H> struct HashTraits<GenericHashKey<K, H>> : GenericHashTraits<GenericHashKey<K, H>> {
      |       

必要な #include が抜けている。

diff --git a/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h b/Source/JavaScriptCore/runtime/Fun
ctionHasExecutedCache.h
index 9bc808138864..4495da82330c 100644
--- a/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h
+++ b/Source/JavaScriptCore/runtime/FunctionHasExecutedCache.h
@@ -26,6 +26,8 @@
 #pragma once

 #include "SourceID.h"
+#include <wtf/HashMap.h>
+#include <wtf/HashTraits.h>
 #include <wtf/GenericHashKey.h>
 #include <wtf/Vector.h>

okuokuokuoku

Internal Compiler Errorになる

-std=gnu++2a -MD -MT Source/WebCore/CMakeFiles/WebCore.dir/__/__/WebCore/DerivedSources/JSDOMWindow.cpp.o -MF Source/WebCore/CMakeFiles/WebCore.dir/__/__/WebCore/DerivedSources/JSDOMWindow.cpp.o.d -o Source/WebCore/CMakeFiles/WebCore.dir/__/__/WebCore/DerivedSources/JSDOMWindow.cpp.o -c WebCore/DerivedSources/JSDOMWindow.cpp
c++: internal compiler error: Segmentation fault signal terminated program cc1plus
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.

ダメだな。。