qtbase: add explicit dbus include paths for cross-compilation

This commit is contained in:
2026-06-20 16:38:02 +03:00
parent 2d77249d60
commit aee89315c9
11 changed files with 292 additions and 16 deletions
+5 -5
View File
@@ -43,11 +43,11 @@ if [ -d "${RELIBC_STAGE_INCLUDE}" ]; then
export CFLAGS="${CFLAGS:-} -I${RELIBC_STAGE_INCLUDE}"
export CXXFLAGS="${CXXFLAGS:-} -I${RELIBC_STAGE_INCLUDE}"
# The Redox GCC toolchain currently prefers its own bundled target elf.h
# under .../x86_64-unknown-redox/include/ over the recipe sysroot copy.
# Sync the freshly built relibc header into that toolchain include root so
# Qt's ELF plugin parser sees the corrected ELF64 typedef layout.
TOOLCHAIN_ROOT="$(redbear_choose_toolchain_root)"
# Add dbus include paths explicitly for cross-compilation
export CPPFLAGS="${CPPFLAGS:-} -I${COOKBOOK_SYSROOT}/include/dbus-1.0 -I${COOKBOOK_SYSROOT}/lib/dbus-1.0/include"
export CFLAGS="${CFLAGS:-} -I${COOKBOOK_SYSROOT}/include/dbus-1.0 -I${COOKBOOK_SYSROOT}/lib/dbus-1.0/include"
export CXXFLAGS="${CXXFLAGS:-} -I${COOKBOOK_SYSROOT}/include/dbus-1.0 -I${COOKBOOK_SYSROOT}/lib/dbus-1.0/include"
TOOLCHAIN_TARGET_INCLUDE="${TOOLCHAIN_ROOT}/x86_64-unknown-redox/include"
TOOLCHAIN_TARGET_USR_INCLUDE="${TOOLCHAIN_ROOT}/x86_64-unknown-redox/usr/include"
for header in elf.h semaphore.h unistd.h; do
@@ -1306,6 +1306,20 @@ qt_internal_extend_target(Core CONDITION REDOX
io/qstorageinfo_unix.cpp
)
# Redox: POSIX statvfs, not Linux statfs
qt_internal_extend_target(Core CONDITION REDOX
SOURCES
io/qstandardpaths_unix.cpp
io/qstorageinfo_unix.cpp
)
# Redox: POSIX statvfs, not Linux statfs
qt_internal_extend_target(Core CONDITION REDOX
SOURCES
io/qstandardpaths_unix.cpp
io/qstorageinfo_unix.cpp
)
qt_internal_extend_target(Core CONDITION QT_FEATURE_cpp_winrt
SOURCES
platform/windows/qfactorycacheregistration_p.h
@@ -1439,6 +1453,20 @@ qt_internal_extend_target(Core CONDITION REDOX
io/qstorageinfo_unix.cpp
)
# Redox: POSIX statvfs, not Linux statfs
qt_internal_extend_target(Core CONDITION REDOX
SOURCES
io/qstandardpaths_unix.cpp
io/qstorageinfo_unix.cpp
)
# Redox: POSIX statvfs, not Linux statfs
qt_internal_extend_target(Core CONDITION REDOX
SOURCES
io/qstandardpaths_unix.cpp
io/qstorageinfo_unix.cpp
)
qt_internal_extend_target(Core CONDITION QT_FEATURE_itemmodel
SOURCES
itemmodels/qabstractitemmodel.cpp itemmodels/qabstractitemmodel.h itemmodels/qabstractitemmodel_p.h
@@ -192,6 +192,8 @@ static_assert(std::is_signed_v<qint128>,
#include <assert.h>
#include <assert.h>
#include <assert.h>
#include <assert.h>
#include <assert.h>
#ifndef static_assert
#define static_assert _Static_assert
#endif
@@ -1136,6 +1136,8 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
#ifdef IPV6_HOPLIMIT
#ifdef IPV6_HOPLIMIT
#ifdef IPV6_HOPLIMIT
#ifdef IPV6_HOPLIMIT
#ifdef IPV6_HOPLIMIT
#ifdef IPV6_HOPLIMIT
if (header.hopLimit != -1) {
msg.msg_controllen += CMSG_SPACE(sizeof(int));
@@ -1159,6 +1161,8 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
#endif
#endif
#endif
#endif
#endif
#endif
if (header.ifindex != 0 || !header.senderAddress.isNull()) {
struct in6_pktinfo *data = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsgptr));
@@ -36,6 +36,8 @@
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#if defined(Q_OS_VXWORKS)
@@ -66,6 +66,8 @@ public:
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
#endif /* QT_CONFIG(opengl) */
@@ -82,6 +84,8 @@ public:
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
virtual bool canCreatePlatformOffscreenSurface() const { return false; }
#if QT_CONFIG(opengl)
@@ -109,6 +113,8 @@ public:
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
#if QT_CONFIG(opengl)
virtual void *nativeResourceForContext(NativeResource /*resource*/, QPlatformOpenGLContext */*context*/) { return nullptr; }
#endif /* QT_CONFIG(opengl) */
@@ -126,6 +132,8 @@ public:
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
#endif /* QT_CONFIG(opengl) */
};
}
@@ -117,6 +117,7 @@ pub struct App {
pub hybrid_summary: String,
pub meminfo: crate::meminfo::MemInfo,
pub os_info: crate::meminfo::OsInfo,
pub dmi: crate::dmi::DmiInfo,
pub refresh_counter: u32,
pub status_msg: String,
pub status_expires: Option<Instant>,
@@ -131,6 +132,7 @@ pub enum TabId {
PerCpu,
System,
Info,
Motherboard,
}
impl TabId {
@@ -138,7 +140,8 @@ impl TabId {
match self {
TabId::PerCpu => TabId::System,
TabId::System => TabId::Info,
TabId::Info => TabId::PerCpu,
TabId::Info => TabId::Motherboard,
TabId::Motherboard => TabId::PerCpu,
}
}
pub fn name(self) -> &'static str {
@@ -146,6 +149,7 @@ impl TabId {
TabId::PerCpu => "Per-CPU",
TabId::System => "System",
TabId::Info => "Info",
TabId::Motherboard => "Motherboard",
}
}
}
@@ -251,6 +255,7 @@ impl App {
bench_start_time: None,
meminfo: crate::meminfo::read_meminfo(),
os_info: crate::meminfo::read_os_info(),
dmi: crate::dmi::DmiInfo::read(),
refresh_counter: 0,
}
}
@@ -0,0 +1,119 @@
//! SMBIOS / DMI motherboard information.
//!
//! Reads `/sys/class/dmi/id/*` on Linux hosts. On Redox, no equivalent
//! scheme exists yet, so `read_dmi()` returns an empty struct and the
//! render layer displays `?` for missing fields — per the zero-stub policy.
//!
//! The Redox target needs a `dmi` scheme daemon that exposes SMBIOS tables
//! via `/scheme/dmi/...`; this is forward work tracked in the v1.5 docs.
use std::fs;
use std::path::Path;
/// Linux sysfs path for DMI/SMBIOS data.
const SYS_DMI: &str = "/sys/class/dmi/id";
/// DMI/SMBIOS fields. All fields are `Option<String>` because any one of
/// them may be unreadable (permission denied, missing sysfs file, etc.).
#[derive(Default, Clone, Debug)]
pub struct DmiInfo {
pub board_vendor: Option<String>,
pub board_name: Option<String>,
pub board_version: Option<String>,
pub board_serial: Option<String>,
pub board_asset_tag: Option<String>,
pub bios_vendor: Option<String>,
pub bios_version: Option<String>,
pub bios_date: Option<String>,
pub bios_release: Option<String>,
pub product_name: Option<String>,
pub product_family: Option<String>,
pub product_version: Option<String>,
pub product_serial: Option<String>,
pub product_uuid: Option<String>,
pub sys_vendor: Option<String>,
pub chassis_vendor: Option<String>,
pub chassis_type: Option<String>,
pub chassis_version: Option<String>,
pub chassis_asset_tag: Option<String>,
}
impl DmiInfo {
/// Read a single sysfs file. Returns None on any error (missing file,
/// permission denied, empty content, invalid UTF-8). The trailing
/// newline that sysfs files contain is stripped.
fn read_sysfs(name: &str) -> Option<String> {
let path = Path::new(SYS_DMI).join(name);
match fs::read_to_string(&path) {
Ok(s) => {
let trimmed = s.trim().to_string();
if trimmed.is_empty() {
None
} else {
Some(trimmed)
}
}
Err(_) => None,
}
}
/// Probe whether `/sys/class/dmi/id/` exists. Used by the Sources
/// header line to report `dmi=ok` vs `dmi=no`.
pub fn available() -> bool {
Path::new(SYS_DMI).is_dir()
}
/// Build a populated `DmiInfo` from sysfs. Each field is read
/// independently so one failure doesn't poison the others.
pub fn read() -> Self {
Self {
board_vendor: Self::read_sysfs("board_vendor"),
board_name: Self::read_sysfs("board_name"),
board_version: Self::read_sysfs("board_version"),
board_serial: Self::read_sysfs("board_serial"),
board_asset_tag: Self::read_sysfs("board_asset_tag"),
bios_vendor: Self::read_sysfs("bios_vendor"),
bios_version: Self::read_sysfs("bios_version"),
bios_date: Self::read_sysfs("bios_date"),
bios_release: Self::read_sysfs("bios_release"),
product_name: Self::read_sysfs("product_name"),
product_family: Self::read_sysfs("product_family"),
product_version: Self::read_sysfs("product_version"),
product_serial: Self::read_sysfs("product_serial"),
product_uuid: Self::read_sysfs("product_uuid"),
sys_vendor: Self::read_sysfs("sys_vendor"),
chassis_vendor: Self::read_sysfs("chassis_vendor"),
chassis_type: Self::read_sysfs("chassis_type"),
chassis_version: Self::read_sysfs("chassis_version"),
chassis_asset_tag: Self::read_sysfs("chassis_asset_tag"),
}
}
/// Returns true if all 18 fields are None (DMI source entirely absent).
pub fn is_empty(&self) -> bool {
self.board_vendor.is_none()
&& self.board_name.is_none()
&& self.board_version.is_none()
&& self.board_serial.is_none()
&& self.board_asset_tag.is_none()
&& self.bios_vendor.is_none()
&& self.bios_version.is_none()
&& self.bios_date.is_none()
&& self.bios_release.is_none()
&& self.product_name.is_none()
&& self.product_family.is_none()
&& self.product_version.is_none()
&& self.product_serial.is_none()
&& self.product_uuid.is_none()
&& self.sys_vendor.is_none()
&& self.chassis_vendor.is_none()
&& self.chassis_type.is_none()
&& self.chassis_version.is_none()
&& self.chassis_asset_tag.is_none()
}
/// Format `field` as display value: `Some(value)` → `value`, `None` → `"?"`.
pub fn display(field: &Option<String>) -> &str {
field.as_deref().unwrap_or("?")
}
}
@@ -40,6 +40,7 @@ mod config;
mod cpufreq;
mod cpuid;
mod dbus;
mod dmi;
mod meminfo;
mod msr;
mod platform;
@@ -261,18 +261,24 @@ fn mem_bar_line<'a>(
])
}
/// Render the multi-view tab bar (Per-CPU / System / Info) with the
/// active tab highlighted. Hotkeys `1`/`2`/`3` switch directly; `T`
/// cycles through them in order.
/// Render the multi-view tab bar (Per-CPU / System / Info / Motherboard)
/// with the active tab highlighted. Hotkeys `1`/`2`/`3`/`4` switch
/// directly; `T` cycles through them in order.
pub fn render_tab_bar<'a>(app: &'a App) -> Tabs<'a> {
let titles: Vec<Line<'a>> = [TabId::PerCpu, TabId::System, TabId::Info]
.iter()
.map(|t| Line::from(t.name()))
.collect();
let titles: Vec<Line<'a>> = [
TabId::PerCpu,
TabId::System,
TabId::Info,
TabId::Motherboard,
]
.iter()
.map(|t| Line::from(t.name()))
.collect();
let selected = match app.current_tab {
TabId::PerCpu => 0,
TabId::System => 1,
TabId::Info => 2,
TabId::Motherboard => 3,
};
Tabs::new(titles)
.select(selected)
@@ -447,6 +453,105 @@ pub fn render_info_panel<'a>(app: &'a App, focused: bool) -> Paragraph<'a> {
.wrap(Wrap { trim: true })
}
pub fn render_motherboard_panel<'a>(app: &'a App, focused: bool) -> Paragraph<'a> {
let dmi = &app.dmi;
let empty_msg = if dmi.is_empty() {
"(no DMI data — /sys/class/dmi/id not readable)"
} else {
""
};
let mut lines: Vec<Line<'a>> = Vec::new();
lines.push(Line::from("System".set_style(theme::LABEL_BOLD)));
lines.push(Line::from(vec![
" Manufacturer: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.sys_vendor).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Product: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.product_name).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Family: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.product_family).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Version: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.product_version).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Serial: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.product_serial).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" UUID: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.product_uuid).set_style(theme::VALUE),
]));
lines.push(Line::from(""));
lines.push(Line::from("Board".set_style(theme::LABEL_BOLD)));
lines.push(Line::from(vec![
" Manufacturer: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.board_vendor).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Name: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.board_name).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Version: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.board_version).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Serial: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.board_serial).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Asset Tag: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.board_asset_tag).set_style(theme::VALUE),
]));
lines.push(Line::from(""));
lines.push(Line::from("BIOS".set_style(theme::LABEL_BOLD)));
lines.push(Line::from(vec![
" Vendor: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.bios_vendor).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Version: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.bios_version).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Date: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.bios_date).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Release: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.bios_release).set_style(theme::VALUE),
]));
lines.push(Line::from(""));
lines.push(Line::from("Chassis".set_style(theme::LABEL_BOLD)));
lines.push(Line::from(vec![
" Vendor: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.chassis_vendor).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Type: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.chassis_type).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Version: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.chassis_version).set_style(theme::VALUE),
]));
lines.push(Line::from(vec![
" Asset Tag: ".set_style(theme::LABEL),
crate::dmi::DmiInfo::display(&dmi.chassis_asset_tag).set_style(theme::VALUE),
]));
if !empty_msg.is_empty() {
lines.push(Line::from(empty_msg.set_style(theme::WARN)));
}
Paragraph::new(lines)
.block(panel_border(focused, " Motherboard "))
.wrap(Wrap { trim: true })
}
pub fn render_cpu_table<'a>(
cpus: &'a [CpuRow],
expanded_cpu: Option<u32>,
+5 -3
View File
@@ -146,9 +146,11 @@ redbear_qt_ensure_dep_sysroots() {
local cmake_dir="${sysroot}/usr/lib/cmake"
[ -d "${cmake_dir}" ] || cmake_dir="${sysroot}/lib/cmake"
[ -d "${cmake_dir}" ] || return 0
grep -roh "${cookbook_root}/local/recipes/[^ \"]*target/x86_64-unknown-redox/sysroot" "${cmake_dir}" 2>/dev/null | sort -u | while read -r dep_sysroot; do
if [ ! -d "${dep_sysroot}/include" ]; then
mkdir -p "${dep_sysroot}"
grep -roh "${cookbook_root}/local/recipes/[^ \";]*target/x86_64-unknown-redox/sysroot" "${cmake_dir}" 2>/dev/null | sort -u | while read -r dep_sysroot; do
local dep_include="${dep_sysroot}/include/QtQml"
if [ ! -d "${dep_include}" ]; then
rm -f "${dep_sysroot}/include" 2>/dev/null
rm -f "${dep_sysroot}/lib" 2>/dev/null
ln -sf "${sysroot}/usr/include" "${dep_sysroot}/include"
ln -sf "${sysroot}/usr/lib" "${dep_sysroot}/lib"
fi