From c290fda6e542734e7aeac5608c60e46ea30c359e Mon Sep 17 00:00:00 2001 From: Vasilito Date: Thu, 16 Apr 2026 12:44:04 +0100 Subject: [PATCH] Refresh Qt and Wayland recipes Red Bear OS Team --- local/recipes/qt/redox-toolchain.cmake | 7 + .../wayland/qt6-wayland-smoke/recipe.toml | 45 +++++ .../qt6-wayland-smoke/source/CMakeLists.txt | 47 +++++ .../qt6-wayland-smoke/source/bootstrap.cpp | 47 +++++ .../wayland/qt6-wayland-smoke/source/main.cpp | 24 +++ .../qt6-wayland-smoke/source/plugincheck.cpp | 57 ++++++ .../wayland/qt6-wayland-smoke/source/qt.conf | 4 + recipes/wip/qt/qtbase/recipe.toml | 175 +++++++++++++++++- recipes/wip/qt/qtbase/redox.patch | 121 ++++++++++++ recipes/wip/qt/qtwayland/recipe.toml | 10 + recipes/wip/wayland/libwayland/recipe.toml | 123 +++++++++++- recipes/wip/wayland/libwayland/redox.patch | 82 +++++++- recipes/wip/wayland/qt6-wayland-smoke | 1 + 13 files changed, 726 insertions(+), 17 deletions(-) create mode 100644 local/recipes/wayland/qt6-wayland-smoke/recipe.toml create mode 100644 local/recipes/wayland/qt6-wayland-smoke/source/CMakeLists.txt create mode 100644 local/recipes/wayland/qt6-wayland-smoke/source/bootstrap.cpp create mode 100644 local/recipes/wayland/qt6-wayland-smoke/source/main.cpp create mode 100644 local/recipes/wayland/qt6-wayland-smoke/source/plugincheck.cpp create mode 100644 local/recipes/wayland/qt6-wayland-smoke/source/qt.conf create mode 120000 recipes/wip/wayland/qt6-wayland-smoke diff --git a/local/recipes/qt/redox-toolchain.cmake b/local/recipes/qt/redox-toolchain.cmake index d8ae01e6..718a813b 100644 --- a/local/recipes/qt/redox-toolchain.cmake +++ b/local/recipes/qt/redox-toolchain.cmake @@ -40,6 +40,13 @@ set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR x86_64) set(CMAKE_SYSTEM_VERSION 1) +# Redox userspace currently must not emit CET/IBT entry instructions (endbr64), +# because they trap as invalid opcode in the current runtime stack. +set(CMAKE_C_FLAGS "-fcf-protection=none" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS "-fcf-protection=none" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS_RELEASE "-fcf-protection=none" CACHE STRING "" FORCE) +set(CMAKE_CXX_FLAGS_RELEASE "-fcf-protection=none" CACHE STRING "" FORCE) + # Flag for redox.patch: enables REDOX-specific CMake code paths (mkspec, QPA plugin). # QtPlatformSupport.cmake checks this variable. Set as CACHE INTERNAL so it persists # across CMake re-configures and is visible in Qt's CMake modules. diff --git a/local/recipes/wayland/qt6-wayland-smoke/recipe.toml b/local/recipes/wayland/qt6-wayland-smoke/recipe.toml new file mode 100644 index 00000000..1ec20cd6 --- /dev/null +++ b/local/recipes/wayland/qt6-wayland-smoke/recipe.toml @@ -0,0 +1,45 @@ +[source] +path = "source" + +[build] +template = "custom" +dependencies = [ + "qtbase", + "qtwayland", +] +script = """ +DYNAMIC_INIT + +for qtdir in plugins mkspecs metatypes modules; do + if [ -d "${COOKBOOK_SYSROOT}/usr/${qtdir}" ] && [ -d "${COOKBOOK_SYSROOT}/${qtdir}" ] && [ ! -L "${COOKBOOK_SYSROOT}/${qtdir}" ]; then + rm -rf "${COOKBOOK_SYSROOT}/${qtdir}" + fi + if [ -d "${COOKBOOK_SYSROOT}/usr/${qtdir}" ] && [ ! -e "${COOKBOOK_SYSROOT}/${qtdir}" ]; then + ln -s "usr/${qtdir}" "${COOKBOOK_SYSROOT}/${qtdir}" + fi +done + +rm -f CMakeCache.txt +rm -rf CMakeFiles + +cmake "${COOKBOOK_SOURCE}" \ + -DCMAKE_TOOLCHAIN_FILE="${COOKBOOK_ROOT}/local/recipes/qt/redox-toolchain.cmake" \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PREFIX_PATH="${COOKBOOK_SYSROOT}" \ + -DQT_NO_PRIVATE_MODULE_WARNING=ON \ + -Wno-dev + +cmake --build . -j${COOKBOOK_MAKE_JOBS} +cmake --install . --prefix "${COOKBOOK_STAGE}/usr" + +for lib in "${COOKBOOK_STAGE}/usr/lib/"lib*.so.*; do + [ -f "${lib}" ] || continue + patchelf --remove-rpath "${lib}" 2>/dev/null || true +done +""" + +[package.files] +"/usr/bin/qt6-wayland-smoke" = "qt6-wayland-smoke" +"/usr/bin/qt6-bootstrap-check" = "qt6-bootstrap-check" +"/usr/bin/qt6-plugin-check" = "qt6-plugin-check" diff --git a/local/recipes/wayland/qt6-wayland-smoke/source/CMakeLists.txt b/local/recipes/wayland/qt6-wayland-smoke/source/CMakeLists.txt new file mode 100644 index 00000000..bc437b2d --- /dev/null +++ b/local/recipes/wayland/qt6-wayland-smoke/source/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.20) +project(qt6-wayland-smoke LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Gui Core) + +qt_add_executable(qt6-wayland-smoke + main.cpp +) + +qt_add_executable(qt6-bootstrap-check + bootstrap.cpp +) + +qt_add_executable(qt6-plugin-check + plugincheck.cpp +) + +target_compile_options(qt6-wayland-smoke PRIVATE -fcf-protection=none) +target_compile_options(qt6-bootstrap-check PRIVATE -fcf-protection=none) +target_compile_options(qt6-plugin-check PRIVATE -fcf-protection=none) + +target_link_options(qt6-wayland-smoke PRIVATE -fcf-protection=none) +target_link_options(qt6-bootstrap-check PRIVATE -fcf-protection=none) +target_link_options(qt6-plugin-check PRIVATE -fcf-protection=none) + +target_link_libraries(qt6-wayland-smoke PRIVATE + Qt6::Core + Qt6::Gui +) + +target_link_libraries(qt6-bootstrap-check PRIVATE + Qt6::Core + Qt6::Gui +) + +target_link_libraries(qt6-plugin-check PRIVATE + Qt6::Core +) + +install(TARGETS qt6-wayland-smoke RUNTIME DESTINATION bin) +install(TARGETS qt6-bootstrap-check RUNTIME DESTINATION bin) +install(TARGETS qt6-plugin-check RUNTIME DESTINATION bin) +install(FILES qt.conf DESTINATION bin) diff --git a/local/recipes/wayland/qt6-wayland-smoke/source/bootstrap.cpp b/local/recipes/wayland/qt6-wayland-smoke/source/bootstrap.cpp new file mode 100644 index 00000000..057378ae --- /dev/null +++ b/local/recipes/wayland/qt6-wayland-smoke/source/bootstrap.cpp @@ -0,0 +1,47 @@ +#include +#include + +#include +#include + +static void dumpPluginElfHeader(const char *path) { + std::fprintf(stderr, "qt6-bootstrap-check inspecting %s\n", path); + FILE *file = std::fopen(path, "rb"); + if (!file) { + std::perror("fopen"); + return; + } + + std::array hdr{}; + const size_t n = std::fread(hdr.data(), 1, hdr.size(), file); + std::fclose(file); + + std::fprintf(stderr, "qt6-bootstrap-check read %zu bytes\n", n); + std::fprintf(stderr, "qt6-bootstrap-check ELF header bytes:"); + for (size_t i = 0; i < n; ++i) { + std::fprintf(stderr, " %02x", hdr[i]); + } + std::fprintf(stderr, "\n"); + + if (n >= 58) { + const unsigned phentsize = unsigned(hdr[54]) | (unsigned(hdr[55]) << 8); + const unsigned phnum = unsigned(hdr[56]) | (unsigned(hdr[57]) << 8); + std::fprintf(stderr, + "qt6-bootstrap-check decoded ELF phentsize=%u phnum=%u\n", + phentsize, + phnum); + } +} + +int main(int argc, char **argv) { + const QByteArray platform = qEnvironmentVariableIsSet("QT_QPA_PLATFORM") + ? qgetenv("QT_QPA_PLATFORM") + : QByteArray("minimal"); + + qputenv("QT_QPA_PLATFORM", platform); + std::fprintf(stderr, "qt6-bootstrap-check before QGuiApplication platform=%s\n", platform.constData()); + dumpPluginElfHeader("/usr/plugins/platforms/libqminimal.so"); + QGuiApplication app(argc, argv); + std::fprintf(stderr, "qt6-bootstrap-check after QGuiApplication platform=%s\n", platform.constData()); + return 0; +} diff --git a/local/recipes/wayland/qt6-wayland-smoke/source/main.cpp b/local/recipes/wayland/qt6-wayland-smoke/source/main.cpp new file mode 100644 index 00000000..4d2c0a5f --- /dev/null +++ b/local/recipes/wayland/qt6-wayland-smoke/source/main.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) { + const QByteArray platform = qEnvironmentVariableIsSet("QT_QPA_PLATFORM") + ? qgetenv("QT_QPA_PLATFORM") + : QByteArray("wayland"); + + qputenv("QT_QPA_PLATFORM", platform); + std::fprintf(stderr, "qt6-wayland-smoke before QGuiApplication platform=%s\n", platform.constData()); + + QGuiApplication app(argc, argv); + std::fprintf(stderr, "qt6-wayland-smoke after QGuiApplication platform=%s\n", platform.constData()); + + qInfo() << "qt6-wayland-smoke platform" << QGuiApplication::platformName(); + + QTimer::singleShot(1000, &app, &QCoreApplication::quit); + return app.exec(); +} diff --git a/local/recipes/wayland/qt6-wayland-smoke/source/plugincheck.cpp b/local/recipes/wayland/qt6-wayland-smoke/source/plugincheck.cpp new file mode 100644 index 00000000..37c5cb9e --- /dev/null +++ b/local/recipes/wayland/qt6-wayland-smoke/source/plugincheck.cpp @@ -0,0 +1,57 @@ +#include +#include +#include + +#include +#include + +static constexpr const char *PhaseFile = "/home/root/.qt6-plugin-check.phase"; + +static void mark(const char *value) { + std::ofstream out(PhaseFile, std::ios::trunc); + out << value << '\n'; + out.flush(); +} + +int main(int argc, char **argv) { + mark("before-qcoreapplication"); + std::fprintf(stderr, "qt6-plugin-check before QCoreApplication\n"); + std::fflush(stderr); + QCoreApplication app(argc, argv); + mark("after-qcoreapplication"); + std::fprintf(stderr, "qt6-plugin-check after QCoreApplication\n"); + std::fflush(stderr); + + const QString plugin = argc > 1 + ? QString::fromLocal8Bit(argv[1]) + : QStringLiteral("/usr/plugins/platforms/libqminimal.so"); + + QPluginLoader loader(plugin); + mark("before-metadata"); + std::fprintf(stderr, "qt6-plugin-check before metadata\n"); + std::fflush(stderr); + qInfo() << "qt6-plugin-check file" << plugin; + qInfo() << "qt6-plugin-check metaData" << loader.metaData(); + + mark("before-load"); + std::fprintf(stderr, "qt6-plugin-check before load\n"); + std::fflush(stderr); + if (!loader.load()) { + mark("load-failed"); + qWarning() << "qt6-plugin-check load failed" << loader.errorString(); + return 1; + } + + QObject *instance = loader.instance(); + if (!instance) { + mark("instance-failed"); + qWarning() << "qt6-plugin-check instance failed" << loader.errorString(); + return 2; + } + + mark("instance-ok"); + std::fprintf(stderr, "qt6-plugin-check instance ok\n"); + std::fflush(stderr); + qInfo() << "qt6-plugin-check instance ok" << instance->metaObject()->className(); + return 0; +} diff --git a/local/recipes/wayland/qt6-wayland-smoke/source/qt.conf b/local/recipes/wayland/qt6-wayland-smoke/source/qt.conf new file mode 100644 index 00000000..42947cf2 --- /dev/null +++ b/local/recipes/wayland/qt6-wayland-smoke/source/qt.conf @@ -0,0 +1,4 @@ +[Paths] +Prefix=/usr +Plugins=/usr/plugins +QmlImports=/usr/qml diff --git a/recipes/wip/qt/qtbase/recipe.toml b/recipes/wip/qt/qtbase/recipe.toml index 69225bd2..a79f45ca 100644 --- a/recipes/wip/qt/qtbase/recipe.toml +++ b/recipes/wip/qt/qtbase/recipe.toml @@ -34,6 +34,25 @@ if [ -d "${RELIBC_STAGE_LIB}" ]; then export LDFLAGS="-L${RELIBC_STAGE_LIB} -Wl,-rpath-link,${RELIBC_STAGE_LIB} ${LDFLAGS}" fi +export CFLAGS="${CFLAGS} -fcf-protection=none" +export CXXFLAGS="${CXXFLAGS} -fcf-protection=none" + +# Mesa's Redox sysroot currently exposes GLES2 headers but not the GLES3 wrapper headers +# that qtbase expects when building the ES-backed OpenGL path. Provide minimal forwarding +# wrappers in the per-recipe sysroot so clean rebuilds do not fail on missing gl3*.h. +mkdir -p "${COOKBOOK_SYSROOT}/include/GLES3" +for hdr in gl3.h gl31.h gl32.h; do + if [ ! -f "${COOKBOOK_SYSROOT}/include/GLES3/${hdr}" ]; then + cat > "${COOKBOOK_SYSROOT}/include/GLES3/${hdr}" <<'GLES3_EOF' +#ifndef REDBEAR_QT_GLES3_WRAPPER_H +#define REDBEAR_QT_GLES3_WRAPPER_H +#include +#include +#endif +GLES3_EOF + fi +done + # ============================================================ # Step 1: Build Qt host tools (moc, rcc, uic) on the host # These are needed for cross-compilation — Qt6 generates code @@ -158,6 +177,15 @@ sed -i 's/^ add_subdirectory(network)/ # add_subdirectory(network) # disab # Disable TUIO touch plugin — depends on QtNetwork which is disabled sed -i 's/^ add_subdirectory(tuiotouch)/ # add_subdirectory(tuiotouch) # disabled for Redox (needs Network)/' \ "${COOKBOOK_SOURCE}/src/plugins/generic/CMakeLists.txt" +# Disable Wayland shm-emulation-server on Redox. +# It requires QSharedMemory lock/unlock support, which is gated behind systemsemaphore +# and is not available in the current Redox QtCore configuration. +HWI_CMAKE="${COOKBOOK_SOURCE}/src/plugins/platforms/wayland/plugins/hardwareintegration/CMakeLists.txt" +awk 'index($0, "if(QT_FEATURE_wayland_shm_emulation_server_buffer)") { + print "if(FALSE AND QT_FEATURE_wayland_shm_emulation_server_buffer) # disabled for Redox (no systemsemaphore-backed QSharedMemory locking)"; + next + } { print }' "${HWI_CMAKE}" > "${HWI_CMAKE}.tmp" +mv "${HWI_CMAKE}.tmp" "${HWI_CMAKE}" # QtGui needs the float16 shims — copy to gui dir and append to first SOURCES line cp "${COOKBOOK_SOURCE}/src/corelib/global/qt_float16_shims.c" \ @@ -189,14 +217,103 @@ awk ' ' "${BUFI}" > "${BUFI}.tmp" mv "${BUFI}.tmp" "${BUFI}" -# qtypes.h uses static_assert (C11 macro from ) but forkfd_qt.c (C file) -# includes qglobal→qtypes before assert.h. Add the include guard for C mode. +# qtypes.h uses static_assert in C mode. relibc's assert.h does not currently expose the +# expected macro there, so inject both the include and a bounded fallback macro for C only. QTYPES="${COOKBOOK_SOURCE}/src/corelib/global/qtypes.h" -if ! grep -q 'assert.h' "${QTYPES}" 2>/dev/null; then +if ! grep -q '#ifndef __cplusplus.*#include ' "${QTYPES}" 2>/dev/null; then awk '/#ifndef __cplusplus/ { print; print "#include "; next } { print }' \ "${QTYPES}" > "${QTYPES}.tmp" mv "${QTYPES}.tmp" "${QTYPES}" fi +if ! grep -q '#define static_assert _Static_assert' "${QTYPES}" 2>/dev/null; then + awk '/#include / { print; print "#ifndef static_assert"; print "#define static_assert _Static_assert"; print "#endif"; next } { print }' \ + "${QTYPES}" > "${QTYPES}.tmp" + mv "${QTYPES}.tmp" "${QTYPES}" +fi + +# For Redox diagnostics, turn Q_UNREACHABLE into a Qt assertion instead of a raw ud2 trap. +# This preserves a useful file/line failure path while we narrow remaining early-startup issues. +QASSERT_H="${COOKBOOK_SOURCE}/src/corelib/global/qassert.h" +if ! grep -q 'Q_OS_REDOX' "${QASSERT_H}" 2>/dev/null; then + python - </dev/null; then + awk '/#include / { + print; + print "#ifdef __redox__"; + print "#define REDOX_WAITID_IDTYPE_SHIMS 1"; + print "#ifndef P_ALL"; + print "#define P_ALL 0"; + print "#endif"; + print "#ifndef P_PID"; + print "#define P_PID 1"; + print "#endif"; + print "#ifndef P_PGID"; + print "#define P_PGID 2"; + print "#endif"; + print "#endif"; + next + } { print }' "${FORKFD_C}" > "${FORKFD_C}.tmp" + mv "${FORKFD_C}.tmp" "${FORKFD_C}" +fi +if ! grep -q 'REDOX_DISABLE_HAVE_WAITID' "${FORKFD_C}" 2>/dev/null; then + awk 'index($0, "#if !defined(WEXITED) || !defined(WNOWAIT)") { + print; + print "#ifdef __redox__"; + print "#define REDOX_DISABLE_HAVE_WAITID 1"; + print "#undef HAVE_WAITID"; + print "#endif"; + next + } { print }' "${FORKFD_C}" > "${FORKFD_C}.tmp" + mv "${FORKFD_C}.tmp" "${FORKFD_C}" +fi +if ! grep -q 'REDOX_FORCE_WAITPID_FALLBACK' "${FORKFD_C}" 2>/dev/null; then + awk 'index($0, "#if defined(__APPLE__)") { + print "#ifdef __redox__"; + print "#define REDOX_FORCE_WAITPID_FALLBACK 1"; + print "#undef HAVE_WAITID"; + print "#endif"; + print; + next + } { print }' "${FORKFD_C}" > "${FORKFD_C}.tmp" + mv "${FORKFD_C}.tmp" "${FORKFD_C}" +fi # qprocess_unix.cpp needs sys/ioctl.h (for FIONREAD) but doesn't include it QP="${COOKBOOK_SOURCE}/src/corelib/io/qprocess_unix.cpp" @@ -205,6 +322,56 @@ if ! grep -q 'sys/ioctl.h' "${QP}" 2>/dev/null; then "${QP}" > "${QP}.tmp" mv "${QP}.tmp" "${QP}" fi +if ! grep -q 'REDOX_VFORK_SHIM' "${QP}" 2>/dev/null; then + awk '/#include / { + print; + print "#ifdef __redox__"; + print "#define REDOX_VFORK_SHIM 1"; + print "#ifndef vfork"; + print "#define vfork fork"; + print "#endif"; + print "#endif"; + next + } { print }' "${QP}" > "${QP}.tmp" + mv "${QP}.tmp" "${QP}" +fi + +# On Redox, keep Qt plugin metadata at the architectural baseline. +# The x86 plugin arch-requirement path produces feature-level warnings at runtime +# and can cause otherwise-present plugins to be rejected before load. +QPLUGIN_H="${COOKBOOK_SOURCE}/src/corelib/plugin/qplugin.h" +export QPLUGIN_H +python - <<'PY' +from pathlib import Path +import os + +path = Path(os.environ["QPLUGIN_H"]) +text = path.read_text() +needle = ''' static constexpr quint8 archRequirements() + { + quint8 v = 0; +''' +replacement = ''' static constexpr quint8 archRequirements() + { +#ifdef Q_OS_REDOX + return 0; +#else + quint8 v = 0; +''' +if needle in text and "#ifdef Q_OS_REDOX" not in text: + text = text.replace(needle, replacement, 1) + text = text.replace( + ''' return v; + } +''', + ''' return v; +#endif + } +''', + 1, + ) +path.write_text(text) +PY cmake "${COOKBOOK_SOURCE}" \ -DCMAKE_TOOLCHAIN_FILE="${COOKBOOK_ROOT}/local/recipes/qt/redox-toolchain.cmake" \ @@ -297,5 +464,5 @@ for lib in "${COOKBOOK_STAGE}/usr/lib/libQt6"*.so.*; do [ -f "${lib}" ] || continue patchelf --remove-rpath "${lib}" 2>/dev/null || true done -find "${COOKBOOK_STAGE}/usr/plugins" -name '*.so' -exec patchelf --remove-rpath {} + 2>/dev/null || true +find "${COOKBOOK_STAGE}/usr/plugins" -name '*.so' -exec patchelf --set-rpath '$ORIGIN/../../lib' {} + 2>/dev/null || true """ diff --git a/recipes/wip/qt/qtbase/redox.patch b/recipes/wip/qt/qtbase/redox.patch index 94d81d81..fd25a3f3 100644 --- a/recipes/wip/qt/qtbase/redox.patch +++ b/recipes/wip/qt/qtbase/redox.patch @@ -258,7 +258,128 @@ diff -ruwN source-old/src/corelib/io/qstorageinfo_unix.cpp source/src/corelib/io +#elif defined(Q_OS_HAIKU) || defined(Q_OS_CYGWIN) # define QT_STATFSBUF struct statvfs # define QT_STATFS ::statvfs + +diff -ruwN source-old/configure.cmake source/configure.cmake +--- source-old/configure.cmake 2024-12-02 05:39:06.000000000 +0000 ++++ source/configure.cmake 2026-04-15 00:00:00.000000000 +0000 +@@ -1233,7 +1233,7 @@ + qt_feature("intelcet" PRIVATE + LABEL "Using Intel Control-flow Enforcement Technology (CET)" + AUTODETECT ON +- CONDITION TEST_intelcet ++ CONDITION TEST_intelcet AND NOT REDOX + ) + qt_feature_config("intelcet" QMAKE_PUBLIC_CONFIG) + qt_feature("glibc_fortify_source" PRIVATE +diff -ruwN source-old/cmake/QtBaseConfigureTests.cmake source/cmake/QtBaseConfigureTests.cmake +--- source-old/cmake/QtBaseConfigureTests.cmake 2024-12-02 05:39:06.000000000 +0000 ++++ source/cmake/QtBaseConfigureTests.cmake 2026-04-16 00:00:00.000000000 +0000 +@@ -265,4 +265,23 @@ + set(TEST_subarch_sse4_1 FALSE CACHE BOOL INTERNAL FORCE) + set(TEST_subarch_sse4_2 FALSE CACHE BOOL INTERNAL FORCE) + endif() ++if(REDOX) ++ set(QT_FEATURE_avx OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx2 OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_f16c OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512f OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512er OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512cd OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512pf OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512dq OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512bw OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512vl OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512ifma OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512vbmi OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_avx512vbmi2 OFF CACHE BOOL INTERNAL FORCE) ++ set(QT_FEATURE_vaes OFF CACHE BOOL INTERNAL FORCE) ++ set(TEST_subarch_avx FALSE CACHE BOOL INTERNAL FORCE) ++ set(TEST_subarch_avx2 FALSE CACHE BOOL INTERNAL FORCE) ++ set(TEST_subarch_avx512vbmi2 FALSE CACHE BOOL INTERNAL FORCE) ++endif() + qt_run_qtbase_config_tests() + +diff -ruwN source-old/src/corelib/plugin/qelfparser_p.cpp source/src/corelib/plugin/qelfparser_p.cpp +--- source-old/src/corelib/plugin/qelfparser_p.cpp 2024-12-02 05:39:06.000000000 +0000 ++++ source/src/corelib/plugin/qelfparser_p.cpp 2026-04-15 00:00:00.000000000 +0000 +@@ -177,5 +177,8 @@ + static bool checkElfVersion(const uchar *ident) + { ++#ifdef Q_OS_REDOX ++ return true; ++#endif + uchar elfversion = ident[EI_VERSION]; + return elfversion == EV_CURRENT; + } +@@ -258,4 +261,7 @@ + static bool checkFileVersion(const Ehdr &header) + { ++#ifdef Q_OS_REDOX ++ return true; ++#endif + return header.e_version == EV_CURRENT; + } + +diff -ruwN source-old/src/corelib/plugin/qlibrary.cpp source/src/corelib/plugin/qlibrary.cpp +--- source-old/src/corelib/plugin/qlibrary.cpp 2024-12-02 05:39:06.000000000 +0000 ++++ source/src/corelib/plugin/qlibrary.cpp 2026-04-16 00:00:00.000000000 +0000 +@@ -232,24 +232,35 @@ + qsizetype fdlen = qMin(file.size(), MaxMemoryMapSize); +- const char *filedata = reinterpret_cast(file.map(0, fdlen)); ++ const char *filedata = nullptr; ++ QByteArray data; ++ ++#ifdef Q_OS_REDOX ++ data = file.read(qMin(fdlen, 64 * 1024 * 1024)); ++ filedata = data.constData(); ++ fdlen = data.size(); ++ if (filedata == nullptr || fdlen == 0) { ++ qCWarning(qt_lcDebugPlugins, "%ls: failed to read for metadata scan: %ls", ++ qUtf16Printable(library), qUtf16Printable(file.errorString())); ++ return {}; ++ } ++#else ++ filedata = reinterpret_cast(file.map(0, fdlen)); ++#endif + + #ifdef Q_OS_UNIX + if (filedata == nullptr) { + // If we can't mmap(), then the dynamic loader won't be able to either. + // This can't be used as a plugin. + qCWarning(qt_lcDebugPlugins, "%ls: failed to map to memory: %ls", + qUtf16Printable(library), qUtf16Printable(file.errorString())); + return {}; + } #else +- QByteArray data; + if (filedata == nullptr) { + // It's unknown at this point whether Windows supports LoadLibrary() on + // files that fail to CreateFileMapping / MapViewOfFile, so we err on + // the side of doing a regular read into memory (up to 64 MB). + data = file.read(64 * 1024 * 1024); + filedata = data.constData(); + fdlen = data.size(); + } + #endif + + QString errMsg = library; + +diff -ruwN source-old/src/corelib/global/qsimd.cpp source/src/corelib/global/qsimd.cpp +--- source-old/src/corelib/global/qsimd.cpp 2024-12-02 05:39:06.000000000 +0000 ++++ source/src/corelib/global/qsimd.cpp 2026-04-16 00:00:00.000000000 +0000 +@@ -377,7 +377,11 @@ + static void xgetbv(uint in, uint &eax, uint &edx) + { +-#if (defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)) || defined(Q_CC_GHS) ++#ifdef Q_OS_REDOX ++ Q_UNUSED(in); ++ eax = 0; ++ edx = 0; ++#elif (defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)) || defined(Q_CC_GHS) + asm (".byte 0x0F, 0x01, 0xD0" // xgetbv instruction + : "=a" (eax), "=d" (edx) + : "c" (in)); + diff -ruwN source-old/src/corelib/io/qfilesystemengine_unix.cpp source/src/corelib/io/qfilesystemengine_unix.cpp --- source-old/src/corelib/io/qfilesystemengine_unix.cpp 2024-12-02 05:39:06.000000000 +0000 +++ source/src/corelib/io/qfilesystemengine_unix.cpp 2026-04-13 00:00:00.000000000 +0000 diff --git a/recipes/wip/qt/qtwayland/recipe.toml b/recipes/wip/qt/qtwayland/recipe.toml index 1da6a2a1..e8fa97c1 100644 --- a/recipes/wip/qt/qtwayland/recipe.toml +++ b/recipes/wip/qt/qtwayland/recipe.toml @@ -32,6 +32,16 @@ if [ -f "${SERVER_H}" ] && ! grep -q 'QT_CONFIG(opengl)' "${SERVER_H}" 2>/dev/nu : fi +# Disable compositor shm-emulation-server on Redox. +# It depends on QSharedMemory lock/unlock, which are gated behind systemsemaphore-backed +# sharedmemory support not present in the current Redox Qt stack. +QTWAYLAND_HWI_CMAKE="${COOKBOOK_SOURCE}/src/plugins/hardwareintegration/compositor/CMakeLists.txt" +awk 'index($0, "if(QT_FEATURE_wayland_shm_emulation_server_buffer)") { + print "if(FALSE AND QT_FEATURE_wayland_shm_emulation_server_buffer) # disabled for Redox (no systemsemaphore-backed QSharedMemory locking)"; + next + } { print }' "${QTWAYLAND_HWI_CMAKE}" > "${QTWAYLAND_HWI_CMAKE}.tmp" +mv "${QTWAYLAND_HWI_CMAKE}.tmp" "${QTWAYLAND_HWI_CMAKE}" + # Create dummy SBOM to satisfy Qt's install-time reference mkdir -p "${COOKBOOK_BUILD}/qt_sbom/sbom" if [ -f "${COOKBOOK_ROOT}/recipes/wip/qt/qtbase/target/x86_64-unknown-redox/build/qt_sbom/staging-qtbase.spdx.in" ]; then diff --git a/recipes/wip/wayland/libwayland/recipe.toml b/recipes/wip/wayland/libwayland/recipe.toml index 2b1ad695..6b033a62 100644 --- a/recipes/wip/wayland/libwayland/recipe.toml +++ b/recipes/wip/wayland/libwayland/recipe.toml @@ -3,19 +3,124 @@ # redox.patch restores the Redox compatibility stubs plus Meson scanner detection. [source] tar = "https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.24.0/downloads/wayland-1.24.0.tar.xz" -patches = [ - "redox.patch" -] + [build] -template = "meson" +template = "custom" dependencies = [ "relibc", "libffi", "expat", "libxml2", ] -mesonflags = [ - "-Ddocumentation=false", - "-Dtests=false", - "-Ddtd_validation=false", -] +script = """ +DYNAMIC_INIT + +python - <<'PY' +import os +from pathlib import Path + +source_root = Path(os.environ["COOKBOOK_SOURCE"]) + +meson = source_root / "src/meson.build" +meson_text = meson.read_text() +meson_text = meson_text.replace( + '''\tscanner_dep = dependency('wayland-scanner', native: true, version: meson.project_version()) +\twayland_scanner_for_build = find_program(scanner_dep.get_variable(pkgconfig: 'wayland_scanner'))''', + '''\twayland_scanner_for_build = find_program('wayland-scanner', native: true)''', +) +meson.write_text(meson_text) + +event_loop = source_root / "src/event-loop.c" +event_text = event_loop.read_text() +event_text = event_text.replace( + '''#include +#include +#include ''', + '''#include +#ifdef __redox__ +#include +#ifndef SFD_CLOEXEC +#define SFD_CLOEXEC O_CLOEXEC +#endif +#ifndef SFD_NONBLOCK +#define SFD_NONBLOCK O_NONBLOCK +#endif +struct signalfd_siginfo { + uint8_t pad[128]; +}; +int signalfd(int fd, const sigset_t *mask, int flags); +#ifndef TFD_CLOEXEC +#define TFD_CLOEXEC O_CLOEXEC +#endif +#ifndef TFD_NONBLOCK +#define TFD_NONBLOCK O_NONBLOCK +#endif +#ifndef TFD_TIMER_ABSTIME +#define TFD_TIMER_ABSTIME TIMER_ABSTIME +#endif +int timerfd_create(int clockid, int flags); +int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value); +#else +#include +#include +#endif''', +) +if "TFD_TIMER_ABSTIME" not in event_text: + event_text = event_text.replace( + '''#ifndef TFD_NONBLOCK +#define TFD_NONBLOCK O_NONBLOCK +#endif +int timerfd_create''', + '''#ifndef TFD_NONBLOCK +#define TFD_NONBLOCK O_NONBLOCK +#endif +#ifndef TFD_TIMER_ABSTIME +#define TFD_TIMER_ABSTIME TIMER_ABSTIME +#endif +int timerfd_create''', + ) +event_loop.write_text(event_text) + +server = source_root / "src/wayland-server.c" +server_text = server.read_text() +server_text = server_text.replace( + '''#include +#include ''', + '''#include +#ifdef __redox__ +#ifndef EFD_CLOEXEC +#define EFD_CLOEXEC O_CLOEXEC +#endif +#ifndef EFD_NONBLOCK +#define EFD_NONBLOCK O_NONBLOCK +#endif +int eventfd(unsigned int initval, int flags); +#else +#include +#endif''', +) +server.write_text(server_text) + +connection = source_root / "src/connection.c" +connection_text = connection.read_text() +connection_text = connection_text.replace( + '''#include + +#include "wayland-util.h"''', + '''#include + +#ifdef __redox__ +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif +FILE *open_memstream(char **bufp, size_t *sizep); +#endif + +#include "wayland-util.h"''', +) +connection.write_text(connection_text) +PY + +COOKBOOK_MESON_FLAGS+=("-Ddocumentation=false" "-Dtests=false" "-Ddtd_validation=false") +cookbook_meson +""" diff --git a/recipes/wip/wayland/libwayland/redox.patch b/recipes/wip/wayland/libwayland/redox.patch index c51c1b0b..19399e52 100644 --- a/recipes/wip/wayland/libwayland/redox.patch +++ b/recipes/wip/wayland/libwayland/redox.patch @@ -1,6 +1,6 @@ -diff -ruwN source-old/src/meson.build source/src/meson.build ---- source-old/src/meson.build 2025-07-06 13:11:26.000000000 +0100 -+++ source/src/meson.build 2026-04-14 19:30:00.000000000 +0100 +diff --git a/src/meson.build b/src/meson.build +--- a/src/meson.build ++++ b/src/meson.build @@ -81,8 +81,7 @@ endif @@ -9,5 +9,79 @@ diff -ruwN source-old/src/meson.build source/src/meson.build - wayland_scanner_for_build = find_program(scanner_dep.get_variable(pkgconfig: 'wayland_scanner')) + wayland_scanner_for_build = find_program('wayland-scanner', native: true) else - wayland_scanner_for_build = wayland_scanner + wayland_scanner_for_build = wayland_scanner endif +diff --git a/src/event-loop.c b/src/event-loop.c +--- a/src/event-loop.c ++++ b/src/event-loop.c +@@ -35,7 +35,32 @@ + #include + #include + #include ++#ifdef __redox__ ++#include ++#ifndef SFD_CLOEXEC ++#define SFD_CLOEXEC O_CLOEXEC ++#endif ++#ifndef SFD_NONBLOCK ++#define SFD_NONBLOCK O_NONBLOCK ++#endif ++struct signalfd_siginfo { ++ uint8_t pad[128]; ++}; ++int signalfd(int fd, const sigset_t *mask, int flags); ++#else + #include ++#endif + #ifdef __redox__ + #ifndef TFD_CLOEXEC + #define TFD_CLOEXEC O_CLOEXEC + #endif + #ifndef TFD_NONBLOCK + #define TFD_NONBLOCK O_NONBLOCK + #endif + int timerfd_create(int clockid, int flags); + int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value); + #else + #include + #endif + #include + #include "timespec-util.h" +diff --git a/src/wayland-server.c b/src/wayland-server.c +--- a/src/wayland-server.c ++++ b/src/wayland-server.c +@@ -39,7 +39,17 @@ + #include + #include + #include ++#ifdef __redox__ ++#ifndef EFD_CLOEXEC ++#define EFD_CLOEXEC O_CLOEXEC ++#endif ++#ifndef EFD_NONBLOCK ++#define EFD_NONBLOCK O_NONBLOCK ++#endif ++int eventfd(unsigned int initval, int flags); ++#else + #include ++#endif + #include + #include + +diff --git a/src/connection.c b/src/connection.c +--- a/src/connection.c ++++ b/src/connection.c +@@ -40,6 +40,13 @@ + #include + #include + ++#ifdef __redox__ ++#ifndef MSG_NOSIGNAL ++#define MSG_NOSIGNAL 0 ++#endif ++FILE *open_memstream(char **bufp, size_t *sizep); ++#endif ++ + #include "wayland-util.h" + #include "wayland-private.h" + #include "wayland-os.h" diff --git a/recipes/wip/wayland/qt6-wayland-smoke b/recipes/wip/wayland/qt6-wayland-smoke new file mode 120000 index 00000000..0c08031d --- /dev/null +++ b/recipes/wip/wayland/qt6-wayland-smoke @@ -0,0 +1 @@ +../../../local/recipes/wayland/qt6-wayland-smoke \ No newline at end of file