Refresh Qt and Wayland recipes

Red Bear OS Team
This commit is contained in:
2026-04-16 12:44:04 +01:00
parent 35193bb32d
commit c290fda6e5
13 changed files with 726 additions and 17 deletions
+7
View File
@@ -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.
@@ -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"
@@ -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)
@@ -0,0 +1,47 @@
#include <QByteArray>
#include <QGuiApplication>
#include <array>
#include <cstdio>
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<unsigned char, 64> 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;
}
@@ -0,0 +1,24 @@
#include <QByteArray>
#include <QCoreApplication>
#include <QGuiApplication>
#include <QDebug>
#include <QTimer>
#include <cstdio>
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();
}
@@ -0,0 +1,57 @@
#include <QCoreApplication>
#include <QDebug>
#include <QPluginLoader>
#include <cstdio>
#include <fstream>
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;
}
@@ -0,0 +1,4 @@
[Paths]
Prefix=/usr
Plugins=/usr/plugins
QmlImports=/usr/qml
+171 -4
View File
@@ -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 <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#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 <assert.h>) 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 <assert.h>' "${QTYPES}" 2>/dev/null; then
awk '/#ifndef __cplusplus/ { print; print "#include <assert.h>"; 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 <assert.h>/ { 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 - <<PY
from pathlib import Path
path = Path(r"${QASSERT_H}")
lines = path.read_text().splitlines()
start = None
end = None
for i, line in enumerate(lines):
if line == "// Q_UNREACHABLE_IMPL() and Q_ASSUME_IMPL() used below are defined in qcompilerdetection.h":
start = i
if start is not None and line == "#ifndef Q_UNREACHABLE_RETURN":
end = i
break
if start is None or end is None or end <= start:
raise SystemExit("qassert.h Q_UNREACHABLE block not found")
replacement = [
"// Q_UNREACHABLE_IMPL() and Q_ASSUME_IMPL() used below are defined in qcompilerdetection.h",
"#ifdef Q_OS_REDOX",
"#define Q_UNREACHABLE() " + chr(92),
" do { " + chr(92),
' QT_PREPEND_NAMESPACE(qt_assert_x)("Q_UNREACHABLE()", "Q_UNREACHABLE was reached", __FILE__, __LINE__); ' + chr(92),
" } while (false)",
"#else",
"#define Q_UNREACHABLE() " + chr(92),
" do {" + chr(92),
' Q_ASSERT_X(false, "Q_UNREACHABLE()", "Q_UNREACHABLE was reached");' + chr(92),
" Q_UNREACHABLE_IMPL();" + chr(92),
" } while (false)",
"#endif",
"",
]
lines[start:end] = replacement
path.write_text(chr(10).join(lines) + chr(10))
PY
fi
# forkfd still needs waitid idtype constants on Redox. Provide source-level fallbacks near the
# waitid consumer instead of relying on toolchain/env defines that clean builds may drop.
FORKFD_C="${COOKBOOK_SOURCE}/src/3rdparty/forkfd/forkfd.c"
if ! grep -q 'REDOX_WAITID_IDTYPE_SHIMS' "${FORKFD_C}" 2>/dev/null; then
awk '/#include <unistd.h>/ {
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 <unistd.h>/ {
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
"""
+121
View File
@@ -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<char *>(file.map(0, fdlen));
+ const char *filedata = nullptr;
+ QByteArray data;
+
+#ifdef Q_OS_REDOX
+ data = file.read(qMin<qsizetype>(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<char *>(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
+10
View File
@@ -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
+114 -9
View File
@@ -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 <sys/epoll.h>
#include <sys/signalfd.h>
#include <sys/timerfd.h>''',
'''#include <sys/epoll.h>
#ifdef __redox__
#include <sys/types.h>
#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 <sys/signalfd.h>
#include <sys/timerfd.h>
#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 <fcntl.h>
#include <sys/eventfd.h>''',
'''#include <fcntl.h>
#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 <sys/eventfd.h>
#endif''',
)
server.write_text(server_text)
connection = source_root / "src/connection.c"
connection_text = connection.read_text()
connection_text = connection_text.replace(
'''#include <ffi.h>
#include "wayland-util.h"''',
'''#include <ffi.h>
#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
"""
+78 -4
View File
@@ -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 <sys/socket.h>
#include <sys/un.h>
#include <sys/epoll.h>
+#ifdef __redox__
+#include <sys/types.h>
+#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 <sys/signalfd.h>
+#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 <sys/timerfd.h>
#endif
#include <unistd.h>
#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 <dlfcn.h>
#include <sys/time.h>
#include <fcntl.h>
+#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 <sys/eventfd.h>
+#endif
#include <sys/file.h>
#include <sys/stat.h>
diff --git a/src/connection.c b/src/connection.c
--- a/src/connection.c
+++ b/src/connection.c
@@ -40,6 +40,13 @@
#include <time.h>
#include <ffi.h>
+#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"
+1
View File
@@ -0,0 +1 @@
../../../local/recipes/wayland/qt6-wayland-smoke