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.

Attachment: smime.p7s
Description: S/MIME cryptographic signature

-- 
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to