On Wednesday, 22 July 2026 01:22:29 Pacific Daylight Time Volker Hilsheimer via Development wrote: > Is it code using some posix APIs (which would likely also exist, but perhaps > not be the best choice, on Android)? Is it code using some subsystem API > that only exists on linux (but then perhaps not on every linux system)? > > Looking at current usage of Q_OS_LINUX, they are mostly combined with some > other condition. The comparatively rare “naked” usages of Q_OS_LINUX are > either in code that is only compiled on Unix-ish systems (such as QPA code, > which might be used on some RTOS platforms as well), or would also work on > e.g. Android. > > Perhaps QSysInfo already provides you with the information you are > conceptually looking for; its QString-based API doesn’t allow for any > compile-time checking though.
When Jake wrote QOperatingSystemVersion, the intended use was for Apple
systems, for which the APIs are usually always defined, but may fail at runtime
if run on an older system or the wrong flavour. That allows for things like in
qcocoaapplicationdelegate.mm:
if (QOperatingSystemVersion::current() >=
QOperatingSystemVersion::MacOSSonoma) {
[currentApplication
activateWithOptions:NSApplicationActivateAllWindows];
}
We did add Windows, but of course there's no flavour of Windows there. It is
useful for Windows for COM or other IPC-like APIs, because we can make calls
to other services that may be missing, without linking to symbols that may be
missing.
For Android, we could make the same case: the JNI doesn't *link* to symbols,
so it makes sense to write code that supports multiple versions and just
dispatches differently at runtime. HarmonyOS with its JS bridge is similar.
How does that apply to Linux and other OSes? The problem there is that
constexpr evaluation must still see the definitions. You cannot write, like in
qfilesystemengine_unix.cpp:
if constexpr (Qt::OS::isLinux) {
if (renameat2(AT_FDCWD, srcPath, AT_FDCWD, tgtPath, RENAME_NOREPLACE) ==
0)
return true;
} else if constexpr (Qt:OS::isDarwin) {
if (renameatx_np(AT_FDCWD, srcPath, AT_FDCWD, tgtPath, RENAME_EXCL) == 0)
return true;
}
This will not compile unless both renameat2(), renameatx_np() and the
constants RENAME_NOREPLACE and RENAME_EXCL constants are defined, regardless of
OS. What's more, those are bad tests because they would be proxy-testing for
what they really want to know. The renameat2() call works just fine on FreeBSD
15 because they matched the Linux API. And it does not *always* work on Linux,
because of poorly-written system call filters for containers.
It will not work at all for the higher-level, graphical functionality like the
macOS example above: there's no way to statically determine if we're going to
be running on X11 or Wayland or EGLFS, what compositor or window manager will
be handling our windows, what OpenGL library we'll be using, etc.
Therefore, for the vast majority of checks, you should check for the
functionality you want to use, not for a particular OS or version. This
applies to the CI too, especially the blacklist, where I often see "it failed
on the CI's Ubuntu, therefore it must be failing on ALL Ubuntu", when the
problem might be a particular buggy Wayland compositor that was shipped in
that release or a misconfigured service. [There may not be any better way to
unblock a particular problem, though]
So I think there's little value in this new API: it can't be used for
dispatching to functions or using constants or types that may not be defined,
and it may lead to sloppy code that tests for the wrong thing.
But not zero value. I could see a few uses here and there. So we still need to
come up with a good API.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Principal Engineer - Intel DCG - Platform & Sys. Eng.
smime.p7s
Description: S/MIME cryptographic signature
-- Development mailing list [email protected] https://lists.qt-project.org/listinfo/development
